@convo-lang/convo-lang
Version:
The language of AI
1,326 lines • 52.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getConvoMarkdownVar = exports.defaultConvoVars = void 0;
const common_1 = require("@iyio/common");
const vfs_1 = require("@iyio/vfs");
const date_fns_1 = require("date-fns");
const ConvoError_1 = require("./ConvoError");
const convo_lib_1 = require("./convo-lib");
const convo_pipe_1 = require("./convo-pipe");
const convo_scene_lib_1 = require("./convo-scene-lib");
const convo_types_1 = require("./convo-types");
const convo_zod_1 = require("./convo-zod");
const convoScopeFunctionReadDoc_1 = require("./scope-functions/convoScopeFunctionReadDoc");
const ifFalse = Symbol();
const ifTrue = Symbol();
const breakIteration = Symbol();
const mapFn = (0, convo_lib_1.makeAnyConvoType)('map', (0, convo_lib_1.createConvoScopeFunction)({
usesLabels: true,
}, convo_lib_1.convoLabeledScopeParamsToObj));
const arrayFn = (0, convo_lib_1.makeAnyConvoType)('array', (scope) => {
return scope.paramValues ?? [];
});
const and = (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope) {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
return scope.i + 1;
}
else {
return false;
}
}
}, scope => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
return value ? true : false;
});
const or = (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope) {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
return false;
}
else {
return scope.i + 1;
}
}
}, scope => {
return scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
});
const describeStruct = (0, convo_lib_1.createConvoScopeFunction)(scope => {
const type = (0, convo_zod_1.convoValueToZodType)(scope.paramValues?.[0]);
if (!(0, common_1.valueIsZodObject)(type)) {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'The first arg of new should be a type variable');
}
return (0, convo_zod_1.describeConvoScheme)(type, scope.paramValues?.[1]);
});
exports.defaultConvoVars = {
[convo_lib_1.convoBodyFnName]: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
catchReturn: true,
}),
string: (0, convo_lib_1.createConvoBaseTypeDef)('string'),
number: (0, convo_lib_1.createConvoBaseTypeDef)('number'),
int: (0, convo_lib_1.createConvoBaseTypeDef)('int'),
time: (0, convo_lib_1.createConvoBaseTypeDef)('time'),
void: (0, convo_lib_1.createConvoBaseTypeDef)('void'),
boolean: (0, convo_lib_1.createConvoBaseTypeDef)('boolean'),
any: (0, convo_lib_1.createConvoBaseTypeDef)('any'),
object: (0, convo_lib_1.createConvoBaseTypeDef)('object'),
['true']: true,
['false']: false,
['null']: null,
['undefined']: undefined,
[convo_lib_1.convoGlobalRef]: undefined,
[convo_lib_1.convoPipeFnName]: convo_pipe_1.convoPipeScopeFunction,
[convo_lib_1.convoStructFnName]: (0, convo_lib_1.makeAnyConvoType)('map', (0, convo_lib_1.createConvoScopeFunction)({
usesLabels: true,
}, (scope) => {
scope.cm = true;
return (0, convo_lib_1.convoLabeledScopeParamsToObj)(scope);
})),
[convo_lib_1.convoMapFnName]: mapFn,
[convo_lib_1.convoArrayFnName]: arrayFn,
[convo_lib_1.convoJsonMapFnName]: mapFn,
[convo_lib_1.convoJsonArrayFnName]: arrayFn,
[convo_lib_1.convoArgsName]: undefined,
[convo_lib_1.convoEnumFnName]: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const type = (0, convo_lib_1.createConvoType)({
type: 'enum',
enumValues: scope.paramValues ?? [],
});
const metadata = (0, convo_lib_1.createConvoMetadataForStatement)(scope.s);
type[convo_lib_1.convoMetadataKey] = metadata;
return type;
}),
is: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const type = scope.paramValues[scope.paramValues.length - 1];
if (!type || (typeof type !== 'object')) {
return false;
}
const scheme = (0, convo_zod_1.convoValueToZodType)(type);
for (let i = 0; i < scope.paramValues.length - 1; i++) {
const p = scheme.safeParse(scope.paramValues[i]);
if (!p.success) {
return false;
}
}
return true;
}),
and,
or,
not: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return true;
}
for (let i = 0; i < scope.paramValues.length; i++) {
if (scope.paramValues[i]) {
return false;
}
}
return true;
}),
if: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope, parentScope) {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
return scope.i + 1;
}
else {
if (parentScope) {
parentScope.i++;
}
return false;
}
}
}, (scope) => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
return value ? ifTrue : ifFalse;
}),
elif: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
shouldExecute(scope, parentScope) {
const prev = (parentScope?.paramValues && parentScope.paramValues[parentScope.paramValues.length - 1]);
return prev === ifFalse;
},
nextParam(scope) {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
return scope.i + 1;
}
else {
return false;
}
}
}, scope => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
return value ? ifTrue : ifFalse;
}),
else: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
shouldExecute(scope, parentScope) {
const prev = (parentScope?.paramValues && parentScope.paramValues[parentScope.paramValues.length - 1]);
return prev === ifFalse;
},
}, () => {
return ifTrue;
}),
then: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
shouldExecute(scope, parentScope) {
const prev = (parentScope?.paramValues && parentScope.paramValues[parentScope.paramValues.length - 1]);
return prev === ifTrue;
},
}, () => {
return ifTrue;
}),
while: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope, parentScope) {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (scope.i === 0 && parentScope) {
delete parentScope.fromIndex;
}
if (scope.s.params && scope.i === scope.s.params.length - 1 && parentScope) {
if (value) {
parentScope.fromIndex = parentScope.i + 1;
parentScope.gotoIndex = parentScope.i;
parentScope.li = parentScope.i + 1;
}
}
if (value) {
return scope.i + 1;
}
else {
if (parentScope) {
parentScope.i++;
}
return false;
}
}
}, (scope) => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
scope.ctrlData = ifTrue;
}
return scope.ctrlData ?? ifFalse;
}),
foreach: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
keepData: true,
startParam(scope, parentScope) {
if (!scope.s.params?.length) {
if (parentScope) {
parentScope.i++;
}
return false;
}
return 0;
},
nextParam(scope, parentScope) {
if (scope.paramValues?.[0] === breakIteration) {
if (parentScope) {
parentScope.i++;
}
return false;
}
if (parentScope && scope.i + 1 === scope.s.params?.length) {
parentScope.fromIndex = parentScope.i + 1;
parentScope.gotoIndex = parentScope.i;
parentScope.li = parentScope.i + 1;
}
return scope.i + 1;
}
}, (scope) => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
if (value) {
scope.ctrlData = ifTrue;
}
return scope.ctrlData ?? ifFalse;
}),
in: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
keepData: true,
nextParam(scope) {
const value = scope.paramValues?.[0];
if (!value || (typeof value !== 'object')) {
return false;
}
let it = scope.ctrlData;
if (!it) {
it = { i: 0 };
if (!Array.isArray(value)) {
it.keys = Object.keys(value);
}
scope.ctrlData = it;
}
return false;
}
}, (scope) => {
const it = scope.ctrlData;
if (!it) {
return breakIteration;
}
const value = scope.paramValues?.[0];
const isArray = Array.isArray(value);
const ary = it.keys ?? value;
if (it.i >= ary.length) {
return breakIteration;
}
const r = isArray ? value[it.i] : { key: ary[it.i], value: value[ary[it.i]] };
it.i++;
return r;
}),
break: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope, parentScope) {
if (parentScope?.paramValues) {
scope.ctrlData = parentScope.paramValues[parentScope.paramValues.length - 1];
}
return scope.i + 1;
}
}, (scope) => {
if (!scope.paramValues?.length) {
scope.bl = true;
return scope.ctrlData;
}
for (let i = 0; i < scope.paramValues.length; i++) {
if (scope.paramValues[i]) {
scope.bl = true;
return scope.ctrlData;
}
}
return scope.ctrlData;
}),
do: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
}, scope => {
return scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
}),
fn: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
catchReturn: true,
}, () => {
return undefined;
}),
return: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined;
scope.r = true;
return value;
}),
eq: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
for (let i = 1; i < scope.paramValues.length; i++) {
if (scope.paramValues[i - 1] !== scope.paramValues[i]) {
return false;
}
}
return true;
}),
gt: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
for (let i = 1; i < scope.paramValues.length; i++) {
if (!(scope.paramValues[i - 1] > scope.paramValues[i])) {
return false;
}
}
return true;
}),
gte: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
for (let i = 1; i < scope.paramValues.length; i++) {
if (!(scope.paramValues[i - 1] >= scope.paramValues[i])) {
return false;
}
}
return true;
}),
lt: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
for (let i = 1; i < scope.paramValues.length; i++) {
if (!(scope.paramValues[i - 1] < scope.paramValues[i])) {
return false;
}
}
return true;
}),
lte: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
for (let i = 1; i < scope.paramValues.length; i++) {
if (!(scope.paramValues[i - 1] <= scope.paramValues[i])) {
return false;
}
}
return true;
}),
isIn: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const value = scope.paramValues[0];
const condValue = scope.paramValues[1];
if ((typeof value === 'string') && (typeof condValue === 'string')) {
return value.includes(condValue);
}
else if (Array.isArray(value)) {
return value.includes(condValue);
}
else {
return false;
}
}),
contains: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const value = scope.paramValues[0];
const condValue = scope.paramValues[1];
if ((typeof value === 'string') && (typeof condValue === 'string')) {
return condValue.includes(value);
}
else if (Array.isArray(condValue)) {
return condValue.includes(value);
}
else {
return false;
}
}),
regexMatch: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const value = scope.paramValues[0];
const condValue = scope.paramValues[1];
try {
if (typeof condValue === 'string') {
const reg = new RegExp(condValue);
return reg.test(value);
}
else if (condValue instanceof RegExp) {
return condValue.test(value);
}
else {
return false;
}
}
catch {
return false;
}
}),
starMatch: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const value = scope.paramValues[0];
const condValue = scope.paramValues[1];
if ((typeof value !== 'string') || (typeof condValue !== 'string')) {
return false;
}
else {
return (0, common_1.starStringTest)(condValue, value);
}
}),
deepCompare: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return false;
}
const value = scope.paramValues[0];
const condValue = scope.paramValues[1];
return (0, common_1.deepCompare)(value, condValue, scope.paramValues[2]);
}),
aryRandomize: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const ary = scope.paramValues?.[0];
if (Array.isArray(ary)) {
return (0, common_1.aryRandomize)(ary);
}
return ary;
}),
aryAdd: (0, convo_lib_1.createConvoScopeFunction)(scope => {
let ary = scope.paramValues?.[0];
if (!scope.paramValues || !Array.isArray(ary)) {
return ary;
}
ary = [...ary];
for (let i = 1; i < scope.paramValues.length; i++) {
ary.push(scope.paramValues[i]);
}
return ary;
}),
aryRemove: (0, convo_lib_1.createConvoScopeFunction)(scope => {
let ary = scope.paramValues?.[0];
if (!scope.paramValues || !Array.isArray(ary)) {
return [];
}
ary = [...ary];
for (let i = 1; i < scope.paramValues.length; i++) {
const index = ary.indexOf(scope.paramValues[i]);
if (index === -1) {
continue;
}
ary.splice(index, 1);
i--;
}
return ary;
}),
aryConcat: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const ary = [];
if (!scope.paramValues?.length) {
return ary;
}
for (const v of scope.paramValues) {
if (Array.isArray(v)) {
ary.push(...v);
}
else if (v !== undefined) {
ary.push(v);
}
}
return ary;
}),
aryDistinct: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const ary = [];
if (!scope.paramValues?.length) {
return ary;
}
for (const v of scope.paramValues) {
if (Array.isArray(v)) {
for (const a of v) {
if (!ary.includes(a)) {
ary.push(a);
}
}
}
else if (v !== undefined && !ary.includes(v)) {
ary.push(v);
}
}
return ary;
}),
aryJoin: (0, convo_lib_1.createConvoScopeFunction)(scope => {
let ary = scope.paramValues?.[0];
if (!scope.paramValues || !Array.isArray(ary)) {
return [];
}
if (scope.paramValues.length > 2) {
const out = [];
for (let i = 0; i < ary.length - 1; i++) {
out.push(ary[i]);
out.push(scope.paramValues[1 + (i % (scope.paramValues.length - 1))]);
}
if (ary.length) {
out.push(ary[ary.length - 1]);
}
return out.join('');
}
else {
return ary.join(scope.paramValues[1] ?? ', ');
}
}),
add: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value += v;
}
}
}
return value;
}),
sub: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value -= v;
}
}
}
return value;
}),
mul: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value *= v;
}
}
}
return value;
}),
div: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value /= v;
}
}
}
return value;
}),
mod: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value %= v;
}
}
}
return value;
}),
pow: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
const v = scope.paramValues[i];
if (v !== undefined) {
if (value === undefined) {
value = v;
}
else {
value = Math.pow(value, v);
}
}
}
return value;
}),
print: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
if (scope.paramValues) {
ctx.print(...scope.paramValues);
}
return scope.paramValues?.[scope.paramValues?.length ?? 0];
}),
inc: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
startParam() {
return 1;
}
}, (scope, ctx) => {
if (!scope.s.params) {
return undefined;
}
const value = scope.paramValues?.[0] ?? 1;
let lastValue = value;
const s = scope.s.params[0];
const sv = ctx.getRefValue(s, scope, false);
lastValue = sv === undefined ? value : sv + value;
ctx.setRefValue(s, lastValue, scope);
return lastValue;
}),
dec: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
startParam() {
return 1;
}
}, (scope, ctx) => {
if (!scope.s.params) {
return undefined;
}
const value = scope.paramValues?.[0] ?? 1;
let lastValue = value;
const s = scope.s.params[0];
const sv = ctx.getRefValue(s, scope, false);
lastValue = sv === undefined ? -value : sv - value;
ctx.setRefValue(s, lastValue, scope);
return lastValue;
}),
[convo_lib_1.convoSwitchFnName]: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope) {
if (scope.i === 0) {
if (scope.s.hmc) {
scope.sv = scope.paramValues?.[0];
return 1;
}
else {
return scope.paramValues?.[0] ? 1 : 2;
}
}
if (scope.s.hmc) {
if (scope.s.params && !scope.s.params[scope.i]?.mc) {
scope.sv = scope.paramValues?.[0];
}
const nextIndex = scope.ctrlData;
if (nextIndex === undefined) {
return scope.i + 1;
}
else {
delete scope.ctrlData;
return nextIndex;
}
}
else {
return false;
}
}
}, scope => {
return scope.paramValues?.[0];
}),
[convo_lib_1.convoCaseFnName]: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope, parentScope) {
if (parentScope?.s.fn !== convo_lib_1.convoSwitchFnName || !scope.s.params?.length) {
return false;
}
const isMatch = parentScope.sv === scope.paramValues?.[0];
if (isMatch) { // let control flow move to next statement and do not check anymore statements
parentScope.bi = parentScope.i + 2;
return false;
}
if (scope.i === scope.s.params.length - 1) { // no matches found, skip next statement
parentScope.ctrlData = parentScope.i + 2;
return false;
}
return scope.i + 1;
}
}, () => {
return undefined;
}),
[convo_lib_1.convoDefaultFnName]: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
startParam(scope, parentScope) {
if (parentScope?.s.fn !== convo_lib_1.convoSwitchFnName) {
return false;
}
parentScope.bi = parentScope.i + 2;
return false;
}
}, () => {
return undefined;
}),
[convo_lib_1.convoTestFnName]: (0, convo_lib_1.createConvoScopeFunction)({
discardParams: true,
nextParam(scope, parentScope) {
if (parentScope?.s.fn !== convo_lib_1.convoSwitchFnName || !scope.s.params?.length) {
return false;
}
const isMatch = scope.paramValues?.[0] ? true : false;
if (isMatch) { // let control flow move to next statement and do not check anymore statements
parentScope.bi = parentScope.i + 2;
return false;
}
if (scope.i === scope.s.params.length - 1) { // no matches found, skip next statement
parentScope.ctrlData = parentScope.i + 2;
return false;
}
return scope.i + 1;
}
}, () => {
return undefined;
}),
sleep: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const start = Date.now();
const delay = scope.paramValues?.[0];
return new Promise(r => {
setTimeout(() => {
r(Date.now() - start);
}, typeof delay === 'number' ? delay : 0);
});
}),
rand: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const range = scope.paramValues?.[0];
if (typeof range === 'number') {
return Math.round(Math.random() * range);
}
else {
return Math.random();
}
}),
[convo_lib_1.convoFunctions.idx]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
if (!scope.paramValues) {
return undefined;
}
let value = scope.paramValues[0];
for (let i = 1; i < scope.paramValues.length; i++) {
value = value?.[ctx.getVar(scope.paramValues?.[1] ?? '', scope, '')];
}
return value;
}),
[convo_lib_1.convoFunctions.setDefault]: (0, convo_lib_1.createConvoScopeFunction)({ usesLabels: true }, (scope, ctx) => {
const obj = mapFn(scope, ctx);
if (obj) {
for (const e in obj) {
ctx.setDefaultVarValue(obj[e], e);
}
}
return obj;
}),
httpGet: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
let url = scope.paramValues?.[0];
let options = scope.paramValues?.[1];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
if (options && (typeof options !== 'object')) {
url += `${url.includes('?') ? '&' : '?'}__input=${encodeURIComponent(options.toString())}`;
options = undefined;
}
return await (0, common_1.httpClient)().getAsync(url, options);
}),
httpGetString: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const url = scope.paramValues?.[0];
const options = scope.paramValues?.[1];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
return await (0, common_1.httpClient)().getStringAsync(url, options);
}),
httpPost: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const url = scope.paramValues?.[0];
const body = scope.paramValues?.[1];
const options = scope.paramValues?.[2];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
return await (0, common_1.httpClient)().postAsync(url, body, options);
}),
httpPut: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const url = scope.paramValues?.[0];
const body = scope.paramValues?.[1];
const options = scope.paramValues?.[2];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
return await (0, common_1.httpClient)().putAsync(url, body, options);
}),
httpPatch: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const url = scope.paramValues?.[0];
const body = scope.paramValues?.[1];
const options = scope.paramValues?.[2];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
return await (0, common_1.httpClient)().patchAsync(url, body, options);
}),
httpDelete: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const url = scope.paramValues?.[0];
const options = scope.paramValues?.[1];
if (typeof url !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, "First arg must be a string URL");
}
return await (0, common_1.httpClient)().deleteAsync(url, options);
}),
encodeURI: (0, convo_lib_1.createConvoScopeFunction)(scope => {
return encodeURI(scope.paramValues?.[0]?.toString() ?? '');
}),
encodeURIComponent: (0, convo_lib_1.createConvoScopeFunction)(scope => {
return encodeURIComponent(scope.paramValues?.[0]?.toString() ?? '');
}),
now: (0, convo_lib_1.createConvoScopeFunction)(() => {
return Date.now();
}),
dateTime: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const f = scope.paramValues?.[0] ?? convo_lib_1.convoDateFormat;
let time = scope.paramValues?.[1] ?? new Date();
switch (typeof time) {
case 'string':
time = new Date(time);
break;
case 'number':
break;
default:
if (!(time instanceof Date)) {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'Second arg of timeTime must be a string, number or Date object');
}
break;
}
try {
return (0, date_fns_1.format)(time, f);
}
catch {
return (0, date_fns_1.format)(time, convo_lib_1.convoDateFormat);
}
}),
[convo_lib_1.convoFunctions.today]: (0, convo_lib_1.createConvoScopeFunction)(() => {
return (0, date_fns_1.format)(new Date(), 'yyyy-MM-dd');
}),
md: (0, convo_lib_1.createConvoScopeFunction)((scope) => {
if (!scope.paramValues?.length) {
return '';
}
const out = [];
for (let i = 0; i < scope.paramValues.length; i++) {
const value = scope.paramValues[i];
if (value === undefined) {
out.push('undefined');
}
else if (value === null) {
out.push('null');
}
else if ((typeof value === 'object') && !isPrimitiveArray(value) && !(value instanceof Date)) {
try {
out.push(JSON.stringify(value, null, 4));
}
catch {
try {
out.push(JSON.stringify(value, (0, common_1.createJsonRefReplacer)(), 4));
}
catch {
out.push('[[object with excessive recursive references]]');
}
}
}
else {
(0, common_1.objectToMarkdownBuffer)(value, out, '', 5);
}
}
return out.join('');
}),
toMarkdown: (0, convo_lib_1.createConvoScopeFunction)(scope => {
if (!scope.paramValues?.length) {
return '';
}
const maxDepth = scope.paramValues[0];
if (typeof maxDepth !== 'number') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'The first arg of toMarkdown must be a number indicating the max depth');
}
const out = [];
for (let i = 1; i < scope.paramValues.length; i++) {
(0, common_1.objectToMarkdownBuffer)(scope.paramValues[i], out, '', maxDepth);
}
return out.join('');
}),
toJson: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues?.[0];
if (value === undefined) {
return 'undefined';
}
return JSON.stringify(value, (0, common_1.createJsonRefReplacer)(), 4);
}),
toJsonMdBlock: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues?.[0];
return ('``` json\n' +
value === undefined ? 'undefined' : JSON.stringify(value, (0, common_1.createJsonRefReplacer)(), 4) +
'\n```');
}),
toJsonScheme: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues?.[0];
return JSON.stringify((0, convo_zod_1.convoTypeToJsonScheme)(value));
}),
toCsv: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues?.[0];
if (!Array.isArray(value)) {
return '"!Invalid CSV Data"';
}
return (0, common_1.toCsvLines)(value);
}),
toCsvMdBlock: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = scope.paramValues?.[0];
if (!Array.isArray(value)) {
return '"!Invalid CSV Data"';
}
return '``` csv\n' + (0, common_1.toCsvLines)(value) + '\n```';
}),
merge: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const value = {};
if (scope.paramValues) {
for (let i = 0; i < scope.paramValues.length; i++) {
const item = scope.paramValues[i];
if (item && (typeof item === 'object')) {
for (const e in item) {
const v = item[e];
if (v !== undefined) {
value[e] = v;
}
}
}
}
}
return value;
}),
setObjDefaults: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
let target = scope.paramValues?.[0];
const source = scope.paramValues?.[1];
if (typeof target === 'string') {
let t = ctx.getVar(target, scope);
if (t === undefined) {
const parts = target.split('.');
target = parts.pop() ?? '_';
t = {};
ctx.setVar(true, t, target, parts.length ? parts : undefined);
}
target = t;
}
if (!target || !source || (typeof target !== 'object') || (typeof source !== 'object')) {
return target;
}
for (const e in source) {
const v = source[e];
if (v === undefined || target[e] !== undefined) {
continue;
}
target[e] = v;
}
return target;
}),
['new']: (0, convo_lib_1.createConvoScopeFunction)(scope => {
const type = (0, convo_zod_1.convoValueToZodType)(scope.paramValues?.[0]);
if (!(0, common_1.valueIsZodObject)(type)) {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'The first arg of new should be a type variable');
}
const r = type.safeParse(scope.paramValues?.[1] ?? {});
if (r.success) {
return r.data;
}
else {
throw new ConvoError_1.ConvoError('missing-defaults', { statement: scope.s }, 'The type has missing property defaults and can not be used with the new function - ' + r.error.message);
}
}),
tmpl: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
const name = scope.paramValues?.[0];
const format = scope.paramValues?.[1] ?? 'plain';
const md = ctx.getVar(convo_lib_1.convoVars.__md, null, null);
if (!md) {
return '';
}
return (0, exports.getConvoMarkdownVar)(name, format, ctx);
}),
html: (0, convo_lib_1.createConvoScopeFunction)((scope) => {
const params = scope.paramValues;
if (!params?.length) {
return '';
}
if (params.length === 1) {
return (0, common_1.escapeHtml)(params[0]?.toString?.() ?? '');
}
const out = [];
for (let i = 0; i < params.length; i++) {
const p = params[i];
if (!p) {
out.push((0, common_1.escapeHtml)(p.toString?.() ?? ''));
}
}
return out.join('\n');
}),
describeStruct,
xAtt: (0, convo_lib_1.createConvoScopeFunction)((scope) => {
const value = scope.paramValues?.[0];
switch (typeof value) {
case 'string':
if (value.startsWith('{') && value.endsWith('}')) {
return `"\\${(0, common_1.escapeHtml)(value)}"`;
}
else {
return `"${(0, common_1.escapeHtml)(value)}"`;
}
case 'number':
case 'boolean':
case 'bigint':
return `"{${value}}"`;
case 'undefined':
return '"{undefined}"';
default:
try {
return `'{${(0, common_1.escapeHtmlKeepDoubleQuote)(JSON.stringify(value))}}'`;
}
catch (ex) {
return `'{${(0, common_1.escapeHtmlKeepDoubleQuote)(JSON.stringify({
__error: (0, common_1.getErrorMessage)(ex)
}))}}'`;
}
}
}),
openBrowserWindow: (0, convo_lib_1.createConvoScopeFunction)((scope) => {
const url = scope.paramValues?.[0];
const target = scope.paramValues?.[1] ?? '_blank';
if ((typeof url !== 'string') || (typeof target !== 'string')) {
return false;
}
globalThis.window?.open(url, target);
return true;
}),
[convo_lib_1.convoFunctions.enableRag]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
ctx.enableRag(Array.isArray(scope.paramValues) ? scope.paramValues : undefined);
}),
[convo_lib_1.convoFunctions.clearRag]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
ctx.clearRag();
}),
[convo_lib_1.convoFunctions.shortUuid]: (0, convo_lib_1.createConvoScopeFunction)(() => {
return (0, common_1.shortUuid)();
}),
[convo_lib_1.convoFunctions.uuid]: (0, convo_lib_1.createConvoScopeFunction)(() => {
return (0, common_1.uuid)();
}),
[convo_lib_1.convoFunctions.getVar]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
const name = scope.paramValues?.[0];
if (typeof name !== 'string') {
return undefined;
}
const v = ctx.getVar(name, scope);
return v === undefined ? scope.paramValues?.[1] : v;
}),
[convo_lib_1.convoFunctions.setVar]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
if (!scope.paramValues || scope.paramValues.length < 2) {
return undefined;
}
let name = '';
for (let i = 0; i < scope.paramValues.length - 1; i++) {
const n = scope.paramValues[i];
if (n) {
name += (name ? '.' : '') + n;
}
}
const v = scope.paramValues[scope.paramValues.length - 1];
if (name.includes('.')) {
const parts = name.split('.');
ctx.setVar(true, v, parts.shift(), parts);
}
else {
ctx.setVar(true, v, name);
}
return v;
}),
[convo_lib_1.convoFunctions.describeScene]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
const ctrl = ctx.getVar(convo_lib_1.convoVars.__sceneCtrl);
if (ctrl instanceof common_1.SceneCtrl) {
const scene = ctrl.buildScene();
ctx.setVar(true, scene, convo_lib_1.convoVars.__lastDescribedScene);
return (0, convo_scene_lib_1.createConvoSceneDescription)(scene);
}
else {
return 'Unable to see scene';
}
}),
[convo_lib_1.convoFunctions.readDoc]: convoScopeFunctionReadDoc_1.convoScopeFunctionReadDoc,
[convo_lib_1.convoFunctions.getAgentList]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
const agents = ctx.convo.conversation?.agents;
if (!agents?.length) {
return `<agentList>\n(no agents defined)\n</agentList>`;
}
return `<agentList>\n${agents.map(a => {
const out = [`<agent>\nName: ${a.name}\n`];
if (a.description) {
out.push(`Description: ${a.description}\n\n`);
}
if (a.capabilities.length) {
out.push('Capabilities:\n');
for (const cap of a.capabilities) {
out.push(`- ${cap}\n`);
}
}
out.push('</agent>');
return out.join('');
}).join('\n\n')}\n</agentList>`;
}),
[convo_lib_1.convoFunctions.defineForm]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
const form = (0, common_1.deepClone)(scope.paramValues?.[0]);
if (!form) {
return form;
}
if (ctx.getVar(convo_lib_1.convoVars.__formsEnabled) === undefined) {
ctx.setVar(true, true, convo_lib_1.convoVars.__formsEnabled);
}
let formsAry = ctx.getVar(convo_lib_1.convoVars.__forms);
if (!formsAry || !Array.isArray(formsAry)) {
formsAry = [];
ctx.setVar(true, formsAry, convo_lib_1.convoVars.__forms);
}
if (!form.id) {
form.id = 'form-' + (formsAry.length + 1);
}
if (!form.items) {
form.items = [];
}
for (let i = 0; i < form.items.length; i++) {
let item = form.items[i];
if (!item) {
form.items.splice(i, 1);
i--;
continue;
}
if (typeof item === 'string') {
item = {
id: 'item-' + (i + 1),
type: 'question',
question: item,
};
form.items[i] = item;
}
if (!item.id) {
item.id = 'item-' + (i + 1);
}
}
formsAry.push(form);
}),
[convo_lib_1.convoFunctions.enableTransform]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
if (!scope.paramValues) {
return;
}
for (const t of scope.paramValues) {
if (typeof t === 'string') {
enableTransform(t, ctx);
}
else if (Array.isArray(t)) {
for (const at of t) {
if (typeof at === 'string') {
enableTransform(at, ctx);
}
}
}
}
}),
[convo_lib_1.convoFunctions.enableAllTransforms]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
enableTransform('all', ctx);
}),
[convo_lib_1.convoFunctions.pushConvoTask]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
if (!scope.paramValues) {
return;
}
const str = scope.paramValues.map(v => {
if (typeof v === 'string') {
return v;
}
else if (v === undefined || v === null) {
return '';
}
else {
try {
return JSON.stringify(v);
}
catch {
return v + '';
}
}
}).join(' ');
return ctx.convo.conversation?.addTask({
name: str
});
}),
[convo_lib_1.convoFunctions.popConvoTask]: (0, convo_lib_1.createConvoScopeFunction)((scope, ctx) => {
ctx.convo.conversation?.popTask();
}),
[convo_lib_1.convoFunctions.fsWrite]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
if (!scope.paramValues) {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsWrite expects a file path and value');
}
const path = scope.paramValues[0];
const value = scope.paramValues[1];
if (typeof path !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsWrite expects first argument to be a string');
}
await (0, vfs_1.vfs)().writeObjectAsync(path, value);
return value;
}),
[convo_lib_1.convoFunctions.fsRead]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const path = scope.paramValues?.[0];
if (typeof path !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsRead expects first argument to be a string');
}
return await (0, vfs_1.vfs)().readObjectAsync(path);
}),
[convo_lib_1.convoFunctions.fsRemove]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const path = scope.paramValues?.[0];
if (typeof path !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsRemove expects first argument to be a string');
}
return await (0, vfs_1.vfs)().removeAsync(path);
}),
[convo_lib_1.convoFunctions.fsMkDir]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const path = scope.paramValues?.[0];
if (typeof path !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsMkDir expects first argument to be a string');
}
return await (0, vfs_1.vfs)().mkDirAsync(path);
}),
[convo_lib_1.convoFunctions.fsExists]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const path = scope.paramValues?.[0];
if (typeof path !== 'string') {
throw new ConvoError_1.ConvoError('invalid-args', { statement: scope.s }, 'fsExists expects first argument to be a string');
}
return (await (0, vfs_1.vfs)().getItemAsync(path)) ? true : false;
}),
[convo_lib_1.convoFunctions.joinPaths]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
if (!scope.paramValues) {
return '.';
}
const paths = scope.paramValues.filter(v => v && (typeof v === 'string'));
return (0, common_1.joinPaths)(...paths);
}),
[convo_lib_1.convoFunctions.isUndefined]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
if (!scope.paramValues) {
return true;
}
for (const v of scope.paramValues) {
if (v !== undefined) {
return false;
}
}
return true;
}),
[convo_lib_1.convoFunctions.secondMs]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
return (scope.paramValues?.[0] ?? 0) * 1000;
}),
[convo_lib_1.convoFunctions.minuteMs]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
return (scope.paramValues?.[0] ?? 0) * 60000;
}),
[convo_lib_1.convoFunctions.hourMs]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
return (scope.paramValues?.[0] ?? 0) * 3600000;
}),
[convo_lib_1.convoFunctions.dayMs]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
return (scope.paramValues?.[0] ?? 0) * 86400000;
}),
[convo_lib_1.convoFunctions.aryFindMatch]: (0, convo_lib_1.createConvoScopeFunction)(async (scope) => {
const ary = scope.paramValues?.[0];
const match = scope.paramValues?.[1];
if (!Array.isArray(ary)) {
return undefined;
}
for (let i = 0; i < ary.length; i++) {
const item = ary[i];
if (isShallowEq