agentlang
Version:
The easiest way to build the most reliable AI agents - enterprise-grade teams of AI agents that collaborate with each other and humans
688 lines • 19.7 kB
JavaScript
var _a;
import { parseHelper } from 'langium/test';
import { escapeQueryName, trimQuotes } from '../runtime/util.js';
import { isDecisionDefinition } from './generated/ast.js';
import { createAgentlangServices } from './agentlang-module.js';
import { EmptyFileSystem } from 'langium';
import { introspect, parseModule } from './parser.js';
export class BasePattern {
setAlias(alias) {
this.alias = alias;
return this;
}
unsetAlias() {
this.alias = undefined;
return this;
}
addAlias(alias) {
if (this.aliases === undefined) {
this.aliases = [];
}
this.aliases.push(alias);
}
setAliases(aliases) {
this.aliases = aliases;
}
addHandler(k, handler) {
if (this.handlers === undefined) {
this.handlers = new Map();
}
this.handlers.set(k, handler);
}
aliasesAsString() {
if (this.alias) {
return ` ${this.alias}`;
}
else if (this.aliases) {
return ` [${this.aliases.join(',')}]`;
}
else {
return undefined;
}
}
handlersAsString() {
if (this.handlers) {
let s = '{';
this.handlers.forEach((handler, k) => {
s = `${s} ${k} ${handler.toString()}\n`;
});
return s + '}';
}
else {
return undefined;
}
}
hintsAsString() {
const a = this.aliasesAsString();
const h = this.handlersAsString();
if (!a && !h)
return '';
if (a && !h)
return a;
if (!a && h)
return h;
return `${a}\n${h}`;
}
toString() {
return '';
}
}
export const EmptyBasePattern = new BasePattern();
export var LiteralPatternType;
(function (LiteralPatternType) {
LiteralPatternType[LiteralPatternType["ID"] = 0] = "ID";
LiteralPatternType[LiteralPatternType["NUMBER"] = 1] = "NUMBER";
LiteralPatternType[LiteralPatternType["BOOLEAN"] = 2] = "BOOLEAN";
LiteralPatternType[LiteralPatternType["STRING"] = 3] = "STRING";
LiteralPatternType[LiteralPatternType["REFERENCE"] = 4] = "REFERENCE";
LiteralPatternType[LiteralPatternType["MAP"] = 5] = "MAP";
LiteralPatternType[LiteralPatternType["ARRAY"] = 6] = "ARRAY";
})(LiteralPatternType || (LiteralPatternType = {}));
export class LiteralPattern extends BasePattern {
constructor(type, value) {
super();
this.type = type;
this.value = value;
}
static Id(value) {
return new LiteralPattern(LiteralPatternType.ID, value);
}
static Number(value) {
return new LiteralPattern(LiteralPatternType.NUMBER, value);
}
static Boolean(value) {
return new LiteralPattern(LiteralPatternType.BOOLEAN, value);
}
static String(value) {
return new LiteralPattern(LiteralPatternType.STRING, value);
}
static Reference(value) {
if (value.indexOf('.') < 0) {
throw new Error(`${value} does not look like a reference`);
}
return new LiteralPattern(LiteralPatternType.REFERENCE, value);
}
static Map(value) {
return new LiteralPattern(LiteralPatternType.MAP, value);
}
static Array(value) {
return new LiteralPattern(LiteralPatternType.ARRAY, value);
}
toString() {
let s = '';
switch (this.type) {
case LiteralPatternType.ARRAY: {
const a = this.value;
s = `[${a
.map((v) => {
return v.toString();
})
.join(', ')}]`;
break;
}
case LiteralPatternType.MAP: {
const m = this.value;
const arr = new Array();
m.forEach((v, key) => {
let k = key.str;
if (k === undefined) {
k = key.num;
}
else {
k = `"${k}"`;
}
if (k === undefined) {
k = key.bool;
}
arr.push(`${k}: ${v.toString()}`);
});
s = `{${arr.join(', ')}}`;
break;
}
case LiteralPatternType.STRING: {
s = `"${this.value}"`;
break;
}
default:
s = this.value.toString();
}
return s.concat(this.hintsAsString());
}
}
LiteralPattern.EmptyArray = new LiteralPattern(LiteralPatternType.ARRAY, []);
export function isLiteralPattern(p) {
return p instanceof LiteralPattern;
}
export function isReferenceLiteral(p) {
return p.type == LiteralPatternType.REFERENCE;
}
export function referenceParts(p) {
if (isReferenceLiteral(p)) {
const s = p.value;
return s.split('.');
}
return undefined;
}
export function isStringLiteral(p) {
return p.type == LiteralPatternType.STRING;
}
export function isNumberLiteral(p) {
return p.type == LiteralPatternType.NUMBER;
}
export function isBooleanLiteral(p) {
return p.type == LiteralPatternType.BOOLEAN;
}
export function isIdentifierLiteral(p) {
return p.type == LiteralPatternType.ID;
}
export function isArrayLiteral(p) {
return p.type == LiteralPatternType.ARRAY;
}
export function isMapLiteral(p) {
return p.type == LiteralPatternType.MAP;
}
export class FunctionCallPattern extends BasePattern {
constructor(fnName, args) {
super();
this.isAsync = false;
this.fnName = fnName;
this.arguments = args;
}
asAsync() {
this.isAsync = true;
return this;
}
toString() {
let s = '';
if (this.arguments.length > 0) {
const args = [];
this.arguments.forEach((bp) => {
args.push(bp.toString());
});
s = `${this.fnName}(${args.join(', ')})`;
}
else {
s = `${this.fnName}()`;
}
s = s.concat(this.hintsAsString());
if (this.isAsync) {
return `await ${s}`;
}
else {
return s;
}
}
}
export function isFunctionCallPattern(p) {
return p instanceof FunctionCallPattern;
}
export class ExpressionPattern extends BasePattern {
constructor(expression) {
super();
this.expression = expression;
}
static async Validated(exprString) {
const result = await _a.parse(`module Temp workflow Test { if (${exprString}) {} }`);
if (result.parseResult.lexerErrors.length > 0) {
throw new Error(result.parseResult.lexerErrors.join('\n'));
}
if (result.parseResult.parserErrors.length > 0) {
throw new Error(result.parseResult.parserErrors.join('\n'));
}
return new _a(exprString);
}
toString() {
const s = this.expression.toString();
return s.concat(this.hintsAsString());
}
}
_a = ExpressionPattern;
ExpressionPattern.services = createAgentlangServices(EmptyFileSystem);
ExpressionPattern.doParse = parseHelper(_a.services.Agentlang);
ExpressionPattern.parse = (input) => _a.doParse(input, { validation: true });
export function isExpressionPattern(p) {
return p instanceof ExpressionPattern;
}
export class GroupExpressionPattern extends BasePattern {
constructor(expr) {
super();
this.expression = expr;
}
toString() {
return `(${this.expression.toString()})`;
}
}
export function isGroupExpressionPattern(p) {
return p instanceof GroupExpressionPattern;
}
export class NegExpressionPattern extends BasePattern {
constructor(expr) {
super();
this.expression = expr;
}
toString() {
return `-${this.expression.toString}`;
}
}
export class NotExpressionPattern extends BasePattern {
constructor(expr) {
super();
this.expression = expr;
}
toString() {
return `not(${this.expression.toString})`;
}
}
export function isNegExpressionPattern(p) {
return p instanceof NegExpressionPattern;
}
export function isNotExpressionPattern(p) {
return p instanceof NotExpressionPattern;
}
export class ReferencePattern extends BasePattern {
constructor(record, member) {
super();
this.record = record;
this.member = member;
}
toString() {
return `${this.record}.${this.member}`.concat(this.hintsAsString());
}
}
export function isReferencePattern(p) {
return p instanceof ReferencePattern;
}
export class CrudPattern extends BasePattern {
constructor(recordName) {
super();
this.isQuery = false;
this.isQueryUpdate = false;
this.isCreate = false;
this.recordName = recordName;
this.attributes = [];
if (recordName.endsWith('?')) {
this.isQuery = true;
}
else {
this.isCreate = true;
}
}
addAttribute(n, p, op) {
this.attributes.push({ name: n, op: op, value: p });
if (this.recordName.endsWith('?')) {
this.recordName = this.recordName.substring(0, this.recordName.length - 1);
}
this.flagType();
return this;
}
removeAttribute(n) {
const idx = this.attributes.findIndex((ap) => {
return n == ap.name;
});
if (idx >= 0) {
this.attributes.splice(idx, 1);
}
this.flagType();
return this;
}
addInto(alias, attr) {
if (this.into === undefined) {
this.into = new Map();
}
this.into.set(alias, attr);
return this;
}
removeInto(alias) {
if (this.into) {
this.into.delete(alias);
}
return this;
}
resetInto(into) {
this.into = into;
return this;
}
hasInto() {
if (this.into && this.into.size > 0) {
return true;
}
else {
return false;
}
}
flagType() {
let hasq = false;
let hasc = false;
for (let i = 0; i < this.attributes.length; ++i) {
if (hasq && hasc)
break;
const ap = this.attributes[i];
hasq = ap.name.endsWith('?');
if (!hasc)
hasc = !hasq;
}
if (hasq && hasc) {
this.isQueryUpdate = true;
this.isQuery = false;
this.isCreate = false;
}
else if (hasc) {
this.isCreate = true;
this.isQuery = false;
this.isQueryUpdate = false;
}
else {
this.isQuery = hasq;
this.isCreate = false;
this.isQueryUpdate = false;
}
}
addRelationship(n, p) {
if (this.relationships === undefined) {
this.relationships = new Map();
}
this.relationships.set(n, p);
return this;
}
removeRelationship(n) {
if (this.relationships) {
this.relationships.delete(n);
}
return this;
}
attributesAsString() {
const result = [];
this.attributes.forEach((ap) => {
result.push(`${ap.name}${ap.op ? ap.op : ''} ${ap.value.toString()}`);
});
const s = result.join(', ');
return `{${s}}`;
}
relationshipsAsString() {
if (this.relationships !== undefined) {
const result = [];
this.relationships.forEach((p, n) => {
const ps = p instanceof Array ? `[${patternsToString(p, ',')}]` : p.toString();
result.push(`${n} ${ps}`);
});
return result.join(',');
}
else {
return undefined;
}
}
getNormalizedRecordName() {
return escapeQueryName(this.recordName);
}
intoAsString() {
if (this.into) {
const ss = new Array();
this.into.forEach((attr, alias) => {
ss.push(`${alias} ${attr}`);
});
return ` { ${ss.join(',\n')} }`;
}
return undefined;
}
toString() {
let s = `{${this.recordName} ${this.attributesAsString()}`;
const rs = this.relationshipsAsString();
if (rs) {
s = s.concat(`,${rs}`);
}
const ins = this.intoAsString();
if (ins) {
s = s.concat(`,${ins}`);
}
return s.concat('}', this.hintsAsString());
}
}
export function isCrudPattern(p) {
return p instanceof CrudPattern;
}
export function isCreatePattern(p) {
return isCrudPattern(p) && p.isCreate;
}
export function isQueryPattern(p) {
return isCrudPattern(p) && p.isQuery;
}
export function isQueryUpdatePattern(p) {
return isCrudPattern(p) && p.isQueryUpdate;
}
export class ForEachPattern extends BasePattern {
constructor(variable, source) {
super();
this.variable = variable ? variable : 'X';
this.source = source ? source : LiteralPattern.EmptyArray;
this.body = [];
}
addPattern(p) {
this.body.push(p);
return this;
}
removePattern(index) {
this.body.splice(index, 1);
return this;
}
setPatternAt(p, index) {
this.body[index] = p;
return this;
}
removePatternAt(index) {
this.body.splice(index, 1);
return this;
}
getPatternAt(index) {
return this.body[index];
}
setVariable(s) {
this.variable = s;
return this;
}
setSourcePattern(p) {
this.source = p;
return this;
}
toString() {
if (this.source === undefined || this.variable === undefined) {
throw new Error('`for` requires variable and source-pattern');
}
let s = `for ${this.variable} in ${this.source.toString()}`;
s = s.concat(`{${patternsToString(this.body)}}`);
return s.concat(this.hintsAsString());
}
}
export function isForEachPattern(p) {
return p instanceof ForEachPattern;
}
export class IfPattern extends BasePattern {
constructor(condition) {
super();
this.condition = condition ? condition : IfPattern.True;
this.body = [];
}
isEmpty() {
if (this.condition === IfPattern.True && this.body.length === 0) {
return true;
}
else {
return false;
}
}
addPattern(p) {
this.body.push(p);
return this;
}
removePattern(index) {
this.body.splice(index, 1);
return this;
}
setPatternAt(p, index) {
this.body[index] = p;
return this;
}
removePatternAt(index) {
this.body.splice(index, 1);
return this;
}
getPatternAt(index) {
return this.body[index];
}
setConditionPattern(p) {
this.condition = p;
return this;
}
setElse(elseBody) {
this.elseBody = elseBody ? elseBody : new Array();
return this;
}
removeElse() {
this.elseBody = undefined;
return this;
}
toString() {
let s = `if(${this.condition.toString()}) {`;
s = s.concat(patternsToString(this.body), '}');
if (this.elseBody) {
if (this.elseBody.length == 1 && this.elseBody[0] instanceof IfPattern) {
s = s.concat(` else ${this.elseBody[0].toString()}`);
}
else {
s = s.concat(` else {${patternsToString(this.elseBody)}}`);
}
}
return s.concat(this.hintsAsString());
}
}
IfPattern.True = new LiteralPattern(LiteralPatternType.BOOLEAN, true);
export function isIfPattern(p) {
return p instanceof IfPattern;
}
export class CasePattern extends BasePattern {
constructor(condition, body) {
super();
this.condition = condition;
this.body = body;
}
static async FromString(s) {
var _b;
const ss = s.trimStart();
if (ss.startsWith('case')) {
const m = await parseModule(`module T\ndecision D {\n${ss}}`);
const d = m.defs[0];
if (isDecisionDefinition(d) && d.body) {
const c = d.body.cases[0];
const b = await introspect(((_b = c.statements[0].$cstNode) === null || _b === void 0 ? void 0 : _b.text) || '');
return new CasePattern(new ExpressionPattern(c.cond), b[0]);
}
else {
throw new Error(`Failed to parse ${s}`);
}
}
throw new Error(`Not a case expression - ${s}`);
}
toString() {
return `case (${this.condition.toString()}) {
${this.body.toString()}
}`;
}
}
export function isCasePattern(p) {
return p instanceof CasePattern;
}
export function newCreatePattern(recName) {
const cp = new CrudPattern(recName);
cp.isCreate = true;
return cp;
}
export function newQueryPattern(recName, forQueryUpdate = false) {
recName = recName.charAt(recName.length - 1) == '?' ? recName : recName + '?';
const cp = new CrudPattern(recName);
cp.isCreate = false;
if (forQueryUpdate) {
cp.isQueryUpdate = true;
}
else {
cp.isQuery = true;
}
return cp;
}
export function newQueryUpdatePattern(recName) {
return newQueryPattern(recName, true);
}
export class DeletePattern extends BasePattern {
constructor(pattern) {
super();
this.pattern = pattern;
}
toString() {
return `delete ${this.pattern.toString()}`.concat(this.hintsAsString());
}
}
export class ReturnPattern extends BasePattern {
constructor(pattern) {
super();
this.pattern = pattern;
}
toString() {
return `return ${this.pattern.toString()}`.concat(this.hintsAsString());
}
}
export class FullTextSearchPattern extends BasePattern {
constructor(name, query, options) {
super();
this.name = name;
this.query = query;
this.options = options;
}
toString() {
const ops = this.options ? this.options.toString() : '';
return `{${this.name} ${this.query.toString()} ${ops}}`;
}
}
export function isDeletePattern(p) {
return p instanceof DeletePattern;
}
export function newDeletePattern(recName) {
const qp = newQueryPattern(recName);
return new DeletePattern(qp);
}
function patternsToString(body, sep = ';\n') {
return body
.map((p) => {
return p.toString();
})
.join(sep);
}
export class FlowStepPattern extends BasePattern {
constructor(first, next, condition) {
super();
this.first = first;
this.next = next;
this.condition = condition ? trimQuotes(condition) : undefined;
}
static Parse(s) {
const parts = s.trim().split(' ');
const first = parts[0];
if (parts[1] == '-->') {
if (parts.length == 3) {
return new FlowStepPattern(first, parts[2]);
}
else {
return new FlowStepPattern(first, parts[3], parts[2]);
}
}
else {
throw new Error(`Invalid flow-step format in ${s}`);
}
}
toString() {
if (this.condition) {
return `${this.first} --> "${this.condition}" ${this.next}`;
}
else {
return `${this.first} --> ${this.next}`;
}
}
}
//# sourceMappingURL=syntax.js.map