gpt-maa-ts
Version:
A TypeScript client for submitting AgentDefinitions and user prompt to a gpt-multi-atomic-agents REST API, to generate supported mutations.
1,333 lines (1,295 loc) • 355 kB
JavaScript
'use strict';
var yoctoSpinner = require('yocto-spinner');
var spinners = require('cli-spinners');
var colors = require('colors');
var path = require('node:path');
var fs = require('node:fs');
var inquirer = require('@inquirer/prompts');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var spinners__namespace = /*#__PURE__*/_interopNamespaceDefault(spinners);
var inquirer__namespace = /*#__PURE__*/_interopNamespaceDefault(inquirer);
var TypeScriptBlackboardFormat = /* @__PURE__ */ ((TypeScriptBlackboardFormat2) => {
TypeScriptBlackboardFormat2["function_call"] = "function_call";
return TypeScriptBlackboardFormat2;
})(TypeScriptBlackboardFormat || {});
class FunctionCallBlackboardAccessor {
// The inner blackboard - should only be used to send to REST API, not used directly by the client
constructor(blackboard) {
this.format = "function_call" /* function_call */;
this.blackboard = blackboard;
}
get_new_functions() {
return this.blackboard.internalNewlyGeneratedFunctions ?? [];
}
get_new_messages() {
return this.blackboard.internalNewlyGeneratedMessages ?? [];
}
get_previous_messages() {
return this.blackboard.internalPreviousMessages ?? [];
}
get_previously_generated_functions() {
return this.blackboard.internalPreviouslyGeneratedFunctions ?? [];
}
_reset() {
this.blackboard.internalNewlyGeneratedFunctions = [];
this.blackboard.internalNewlyGeneratedMessages = [];
}
set_user_data(user_data) {
this._reset();
this.blackboard.internalPreviouslyGeneratedFunctions = user_data;
}
get_internal_blackboard() {
return this.blackboard;
}
_reset_all() {
this.blackboard.internalNewlyGeneratedFunctions = [];
this.blackboard.internalNewlyGeneratedMessages = [];
this.blackboard.internalPreviousMessages = [];
this.blackboard.internalPreviouslyGeneratedFunctions = [];
}
}
const changeExtension = (inputFilepath, newExtensionWithDot) => {
if (!newExtensionWithDot.startsWith("."))
throw new Error("newExtensionWithDot must start with a '.'. For example: '.txt'");
let base_filename = inputFilepath;
if (inputFilepath.includes(".")) {
const parts = inputFilepath.split(".");
parts.pop();
base_filename = parts.join(".");
}
return base_filename + newExtensionWithDot;
};
const readJsonFromFile = (filepath, encoding = "utf-8") => {
const buffer = fs.readFileSync(filepath, { encoding });
return JSON.parse(buffer.toString());
};
const writeJsonToFile = (filepath, data, encoding = "utf-8") => {
const jsonString = JSON.stringify(data);
fs.writeFileSync(filepath, jsonString, { encoding });
};
const findFilesByExtension = (dirpath, extensionWithDot) => {
const isFile = (fileName) => {
return fs.lstatSync(fileName).isFile();
};
const isOk = (fileName) => {
return isFile(fileName) && fileName.endsWith(extensionWithDot);
};
return fs.readdirSync(dirpath).map((fileName) => {
return path.join(dirpath, fileName);
}).filter(isOk);
};
const getConfig = () => {
const filename = "config.gpt-maa-ts.json";
const filepath = path.join(process.cwd(), filename);
return readJsonFromFile(filepath);
};
let isDebugActiveValue = void 0;
const isDebugActive = () => {
if (isDebugActiveValue === void 0) {
isDebugActiveValue = getConfig().isDebug;
}
return isDebugActiveValue;
};
const toggleIsDebugActive = () => {
let oldValue = isDebugActive();
isDebugActiveValue = !oldValue;
return isDebugActiveValue;
};
const print = (...args) => {
console.log(...args);
};
const colorArgs = (cb, ...args) => {
return args.map((a) => cb(a));
};
const printWarning = (...args) => {
console.log(...colorArgs((a) => colors.yellow(a), args));
};
const printError = (...args) => {
console.log(...colorArgs((a) => colors.red(a), args));
};
const EMOJI_ASSISTANT = "\u{1F916}";
const EMOJI_USER = "\u{1F615}";
const printAssistant = (...args) => {
console.log(
colors.green(`${EMOJI_ASSISTANT} Assistant: `),
...args.map((a) => colors.green(a))
);
};
const printUser = (...args) => {
const cargs = colorArgs((a) => colors.magenta(a), args);
console.log(`${EMOJI_USER} You: `, ...cargs);
};
const printUserNoNewline = (...args) => {
const cargs = colorArgs((a) => colors.magenta(a), args);
console.log(`${EMOJI_USER} You: `, ...cargs);
};
const printDetail = (...args) => {
const cargs = colorArgs((a) => colors.gray(a), args);
console.log(" ", ...cargs);
};
const dumpJson = (json, name) => {
if (isDebugActive()) {
printDetail(`DUMP: ${name}`);
dumpJsonAlways(json);
}
};
const dumpJsonAlways = (json) => {
console.dir(json, { depth: null, colors: true });
};
const printMessages = (messages) => {
messages.forEach((message) => {
if (message.role == "user") printUser(message.message);
else printAssistant(message.message);
});
};
const startTimer = (name) => {
console.time(name);
return name;
};
const printTimeTaken = (name) => {
console.timeEnd(name);
};
const showSpinner = () => {
return yoctoSpinner({
text: "Processing\u2026",
spinner: spinners__namespace.default.sand
// spinners.randomSpinner(), - ref: https://jsfiddle.net/sindresorhus/2eLtsbey/embedded/result/
}).start();
};
const stopSpinner = (spinner) => {
if (spinner) spinner.success("[done]");
};
const generate_mutations_from_function_calls = async (client, userPrompt, agentDefinitions, chatAgentDescription, existing_plan = void 0, user_data = null) => {
const blackboard = new FunctionCallBlackboardAccessor({
format: "function_call",
internalNewlyGeneratedFunctions: [],
internalNewlyGeneratedMessages: [],
internalPreviouslyGeneratedFunctions: [],
internalPreviousMessages: []
});
if (user_data) {
blackboard.set_user_data(user_data);
}
return generate_mutations(
client,
userPrompt,
agentDefinitions,
chatAgentDescription,
existing_plan,
blackboard
);
};
const _validateUserPromptWillOverridePlan = (userPrompt, existing_plan = void 0) => {
if (existing_plan) {
if (userPrompt.length > 0) {
printDetail(`USER: ${userPrompt}`);
printWarning(
"Have Generation Plan BUT also have a User Prompt - the server will discard the Plan generate a new plan."
);
} else {
printDetail(`Generating from the Generation Plan...`);
}
} else {
printDetail(`USER: ${userPrompt}`);
if (userPrompt.length === 0) {
printWarning("User prompt is empty");
}
printDetail(
`Generating from user prompt - the Server will create a new Generation Plan...`
);
}
};
const _fixUpParameters = (oldParameters, description) => {
const newParameters = {
additionalData: {}
};
const keysToFix = Object.keys(oldParameters).filter(
(k) => k !== "additionalData"
);
if (keysToFix.length > 0) {
printWarning(
`Fixing up '${description}' Parameters '${keysToFix}': kiota bug? - plan response does not align with generate request.`
);
}
keysToFix.forEach((p) => {
newParameters.additionalData[p] = oldParameters[p];
});
return newParameters;
};
const _fixUpAgentParameters = (existing_plan) => {
existing_plan.recommendedAgents?.forEach((agent) => {
if (agent.agentParameters) {
const oldParameters = agent.agentParameters;
agent.agentParameters = _fixUpParameters(
oldParameters,
`Agent ${agent.agentName}`
);
}
});
};
const _fixUpPreviouslyGeneratedFunctionCallParameters = (internalPreviouslyGeneratedFunctions) => {
internalPreviouslyGeneratedFunctions.forEach((fun) => {
if (fun.parameters) {
const oldParams = fun.parameters;
fun.parameters = _fixUpParameters(
oldParams,
`Function Call ${fun.functionName}`
);
}
});
return internalPreviouslyGeneratedFunctions;
};
const EMPTY_USER_PROMPT_TO_ENABLE_PLAN = "";
const generate_mutations_with_existing_plan = async (client, agentDefinitions, chatAgentDescription, existing_plan, blackboardAccessor = null) => {
return generate_mutations(
client,
EMPTY_USER_PROMPT_TO_ENABLE_PLAN,
agentDefinitions,
chatAgentDescription,
existing_plan,
blackboardAccessor
);
};
const generate_mutations = async (client, userPrompt, agentDefinitions, chatAgentDescription, existing_plan = void 0, blackboardAccessor = null) => {
const timer = startTimer("generate_mutations");
userPrompt = userPrompt.trim();
_validateUserPromptWillOverridePlan(userPrompt, existing_plan);
if (existing_plan) _fixUpAgentParameters(existing_plan);
let blackboard = blackboardAccessor?.get_internal_blackboard();
if (blackboard && blackboard.internalPreviouslyGeneratedFunctions) {
blackboard.internalPreviouslyGeneratedFunctions = _fixUpPreviouslyGeneratedFunctionCallParameters(
blackboard.internalPreviouslyGeneratedFunctions
);
}
const function_call_generate_request = {
agentDefinitions,
blackboard,
chatAgentDescription,
executionPlan: existing_plan,
userPrompt
};
let spinner = showSpinner();
blackboard = await client.generate_function_calls.post(
function_call_generate_request
);
stopSpinner(spinner);
dumpJson(blackboard, "blackboard");
printTimeTaken(timer);
if (!blackboard) {
return null;
}
return new FunctionCallBlackboardAccessor(blackboard);
};
const convertAgentDefinitionToDescription = (agentDefinition) => {
let agentParameterNames = [];
if (agentDefinition.agentParameters?.additionalData) {
agentParameterNames = Object.keys(
agentDefinition.agentParameters.additionalData
);
}
return {
agentName: agentDefinition.agentName,
description: agentDefinition.description,
topics: agentDefinition.topics,
agentParameterNames
};
};
const generate_plan = async (client, userPrompt, agentDefinitions, chatAgentDescription, previousPlan = void 0, messages = null) => {
const start = startTimer("generate_plan");
const agentDescriptions = agentDefinitions.map(
convertAgentDefinitionToDescription
);
const generate_plan_request = {
agentDescriptions,
chatAgentDescription,
previousPlan,
userPrompt,
messages
};
printDetail(`Generating a plan for user prompt '${userPrompt}'`);
let spinner = showSpinner();
const executionPlan = await client.generate_plan.post(generate_plan_request);
stopSpinner(spinner);
dumpJson(executionPlan, "executionPlan");
printTimeTaken(start);
return executionPlan;
};
/**
* This factory holds a list of all the registered factories for the various types of nodes.
*/
class ParseNodeFactoryRegistry {
constructor() {
/** List of factories that are registered by content type. */
this.contentTypeAssociatedFactories = new Map();
}
getValidContentType() {
throw new Error("The registry supports multiple content types. Get the registered factory instead.");
}
getRootParseNode(contentType, content) {
if (!contentType) {
throw new Error("content type cannot be undefined or empty");
}
if (!content) {
throw new Error("content cannot be undefined or empty");
}
const vendorSpecificContentType = contentType.split(";")[0];
let factory = this.contentTypeAssociatedFactories.get(vendorSpecificContentType);
if (factory) {
return factory.getRootParseNode(vendorSpecificContentType, content);
}
const cleanedContentType = vendorSpecificContentType.replace(/[^/]+\+/gi, "");
factory = this.contentTypeAssociatedFactories.get(cleanedContentType);
if (factory) {
return factory.getRootParseNode(cleanedContentType, content);
}
throw new Error(`Content type ${cleanedContentType} does not have a factory registered to be parsed`);
}
}
/** Default singleton instance of the registry to be used when registring new factories that should be available by default. */
ParseNodeFactoryRegistry.defaultInstance = new ParseNodeFactoryRegistry();
/** This factory holds a list of all the registered factories for the various types of nodes. */
class SerializationWriterFactoryRegistry {
constructor() {
/** List of factories that are registered by content type. */
this.contentTypeAssociatedFactories = new Map();
}
getValidContentType() {
throw new Error("The registry supports multiple content types. Get the registered factory instead.");
}
getSerializationWriter(contentType) {
if (!contentType) {
throw new Error("content type cannot be undefined or empty");
}
const vendorSpecificContentType = contentType.split(";")[0];
let factory = this.contentTypeAssociatedFactories.get(vendorSpecificContentType);
if (factory) {
return factory.getSerializationWriter(vendorSpecificContentType);
}
const cleanedContentType = vendorSpecificContentType.replace(/[^/]+\+/gi, "");
factory = this.contentTypeAssociatedFactories.get(cleanedContentType);
if (factory) {
return factory.getSerializationWriter(cleanedContentType);
}
throw new Error(`Content type ${cleanedContentType} does not have a factory registered to be serialized`);
}
}
/** Default singleton instance of the registry to be used when registring new factories that should be available by default. */
SerializationWriterFactoryRegistry.defaultInstance = new SerializationWriterFactoryRegistry();
/** Proxy factory that allows the composition of before and after callbacks on existing factories. */
class ParseNodeProxyFactory {
getValidContentType() {
return this._concrete.getValidContentType();
}
/**
* Creates a new proxy factory that wraps the specified concrete factory while composing the before and after callbacks.
* @param _concrete the concrete factory to wrap
* @param _onBefore the callback to invoke before the deserialization of any model object.
* @param _onAfter the callback to invoke after the deserialization of any model object.
*/
constructor(_concrete, _onBefore, _onAfter) {
this._concrete = _concrete;
this._onBefore = _onBefore;
this._onAfter = _onAfter;
if (!_concrete) {
throw new Error("_concrete cannot be undefined");
}
}
getRootParseNode(contentType, content) {
const node = this._concrete.getRootParseNode(contentType, content);
const originalBefore = node.onBeforeAssignFieldValues;
const originalAfter = node.onAfterAssignFieldValues;
node.onBeforeAssignFieldValues = (value) => {
if (this._onBefore)
this._onBefore(value);
if (originalBefore)
originalBefore(value);
};
node.onAfterAssignFieldValues = (value) => {
if (this._onAfter)
this._onAfter(value);
if (originalAfter)
originalAfter(value);
};
return node;
}
}
/** Proxy factory that allows the composition of before and after callbacks on existing factories. */
class SerializationWriterProxyFactory {
getValidContentType() {
return this._concrete.getValidContentType();
}
/**
* Creates a new proxy factory that wraps the specified concrete factory while composing the before and after callbacks.
* @param _concrete the concrete factory to wrap
* @param _onBefore the callback to invoke before the serialization of any model object.
* @param _onAfter the callback to invoke after the serialization of any model object.
* @param _onStart the callback to invoke when the serialization of a model object starts
*/
constructor(_concrete, _onBefore, _onAfter, _onStart) {
this._concrete = _concrete;
this._onBefore = _onBefore;
this._onAfter = _onAfter;
this._onStart = _onStart;
if (!_concrete) {
throw new Error("_concrete cannot be undefined");
}
}
getSerializationWriter(contentType) {
const writer = this._concrete.getSerializationWriter(contentType);
const originalBefore = writer.onBeforeObjectSerialization;
const originalAfter = writer.onAfterObjectSerialization;
const originalStart = writer.onStartObjectSerialization;
writer.onBeforeObjectSerialization = (value) => {
if (this._onBefore)
this._onBefore(value);
if (originalBefore)
originalBefore(value);
};
writer.onAfterObjectSerialization = (value) => {
if (this._onAfter)
this._onAfter(value);
if (originalAfter)
originalAfter(value);
};
writer.onStartObjectSerialization = (value, writer_) => {
if (this._onStart)
this._onStart(value, writer_);
if (originalStart)
originalStart(value, writer_);
};
return writer;
}
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/**
* Factory to create an UntypedNode from a string during deserialization.
* @param _parseNode The ParseNode to deserialize.
* @returns A function that can deserialize an UntypedNode.
*/
const createUntypedNodeFromDiscriminatorValue = (_parseNode) => {
return deserializeIntoUntypedNode;
};
/**
* Type guard to assert that an object instance is an UntypedNode.
* @param node The object to check.
* @returns boolean indicating if the node is an UntypedNode.
*/
const isUntypedNode = (node) => {
const potentialNode = node;
return (potentialNode === null || potentialNode === void 0 ? void 0 : potentialNode.getValue) !== undefined;
};
/**
* The deserialization implementation for UntypedNode.
* @param untypedNode - The UntypedNode to deserialize.
* @returns A function that can deserialize a ParseNode into the provided UntypedNode.
*/
const deserializeIntoUntypedNode = (untypedNode = {}) => {
return {
value: (_n) => {
untypedNode.value = null;
},
getValue: (_n) => {
untypedNode.getValue = () => untypedNode.value;
},
};
};
/**
* Type guard to assert that an object instance is an UntypedNumber.
* @param node The object to check.
* @returns boolean indicating if the node is an UntypedNumber.
*/
function isUntypedNumber(node) {
const proposedNode = node;
return proposedNode && typeof proposedNode.value === "number";
}
/**
* Factory to create an UntypedNumber from a number.
* @param value The number value to create from.
* @returns The created UntypedNumber.
*/
function createUntypedNumber(value) {
return {
value,
getValue: () => value,
};
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/**
* Type guard to assert that an UntypedNode instance is an UntypedArray.
* @param node The UntypedNode to check.
* @returns boolean indicating if the node is an UntypedArray.
*/
const isUntypedArray = (node) => {
const proposedNode = node;
return proposedNode && proposedNode.value instanceof Array && proposedNode.value.every((item) => isUntypedNode(item));
};
/**
* Factory to create an UntypedArray from an array of UntypedNodes.
* @param value The value to create from.
* @returns The created UntypedArray.
*/
const createUntypedArray = (value) => {
return {
value,
getValue: () => value,
};
};
/**
* Type guard to assert that an object instance is an UntypedNull.
* @param node The object to check.
* @returns boolean indicating if the node is an UntypedNull.
*/
function isUntypedNull(node) {
return node.value === null;
}
/**
* Factory to create an UntypedNull from a boolean.
* @returns The created UntypedNull.
*/
function createUntypedNull() {
return {
value: null,
getValue: () => null,
};
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/**
* Type guard to assert that an object instance is an UntypedObject.
* @param node The object to check.
* @returns boolean indicating if the node is an UntypedObject.
*/
const isUntypedObject = (node) => {
const proposedNode = node;
return proposedNode && proposedNode.value instanceof Object && proposedNode.value instanceof Array === false && Object.values(proposedNode.value).every((item) => isUntypedNode(item));
};
/**
* Factory to create an UntypedObject from a Record<string, UntypedNode>.
* @param value The Record<string, UntypedNode> value to create from.
* @returns The created UntypedObject.
*/
const createUntypedObject = (value) => {
return {
value,
getValue: () => value,
};
};
/**
* Type guard to assert that an object instance is an UntypedString.
* @param node The object to check.
* @returns boolean indicating if the node is an UntypedString.
*/
function isUntypedString(node) {
const proposedNode = node;
return proposedNode && typeof proposedNode.value === "string";
}
/**
* Factory to create an UntypedString from a string.
* @param value The string value to create from.
* @returns The created UntypedString.
*/
function createUntypedString(value) {
return {
value,
getValue: () => value,
};
}
/**
* Type guard to assert that an UntypedNode instance is an UntypedBoolean.
* @param node The UntypedNode to check.
* @returns boolean indicating if the node is an UntypedBoolean.
*/
function isUntypedBoolean(node) {
const proposedNode = node;
return proposedNode && typeof proposedNode.value === "boolean";
}
/**
* Factory to create an UntypedBoolean from a boolean.
* @param value The boolean value to create from.
* @returns The created UntypedBoolean.
*/
function createUntypedBoolean(value) {
return {
value,
getValue: () => value,
};
}
const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return (byteToHex[arr[offset + 0]] +
byteToHex[arr[offset + 1]] +
byteToHex[arr[offset + 2]] +
byteToHex[arr[offset + 3]] +
'-' +
byteToHex[arr[offset + 4]] +
byteToHex[arr[offset + 5]] +
'-' +
byteToHex[arr[offset + 6]] +
byteToHex[arr[offset + 7]] +
'-' +
byteToHex[arr[offset + 8]] +
byteToHex[arr[offset + 9]] +
'-' +
byteToHex[arr[offset + 10]] +
byteToHex[arr[offset + 11]] +
byteToHex[arr[offset + 12]] +
byteToHex[arr[offset + 13]] +
byteToHex[arr[offset + 14]] +
byteToHex[arr[offset + 15]]).toLowerCase();
}
let getRandomValues;
const rnds8 = new Uint8Array(16);
function rng() {
if (!getRandomValues) {
if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
getRandomValues = crypto.getRandomValues.bind(crypto);
}
return getRandomValues(rnds8);
}
const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native = { randomUUID };
function v4(options, buf, offset) {
if (native.randomUUID && !buf && !options) {
return native.randomUUID();
}
options = options || {};
const rnds = options.random || (options.rng || rng)();
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
return unsafeStringify(rnds);
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/** In-memory implementation of the backing store. Allows for dirty tracking of changes. */
class InMemoryBackingStore {
constructor() {
this.subscriptions = new Map();
this.store = new Map();
this.returnOnlyChangedValues = false;
this._initializationCompleted = true;
}
get(key) {
const wrapper = this.store.get(key);
if (wrapper && ((this.returnOnlyChangedValues && wrapper.changed) || !this.returnOnlyChangedValues)) {
return wrapper.value;
}
return undefined;
}
set(key, value) {
const oldValueWrapper = this.store.get(key);
const oldValue = oldValueWrapper === null || oldValueWrapper === void 0 ? void 0 : oldValueWrapper.value;
if (oldValueWrapper) {
oldValueWrapper.value = value;
oldValueWrapper.changed = this.initializationCompleted;
}
else {
this.store.set(key, {
changed: this.initializationCompleted,
value,
});
}
this.subscriptions.forEach((sub) => {
sub(key, oldValue, value);
});
}
enumerate() {
let filterableArray = [...this.store.entries()];
if (this.returnOnlyChangedValues) {
filterableArray = filterableArray.filter(([_, v]) => v.changed);
}
return filterableArray.map(([key, value]) => {
return { key, value };
});
}
enumerateKeysForValuesChangedToNull() {
const keys = [];
for (const [key, entry] of this.store) {
if (entry.changed && !entry.value) {
keys.push(key);
}
}
return keys;
}
subscribe(callback, subscriptionId) {
if (!callback) {
throw new Error("callback cannot be undefined");
}
subscriptionId = subscriptionId !== null && subscriptionId !== void 0 ? subscriptionId : v4();
this.subscriptions.set(subscriptionId, callback);
return subscriptionId;
}
unsubscribe(subscriptionId) {
this.subscriptions.delete(subscriptionId);
}
clear() {
this.store.clear();
}
set initializationCompleted(value) {
this._initializationCompleted = value;
this.store.forEach((v) => {
v.changed = !value;
});
}
get initializationCompleted() {
return this._initializationCompleted;
}
}
/** This class is used to create instances of InMemoryBackingStore */
class InMemoryBackingStoreFactory {
createBackingStore() {
return new InMemoryBackingStore();
}
}
class BackingStoreFactorySingleton {
}
BackingStoreFactorySingleton.instance = new InMemoryBackingStoreFactory();
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/** Proxy implementation of ParseNodeFactory for the backing store that automatically sets the state of the backing store when deserializing. */
class BackingStoreParseNodeFactory extends ParseNodeProxyFactory {
/**
* Initializes a new instance of the BackingStoreParseNodeFactory class given the concrete implementation.
* @param concrete the concrete implementation of the ParseNodeFactory
*/
constructor(concrete) {
super(concrete, (value) => {
const backedModel = value;
if (backedModel === null || backedModel === void 0 ? void 0 : backedModel.backingStore) {
backedModel.backingStore.initializationCompleted = false;
}
}, (value) => {
const backedModel = value;
if (backedModel === null || backedModel === void 0 ? void 0 : backedModel.backingStore) {
backedModel.backingStore.initializationCompleted = true;
}
});
}
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/** Proxy implementation of SerializationWriterFactory for the backing store that automatically sets the state of the backing store when serializing. */
class BackingStoreSerializationWriterProxyFactory extends SerializationWriterProxyFactory {
/**
* Initializes a new instance of the BackingStoreSerializationWriterProxyFactory class given a concrete implementation of SerializationWriterFactory.
* @param concrete a concrete implementation of SerializationWriterFactory to wrap.
*/
constructor(concrete) {
super(concrete, (value) => {
const backedModel = value;
if (backedModel === null || backedModel === void 0 ? void 0 : backedModel.backingStore) {
backedModel.backingStore.returnOnlyChangedValues = true;
}
}, (value) => {
const backedModel = value;
if (backedModel === null || backedModel === void 0 ? void 0 : backedModel.backingStore) {
backedModel.backingStore.returnOnlyChangedValues = false;
backedModel.backingStore.initializationCompleted = true;
}
}, (value, writer) => {
const backedModel = value;
if (backedModel === null || backedModel === void 0 ? void 0 : backedModel.backingStore) {
const keys = backedModel.backingStore.enumerateKeysForValuesChangedToNull();
for (const key of keys) {
writer.writeNullValue(key);
}
}
});
}
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
// A method that creates a ProxyHandler for a generic model T and attaches it to a backing store.
const createBackedModelProxyHandler = () => {
// Each model has a backing store that is created by the BackingStoreFactorySingleton
const backingStore = BackingStoreFactorySingleton.instance.createBackingStore();
/**
* The ProxyHandler for the model.
*/
const handler = {
get: (_target, prop) => {
if (prop === "backingStore") {
return backingStore;
}
return backingStore.get(prop.toString());
},
set: (target, prop, value, receiver) => {
if (prop === "backingStore") {
console.warn(`BackingStore - Ignoring attempt to set 'backingStore' property`);
return true;
}
// set the value on the target object as well to allow it to have keys needed for serialization/deserialization
Reflect.set(target, prop, value, receiver);
backingStore.set(prop.toString(), value);
return true;
},
};
return handler;
};
const BackingStoreKey = "backingStoreEnabled";
/**
* Check if the object is an instance a BackedModel
* @param fields The fields of the object
* @returns boolean indicating if the object is a BackedModel
*/
function isBackingStoreEnabled(fields) {
// Check if the fields contain the backing store key
return Object.keys(fields).includes(BackingStoreKey);
}
/**
* -------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License.
* See License in the project root for license information.
* -------------------------------------------------------------------------------------------
*/
/**
* Registers the default serializer to the registry.
* @param type the class of the factory to be registered.
*/
function registerDefaultSerializer(type) {
if (!type)
throw new Error("Type is required");
const serializer = new type();
SerializationWriterFactoryRegistry.defaultInstance.contentTypeAssociatedFactories.set(serializer.getValidContentType(), serializer);
}
/**
* Registers the default deserializer to the registry.
* @param type the class of the factory to be registered.
*/
function registerDefaultDeserializer(type) {
if (!type)
throw new Error("Type is required");
const deserializer = new type();
ParseNodeFactoryRegistry.defaultInstance.contentTypeAssociatedFactories.set(deserializer.getValidContentType(), deserializer);
}
/**
* Enables the backing store on default serialization writers and the given serialization writer.
* @param original The serialization writer to enable the backing store on.
* @returns A new serialization writer with the backing store enabled.
*/
function enableBackingStoreForSerializationWriterFactory(original) {
if (!original)
throw new Error("Original must be specified");
let result = original;
if (original instanceof SerializationWriterFactoryRegistry) {
enableBackingStoreForSerializationRegistry(original);
}
else {
result = new BackingStoreSerializationWriterProxyFactory(original);
}
enableBackingStoreForSerializationRegistry(SerializationWriterFactoryRegistry.defaultInstance);
enableBackingStoreForParseNodeRegistry(ParseNodeFactoryRegistry.defaultInstance);
return result;
}
/**
* Enables the backing store on default parse node factories and the given parse node factory.
* @param original The parse node factory to enable the backing store on.
* @returns A new parse node factory with the backing store enabled.
*/
function enableBackingStoreForParseNodeFactory(original) {
if (!original)
throw new Error("Original must be specified");
let result = original;
if (original instanceof ParseNodeFactoryRegistry) {
enableBackingStoreForParseNodeRegistry(original);
}
else {
result = new BackingStoreParseNodeFactory(original);
}
enableBackingStoreForParseNodeRegistry(ParseNodeFactoryRegistry.defaultInstance);
return result;
}
/**
* Enables the backing store on the given parse node factory registry.
* @param registry The parse node factory registry to enable the backing store on.
*/
function enableBackingStoreForParseNodeRegistry(registry) {
for (const [k, v] of registry.contentTypeAssociatedFactories) {
if (!(v instanceof BackingStoreParseNodeFactory || v instanceof ParseNodeFactoryRegistry)) {
registry.contentTypeAssociatedFactories.set(k, new BackingStoreParseNodeFactory(v));
}
}
}
/**
* Enables the backing store on the given serialization factory registry.
* @param registry The serialization factory registry to enable the backing store on.
*/
function enableBackingStoreForSerializationRegistry(registry) {
for (const [k, v] of registry.contentTypeAssociatedFactories) {
if (!(v instanceof BackingStoreSerializationWriterProxyFactory || v instanceof SerializationWriterFactoryRegistry)) {
registry.contentTypeAssociatedFactories.set(k, new BackingStoreSerializationWriterProxyFactory(v));
}
}
}
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** only globals that common to node and browsers are allowed */
// eslint-disable-next-line node/no-unsupported-features/es-builtins
var _globalThis = typeof globalThis === 'object' ? globalThis : global;
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// this is autogenerated file, see scripts/version-update.js
var VERSION = '1.9.0';
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;
/**
* Create a function to test an API version to see if it is compatible with the provided ownVersion.
*
* The returned function has the following semantics:
* - Exact match is always compatible
* - Major versions must match exactly
* - 1.x package cannot use global 2.x package
* - 2.x package cannot use global 1.x package
* - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API
* - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects
* - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3
* - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor
* - Patch and build tag differences are not considered at this time
*
* @param ownVersion version which should be checked against
*/
function _makeCompatibilityCheck(ownVersion) {
var acceptedVersions = new Set([ownVersion]);
var rejectedVersions = new Set();
var myVersionMatch = ownVersion.match(re);
if (!myVersionMatch) {
// we cannot guarantee compatibility so we always return noop
return function () { return false; };
}
var ownVersionParsed = {
major: +myVersionMatch[1],
minor: +myVersionMatch[2],
patch: +myVersionMatch[3],
prerelease: myVersionMatch[4],
};
// if ownVersion has a prerelease tag, versions must match exactly
if (ownVersionParsed.prerelease != null) {
return function isExactmatch(globalVersion) {
return globalVersion === ownVersion;
};
}
function _reject(v) {
rejectedVersions.add(v);
return false;
}
function _accept(v) {
acceptedVersions.add(v);
return true;
}
return function isCompatible(globalVersion) {
if (acceptedVersions.has(globalVersion)) {
return true;
}
if (rejectedVersions.has(globalVersion)) {
return false;
}
var globalVersionMatch = globalVersion.match(re);
if (!globalVersionMatch) {
// cannot parse other version
// we cannot guarantee compatibility so we always noop
return _reject(globalVersion);
}
var globalVersionParsed = {
major: +globalVersionMatch[1],
minor: +globalVersionMatch[2],
patch: +globalVersionMatch[3],
prerelease: globalVersionMatch[4],
};
// if globalVersion has a prerelease tag, versions must match exactly
if (globalVersionParsed.prerelease != null) {
return _reject(globalVersion);
}
// major versions must match
if (ownVersionParsed.major !== globalVersionParsed.major) {
return _reject(globalVersion);
}
if (ownVersionParsed.major === 0) {
if (ownVersionParsed.minor === globalVersionParsed.minor &&
ownVersionParsed.patch <= globalVersionParsed.patch) {
return _accept(globalVersion);
}
return _reject(globalVersion);
}
if (ownVersionParsed.minor <= globalVersionParsed.minor) {
return _accept(globalVersion);
}
return _reject(globalVersion);
};
}
/**
* Test an API version to see if it is compatible with this API.
*
* - Exact match is always compatible
* - Major versions must match exactly
* - 1.x package cannot use global 2.x package
* - 2.x package cannot use global 1.x package
* - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API
* - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects
* - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3
* - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor
* - Patch and build tag differences are not considered at this time
*
* @param version version of the API requesting an instance of the global API
*/
var isCompatible = _makeCompatibilityCheck(VERSION);
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var major = VERSION.split('.')[0];
var GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for("opentelemetry.js.api." + major);
var _global = _globalThis;
function registerGlobal(type, instance, diag, allowOverride) {
var _a;
if (allowOverride === void 0) { allowOverride = false; }
var api = (_global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : {
version: VERSION,
});
if (!allowOverride && api[type]) {
// already registered an API of this type
var err = new Error("@opentelemetry/api: Attempted duplicate registration of API: " + type);
diag.error(err.stack || err.message);
return false;
}
if (api.version !== VERSION) {
// All registered APIs must be of the same version exactly
var err = new Error("@opentelemetry/api: Registration of version v" + api.version + " for " + type + " does not match previously registered API v" + VERSION);
diag.error(err.stack || err.message);
return false;
}
api[type] = instance;
diag.debug("@opentelemetry/api: Registered a global for " + type + " v" + VERSION + ".");
return true;
}
function getGlobal(type) {
var _a, _b;
var globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version;
if (!globalVersion || !isCompatible(globalVersion)) {
return;
}
return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type];
}
function unregisterGlobal(type, diag) {
diag.debug("@opentelemetry/api: Unregistering a global for " + type + " v" + VERSION + ".");
var api = _global[GLOBAL_OPENTELEMETRY_API_KEY];
if (api) {
delete api[type];
}
}
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __read$3 = (undefined && undefined.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray$3 = (undefined && undefined.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
/**
* Component Logger which is meant to be used as part of any component which
* will add automatically additional namespace in front of the log message.
* It will then forward all message to global diag logger
* @example
* const cLogger = diag.createComponentLogger({ namespace: '@opentelemetry/instrumentation-http' });
* cLogger.debug('test');
* // @opentelemetry/instrumentation-http test
*/
var DiagComponentLogger = /** @class */ (function () {
function DiagComponentLogger(props) {
this._namespace = props.namespace || 'DiagComponentLogger';
}
DiagComponentLogger.prototype.debug = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy('debug', this._namespace, args);
};
DiagComponentLogger.prototype.error = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy('error', this._namespace, args);
};
DiagComponentLogger.prototype.info = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy('info', this._namespace, args);
};
DiagComponentLogger.prototype.warn = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy('warn', this._namespace, args);
};
DiagComponentLogger.prototype.verbose = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy('verbose', this._namespace, args);
};
return DiagComponentLogger;
}());
function logProxy(funcName, namespace, args) {
var logger = getGlobal('diag');
// shortcut if logger not set
if (!logger) {
return;
}
args.unshift(namespace);
return logger[funcName].apply(logger, __spreadArray$3([], __read$3(args), false));
}
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Defines the available internal logging levels for the diagnostic logger, the numeric values
* of the levels are defined to match the or