agentlang 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/cli/main.d.ts.map +1 -1
- package/out/cli/main.js +35 -6
- package/out/cli/main.js.map +1 -1
- package/out/language/generated/ast.d.ts +23 -4
- package/out/language/generated/ast.d.ts.map +1 -1
- package/out/language/generated/ast.js +29 -1
- package/out/language/generated/ast.js.map +1 -1
- package/out/language/generated/grammar.d.ts.map +1 -1
- package/out/language/generated/grammar.js +251 -171
- package/out/language/generated/grammar.js.map +1 -1
- package/out/language/main.cjs +271 -172
- package/out/language/main.cjs.map +2 -2
- package/out/language/parser.d.ts +1 -0
- package/out/language/parser.d.ts.map +1 -1
- package/out/language/parser.js +25 -9
- package/out/language/parser.js.map +1 -1
- package/out/runtime/agents/common.d.ts +1 -1
- package/out/runtime/agents/common.d.ts.map +1 -1
- package/out/runtime/agents/common.js +4 -1
- package/out/runtime/agents/common.js.map +1 -1
- package/out/runtime/agents/impl/anthropic.d.ts +54 -0
- package/out/runtime/agents/impl/anthropic.d.ts.map +1 -1
- package/out/runtime/agents/impl/anthropic.js +109 -3
- package/out/runtime/agents/impl/anthropic.js.map +1 -1
- package/out/runtime/auth/cognito.d.ts +1 -1
- package/out/runtime/auth/cognito.d.ts.map +1 -1
- package/out/runtime/auth/cognito.js +1 -1
- package/out/runtime/auth/cognito.js.map +1 -1
- package/out/runtime/defs.d.ts +4 -0
- package/out/runtime/defs.d.ts.map +1 -1
- package/out/runtime/defs.js +8 -0
- package/out/runtime/defs.js.map +1 -1
- package/out/runtime/interpreter.d.ts.map +1 -1
- package/out/runtime/interpreter.js +87 -25
- package/out/runtime/interpreter.js.map +1 -1
- package/out/runtime/jsmodules.d.ts +0 -1
- package/out/runtime/jsmodules.d.ts.map +1 -1
- package/out/runtime/jsmodules.js +26 -34
- package/out/runtime/jsmodules.js.map +1 -1
- package/out/runtime/loader.d.ts.map +1 -1
- package/out/runtime/loader.js +58 -50
- package/out/runtime/loader.js.map +1 -1
- package/out/runtime/module.d.ts +2 -2
- package/out/runtime/module.d.ts.map +1 -1
- package/out/runtime/module.js +19 -3
- package/out/runtime/module.js.map +1 -1
- package/out/runtime/modules/ai.d.ts +1 -0
- package/out/runtime/modules/ai.d.ts.map +1 -1
- package/out/runtime/modules/ai.js +7 -1
- package/out/runtime/modules/ai.js.map +1 -1
- package/out/runtime/modules/core.js +1 -1
- package/out/runtime/modules/core.js.map +1 -1
- package/out/runtime/openapi.d.ts +16 -0
- package/out/runtime/openapi.d.ts.map +1 -0
- package/out/runtime/openapi.js +51 -0
- package/out/runtime/openapi.js.map +1 -0
- package/out/runtime/resolvers/interface.d.ts.map +1 -1
- package/out/runtime/resolvers/interface.js +11 -5
- package/out/runtime/resolvers/interface.js.map +1 -1
- package/out/runtime/resolvers/registry.d.ts +1 -2
- package/out/runtime/resolvers/registry.d.ts.map +1 -1
- package/out/runtime/resolvers/registry.js +2 -1
- package/out/runtime/resolvers/registry.js.map +1 -1
- package/out/runtime/state.d.ts +23 -0
- package/out/runtime/state.d.ts.map +1 -1
- package/out/runtime/state.js +7 -0
- package/out/runtime/state.js.map +1 -1
- package/out/runtime/util.d.ts +1 -0
- package/out/runtime/util.d.ts.map +1 -1
- package/out/runtime/util.js +20 -0
- package/out/runtime/util.js.map +1 -1
- package/out/syntaxes/agentlang.monarch.js +1 -1
- package/out/syntaxes/agentlang.monarch.js.map +1 -1
- package/package.json +3 -6
- package/src/cli/main.ts +34 -6
- package/src/language/agentlang.langium +9 -3
- package/src/language/generated/ast.ts +55 -4
- package/src/language/generated/grammar.ts +251 -171
- package/src/language/parser.ts +30 -9
- package/src/runtime/agents/common.ts +4 -1
- package/src/runtime/agents/impl/anthropic.ts +190 -4
- package/src/runtime/auth/cognito.ts +1 -1
- package/src/runtime/defs.ts +12 -0
- package/src/runtime/interpreter.ts +87 -24
- package/src/runtime/jsmodules.ts +26 -37
- package/src/runtime/loader.ts +63 -55
- package/src/runtime/module.ts +27 -3
- package/src/runtime/modules/ai.ts +8 -2
- package/src/runtime/modules/core.ts +1 -1
- package/src/runtime/openapi.ts +74 -0
- package/src/runtime/resolvers/interface.ts +14 -9
- package/src/runtime/resolvers/registry.ts +3 -2
- package/src/runtime/state.ts +9 -0
- package/src/runtime/util.ts +22 -0
- package/src/syntaxes/agentlang.monarch.ts +1 -1
- package/out/cli/docs.d.ts +0 -2
- package/out/cli/docs.d.ts.map +0 -1
- package/out/cli/docs.js +0 -236
- package/out/cli/docs.js.map +0 -1
- package/out/cli/openapi-docs.yml +0 -695
- package/out/index.d.ts +0 -19
- package/out/index.d.ts.map +0 -1
- package/out/index.js +0 -25
- package/out/index.js.map +0 -1
package/src/runtime/loader.ts
CHANGED
|
@@ -57,15 +57,17 @@ import { URI } from 'vscode-uri';
|
|
|
57
57
|
import { AstNode, LangiumCoreServices, LangiumDocument } from 'langium';
|
|
58
58
|
import { isNodeEnv, path } from '../utils/runtime.js';
|
|
59
59
|
import { CoreModules, registerCoreModules } from './modules/core.js';
|
|
60
|
-
import { parse, parseModule, parseWorkflow } from '../language/parser.js';
|
|
60
|
+
import { maybeGetValidationErrors, parse, parseModule, parseWorkflow } from '../language/parser.js';
|
|
61
61
|
import { logger } from './logger.js';
|
|
62
62
|
import { Environment, evaluateStatements, GlobalEnvironment } from './interpreter.js';
|
|
63
63
|
import { createPermission, createRole } from './modules/auth.js';
|
|
64
64
|
import { AgentEntityName, CoreAIModuleName, LlmEntityName } from './modules/ai.js';
|
|
65
65
|
import { GenericResolver, GenericResolverMethods } from './resolvers/interface.js';
|
|
66
|
-
import { registerResolver, setResolver
|
|
66
|
+
import { registerResolver, setResolver } from './resolvers/registry.js';
|
|
67
67
|
import { ConfigSchema } from './state.js';
|
|
68
|
-
import { getModuleFn, importModule
|
|
68
|
+
import { getModuleFn, importModule } from './jsmodules.js';
|
|
69
|
+
import { SetSubscription } from './defs.js';
|
|
70
|
+
import { ExtendedFileSystem } from '../utils/fs/interfaces.js';
|
|
69
71
|
|
|
70
72
|
export async function extractDocument(
|
|
71
73
|
fileName: string,
|
|
@@ -87,11 +89,6 @@ export async function extractDocument(
|
|
|
87
89
|
|
|
88
90
|
if (!fileExists) {
|
|
89
91
|
const errorMsg = `File ${fileName} does not exist.`;
|
|
90
|
-
if (chalk) {
|
|
91
|
-
console.error(chalk.red(errorMsg));
|
|
92
|
-
} else {
|
|
93
|
-
console.error(errorMsg);
|
|
94
|
-
}
|
|
95
92
|
throw new Error(errorMsg);
|
|
96
93
|
}
|
|
97
94
|
} else if (!isNodeEnv && typeof fileName === 'string') {
|
|
@@ -100,7 +97,7 @@ export async function extractDocument(
|
|
|
100
97
|
const fileExists = await exists(fullFilePath);
|
|
101
98
|
|
|
102
99
|
if (!fileExists) {
|
|
103
|
-
|
|
100
|
+
throw new Error(`File ${fileName} does not exist.`);
|
|
104
101
|
}
|
|
105
102
|
} else {
|
|
106
103
|
throw new Error('Invalid input: expected file path (Node.js) or File object/content (browser)');
|
|
@@ -116,27 +113,11 @@ export async function extractDocument(
|
|
|
116
113
|
});
|
|
117
114
|
|
|
118
115
|
// Handle validation errors
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
if (validationErrors.length > 0) {
|
|
122
|
-
console.error(
|
|
123
|
-
isNodeEnv && chalk
|
|
124
|
-
? chalk.red('There are validation errors:')
|
|
125
|
-
: 'There are validation errors:'
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
for (const validationError of validationErrors) {
|
|
129
|
-
const errorMsg = `line ${validationError.range.start.line + 1}: ${
|
|
130
|
-
validationError.message
|
|
131
|
-
} [${document.textDocument.getText(validationError.range)}]`;
|
|
132
|
-
if (isNodeEnv && chalk) {
|
|
133
|
-
console.error(chalk.red(errorMsg));
|
|
134
|
-
} else {
|
|
135
|
-
console.error(errorMsg);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
116
|
+
const errs = maybeGetValidationErrors(document);
|
|
138
117
|
|
|
139
|
-
|
|
118
|
+
if (errs) {
|
|
119
|
+
const errorMsg = `${errs.join('\n')}`;
|
|
120
|
+
throw new Error(errorMsg);
|
|
140
121
|
}
|
|
141
122
|
|
|
142
123
|
return document;
|
|
@@ -156,6 +137,31 @@ export const DefaultAppSpec: ApplicationSpec = {
|
|
|
156
137
|
version: '0.0.1',
|
|
157
138
|
};
|
|
158
139
|
|
|
140
|
+
async function getAllModules(
|
|
141
|
+
dir: string,
|
|
142
|
+
fs: ExtendedFileSystem,
|
|
143
|
+
drill: boolean = true
|
|
144
|
+
): Promise<string[]> {
|
|
145
|
+
let alFiles = new Array<string>();
|
|
146
|
+
if (!(await fs.exists(dir))) {
|
|
147
|
+
return alFiles;
|
|
148
|
+
}
|
|
149
|
+
const directoryContents = await fs.readdir(dir);
|
|
150
|
+
for (let i = 0; i < directoryContents.length; ++i) {
|
|
151
|
+
const file = directoryContents[i];
|
|
152
|
+
if (path.extname(file).toLowerCase() == '.al') {
|
|
153
|
+
alFiles.push(dir + path.sep + file);
|
|
154
|
+
} else if (drill) {
|
|
155
|
+
const fullPath = dir + path.sep + file;
|
|
156
|
+
const stat = await fs.stat(fullPath);
|
|
157
|
+
if (stat.isDirectory()) {
|
|
158
|
+
alFiles = alFiles.concat(await getAllModules(fullPath, fs));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return alFiles;
|
|
163
|
+
}
|
|
164
|
+
|
|
159
165
|
async function loadApp(appDir: string, fsOptions?: any, callback?: Function): Promise<string> {
|
|
160
166
|
// Initialize filesystem if not already done
|
|
161
167
|
const fs = await getFileSystem(fsOptions);
|
|
@@ -163,19 +169,11 @@ async function loadApp(appDir: string, fsOptions?: any, callback?: Function): Pr
|
|
|
163
169
|
const appJsonFile = `${appDir}${path.sep}package.json`;
|
|
164
170
|
const s: string = await fs.readFile(appJsonFile);
|
|
165
171
|
const appSpec: ApplicationSpec = JSON.parse(s);
|
|
166
|
-
const alFiles: Array<string> = new Array<string>();
|
|
167
|
-
const directoryContents = await fs.readdir(appDir);
|
|
168
172
|
let lastModuleLoaded: string = '';
|
|
169
173
|
async function cont2() {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
174
|
-
directoryContents.forEach(file => {
|
|
175
|
-
if (path.extname(file).toLowerCase() == '.al') {
|
|
176
|
-
alFiles.push(appDir + path.sep + file);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
174
|
+
const fls01 = await getAllModules(appDir, fs, false);
|
|
175
|
+
const fls02 = await getAllModules(appDir + path.sep + 'src', fs);
|
|
176
|
+
const alFiles = fls01.concat(fls02);
|
|
179
177
|
for (let i = 0; i < alFiles.length; ++i) {
|
|
180
178
|
lastModuleLoaded = (await loadModule(alFiles[i], fsOptions)).name;
|
|
181
179
|
}
|
|
@@ -183,14 +181,21 @@ async function loadApp(appDir: string, fsOptions?: any, callback?: Function): Pr
|
|
|
183
181
|
}
|
|
184
182
|
if (appSpec.dependencies != undefined) {
|
|
185
183
|
for (const [depName, _] of Object.entries(appSpec.dependencies)) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
184
|
+
try {
|
|
185
|
+
const depDirName = `./node_modules/${depName}`;
|
|
186
|
+
const fls01 = await fs.readdir(depDirName);
|
|
187
|
+
const srcDir = depDirName + path.sep + 'src';
|
|
188
|
+
const hasSrc = await fs.exists(srcDir);
|
|
189
|
+
const files = hasSrc ? fls01.concat(await fs.readdir(srcDir)) : fls01;
|
|
190
|
+
if (
|
|
191
|
+
files.find(file => {
|
|
192
|
+
return path.extname(file).toLowerCase() == '.al';
|
|
193
|
+
})
|
|
194
|
+
) {
|
|
195
|
+
await loadApp(depDirName, fsOptions);
|
|
196
|
+
}
|
|
197
|
+
} catch (error) {
|
|
198
|
+
logger.error(`Error loading dependency ${depName}: ${error}`);
|
|
194
199
|
}
|
|
195
200
|
}
|
|
196
201
|
}
|
|
@@ -373,7 +378,7 @@ export function addRelationshipFromDef(
|
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
export function addWorkflowFromDef(def: WorkflowDefinition, moduleName: string): Workflow {
|
|
376
|
-
return addWorkflow(def.name, moduleName, def.statements);
|
|
381
|
+
return addWorkflow(def.name, moduleName, def.statements, def.hints);
|
|
377
382
|
}
|
|
378
383
|
|
|
379
384
|
const StandaloneStatements = new Map<string, Statement[]>();
|
|
@@ -506,7 +511,7 @@ function addResolverDefinition(def: ResolverDefinition, moduleName: string) {
|
|
|
506
511
|
resolver.subs = {
|
|
507
512
|
subscribe: subsFn,
|
|
508
513
|
};
|
|
509
|
-
if (subsEvent)
|
|
514
|
+
if (subsEvent) SetSubscription(subsEvent, resolverName);
|
|
510
515
|
resolver.subscribe();
|
|
511
516
|
}
|
|
512
517
|
});
|
|
@@ -554,7 +559,6 @@ export async function internModule(
|
|
|
554
559
|
const mn = module.name;
|
|
555
560
|
const r = addModule(mn);
|
|
556
561
|
module.imports.forEach(async (imp: Import) => {
|
|
557
|
-
validateImportName(imp.name);
|
|
558
562
|
await importModule(imp.path, imp.name, moduleFileName);
|
|
559
563
|
});
|
|
560
564
|
for (let i = 0; i < module.defs.length; ++i) {
|
|
@@ -586,11 +590,15 @@ export async function loadRawConfig(
|
|
|
586
590
|
fsOptions?: any
|
|
587
591
|
): Promise<any> {
|
|
588
592
|
const fs = await getFileSystem(fsOptions);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
593
|
+
if (await fs.exists(configFileName)) {
|
|
594
|
+
let rawConfig = preprocessRawConfig(JSON.parse(await fs.readFile(configFileName)));
|
|
595
|
+
if (validate) {
|
|
596
|
+
rawConfig = ConfigSchema.parse(rawConfig);
|
|
597
|
+
}
|
|
598
|
+
return rawConfig;
|
|
599
|
+
} else {
|
|
600
|
+
return { service: { port: 8080 } };
|
|
592
601
|
}
|
|
593
|
-
return rawConfig;
|
|
594
602
|
}
|
|
595
603
|
|
|
596
604
|
export function generateRawConfig(configObj: any): string {
|
package/src/runtime/module.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
RbacSpecEntry,
|
|
20
20
|
RbacSpecEntries,
|
|
21
21
|
RbacOpr,
|
|
22
|
+
WorkflowHint,
|
|
22
23
|
} from '../language/generated/ast.js';
|
|
23
24
|
import {
|
|
24
25
|
Path,
|
|
@@ -43,7 +44,12 @@ import {
|
|
|
43
44
|
} from './util.js';
|
|
44
45
|
import { parseStatement } from '../language/parser.js';
|
|
45
46
|
import { ActiveSessionInfo, AdminSession } from './auth/defs.js';
|
|
46
|
-
import {
|
|
47
|
+
import {
|
|
48
|
+
DefaultIdAttributeName,
|
|
49
|
+
FetchModuleFn,
|
|
50
|
+
PathAttributeName,
|
|
51
|
+
SetSubscription,
|
|
52
|
+
} from './defs.js';
|
|
47
53
|
import { logger } from './logger.js';
|
|
48
54
|
|
|
49
55
|
export class ModuleEntry {
|
|
@@ -1594,6 +1600,7 @@ export const propertyNames = new Set([
|
|
|
1594
1600
|
'@indexed',
|
|
1595
1601
|
'@default',
|
|
1596
1602
|
'@optional',
|
|
1603
|
+
'@check',
|
|
1597
1604
|
'@unique',
|
|
1598
1605
|
'@autoincrement',
|
|
1599
1606
|
'@array',
|
|
@@ -1856,7 +1863,8 @@ function normalizeWorkflowName(n: string): string {
|
|
|
1856
1863
|
export function addWorkflow(
|
|
1857
1864
|
name: string,
|
|
1858
1865
|
moduleName = activeModule,
|
|
1859
|
-
statements?: Statement[]
|
|
1866
|
+
statements?: Statement[],
|
|
1867
|
+
hints?: WorkflowHint[]
|
|
1860
1868
|
): Workflow {
|
|
1861
1869
|
const module: Module = fetchModule(moduleName);
|
|
1862
1870
|
if (module.hasEntry(name)) {
|
|
@@ -1869,6 +1877,13 @@ export function addWorkflow(
|
|
|
1869
1877
|
event.addMeta(SystemDefinedEvent, 'true');
|
|
1870
1878
|
}
|
|
1871
1879
|
if (!statements) statements = new Array<Statement>();
|
|
1880
|
+
if (hints && hints.length > 0) {
|
|
1881
|
+
hints.forEach((hint: WorkflowHint) => {
|
|
1882
|
+
if (hint.subs) {
|
|
1883
|
+
SetSubscription(makeFqName(moduleName, name), hint.subs.resolverName);
|
|
1884
|
+
}
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1872
1887
|
return module.addEntry(new Workflow(asWorkflowName(name), statements, moduleName)) as Workflow;
|
|
1873
1888
|
}
|
|
1874
1889
|
|
|
@@ -2103,13 +2118,22 @@ function checkOneOfValue(attrSpec: AttributeSpec, attrName: string, attrValue: a
|
|
|
2103
2118
|
return false;
|
|
2104
2119
|
}
|
|
2105
2120
|
|
|
2121
|
+
function getCheckPredicate(attrSpec: AttributeSpec): any {
|
|
2122
|
+
const p = getAnyProperty('check', attrSpec);
|
|
2123
|
+
if (isString(p)) {
|
|
2124
|
+
return FetchModuleFn(p);
|
|
2125
|
+
}
|
|
2126
|
+
return undefined;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2106
2129
|
function validateType(attrName: string, attrValue: any, attrSpec: AttributeSpec) {
|
|
2107
2130
|
if (attrSpec.type == 'Path') {
|
|
2108
2131
|
if (!isPath(attrValue, getRefSpec(attrSpec))) {
|
|
2109
2132
|
throw new Error(`Failed to validate Path ${attrValue} passed to ${attrName}`);
|
|
2110
2133
|
}
|
|
2111
2134
|
}
|
|
2112
|
-
|
|
2135
|
+
let predic = getCheckPredicate(attrSpec);
|
|
2136
|
+
predic = predic ? predic : builtInChecks.get(attrSpec.type);
|
|
2113
2137
|
if (predic != undefined) {
|
|
2114
2138
|
if (isArrayAttribute(attrSpec)) {
|
|
2115
2139
|
if (!(attrValue instanceof Array)) {
|
|
@@ -34,6 +34,7 @@ entity ${AgentEntityName} {
|
|
|
34
34
|
tools String @optional, // comma-separated list of tool names
|
|
35
35
|
documents String @optional, // comma-separated list of document names
|
|
36
36
|
channels String @optional, // comma-separated list of channel names
|
|
37
|
+
output String @optional, // fq-name of another agent to which the result will be pushed
|
|
37
38
|
llm String
|
|
38
39
|
}
|
|
39
40
|
|
|
@@ -72,6 +73,7 @@ export class AgentInstance {
|
|
|
72
73
|
documents: string | undefined;
|
|
73
74
|
channels: string | undefined;
|
|
74
75
|
runWorkflows: boolean = true;
|
|
76
|
+
output: string | undefined;
|
|
75
77
|
|
|
76
78
|
private constructor() {}
|
|
77
79
|
|
|
@@ -228,8 +230,12 @@ export async function findProviderForLLM(
|
|
|
228
230
|
const llm: Instance = result[0];
|
|
229
231
|
const service = llm.lookup('service');
|
|
230
232
|
const pclass = provider(service);
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
+
const configValue = llm.lookup('config');
|
|
234
|
+
const providerConfig: Map<string, any> = configValue
|
|
235
|
+
? configValue instanceof Map
|
|
236
|
+
? configValue
|
|
237
|
+
: new Map(Object.entries(configValue))
|
|
238
|
+
: new Map().set('service', service);
|
|
233
239
|
p = new pclass(providerConfig);
|
|
234
240
|
if (p) ProviderDb.set(llmName, p);
|
|
235
241
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { parseAndIntern } from './loader.js';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
import { Instance } from './module.js';
|
|
4
|
+
import { isReservedName } from './util.js';
|
|
5
|
+
import { OpenAPIClient, OpenAPIClientAxios } from 'openapi-client-axios';
|
|
6
|
+
|
|
7
|
+
export type OpenApiHandle = {
|
|
8
|
+
api: OpenAPIClientAxios;
|
|
9
|
+
client: OpenAPIClient;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
let OpenApiModules: Map<string, OpenApiHandle> | undefined = undefined;
|
|
13
|
+
|
|
14
|
+
export async function registerOpenApiModule(
|
|
15
|
+
moduleName: string,
|
|
16
|
+
handle: OpenApiHandle
|
|
17
|
+
): Promise<string> {
|
|
18
|
+
if (OpenApiModules == undefined) {
|
|
19
|
+
OpenApiModules = new Map();
|
|
20
|
+
}
|
|
21
|
+
const m = new Map(Object.entries(handle.client));
|
|
22
|
+
const events = new Array<string>();
|
|
23
|
+
m.forEach((v: any, k: string) => {
|
|
24
|
+
if (v instanceof Function) {
|
|
25
|
+
if (isReservedName(k)) {
|
|
26
|
+
k = `_${k}`;
|
|
27
|
+
}
|
|
28
|
+
logger.debug(`OpenAPI event: ${moduleName}/${k}`);
|
|
29
|
+
events.push(
|
|
30
|
+
`event ${k} {parameters Any @optional, data Any @optional, config Any @optional}`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
await parseAndIntern(`module ${moduleName}\n${events.join('\n')}`);
|
|
35
|
+
OpenApiModules.set(moduleName, handle);
|
|
36
|
+
return moduleName;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function isOpenApiModule(moduleName: string): boolean {
|
|
40
|
+
return OpenApiModules != undefined && OpenApiModules.has(moduleName);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type OpenApiArgs = {
|
|
44
|
+
parameters?: any;
|
|
45
|
+
data?: any;
|
|
46
|
+
config?: any;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export async function invokeOpenApiEvent(
|
|
50
|
+
moduleName: string,
|
|
51
|
+
eventName: string,
|
|
52
|
+
params: OpenApiArgs
|
|
53
|
+
): Promise<any> {
|
|
54
|
+
if (OpenApiModules) {
|
|
55
|
+
const handle = OpenApiModules.get(moduleName);
|
|
56
|
+
if (handle) {
|
|
57
|
+
const f = handle.client[eventName];
|
|
58
|
+
if (!f) {
|
|
59
|
+
throw new Error(`No event ${eventName} found in ${moduleName}`);
|
|
60
|
+
} else {
|
|
61
|
+
const r: any = await f(params.parameters, params.data, params.config);
|
|
62
|
+
return r.data;
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
throw new Error(`No OpenAPI module found - ${moduleName}`);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
throw new Error(`OpenAPI module ${moduleName} not initialized`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function isOpenApiEventInstance(eventInst: Instance): boolean {
|
|
73
|
+
return isOpenApiModule(eventInst.moduleName);
|
|
74
|
+
}
|
|
@@ -193,15 +193,20 @@ export class Resolver {
|
|
|
193
193
|
|
|
194
194
|
public async onSubscription(result: any): Promise<any> {
|
|
195
195
|
if (result != undefined) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
196
|
+
try {
|
|
197
|
+
const eventName = getSubscriptionEvent(this.name);
|
|
198
|
+
if (eventName) {
|
|
199
|
+
const path = splitFqName(eventName);
|
|
200
|
+
const inst = makeInstance(
|
|
201
|
+
path.getModuleName(),
|
|
202
|
+
path.getEntryName(),
|
|
203
|
+
newInstanceAttributes().set('data', result)
|
|
204
|
+
);
|
|
205
|
+
return await evaluate(inst);
|
|
206
|
+
}
|
|
207
|
+
} catch (err: any) {
|
|
208
|
+
logger.error(`Resolver ${this.name} raised error in onSubscription handler: ${err}`);
|
|
209
|
+
return undefined;
|
|
205
210
|
}
|
|
206
211
|
}
|
|
207
212
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { setSubscriptionFn } from '../defs.js';
|
|
1
2
|
import { Resolver, setSubscriptionEvent } from './interface.js';
|
|
2
3
|
|
|
3
4
|
type MakeResolver = () => Resolver;
|
|
@@ -17,8 +18,6 @@ export function setResolver(fqEntryName: string, resolverName: string) {
|
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
export const setSubscription = setSubscriptionEvent;
|
|
21
|
-
|
|
22
21
|
export function getResolverNameForPath(fqEntryName: string): string | undefined {
|
|
23
22
|
return resolverPathMappings.get(fqEntryName);
|
|
24
23
|
}
|
|
@@ -31,3 +30,5 @@ export function getResolver(fqEntryName: string): Resolver {
|
|
|
31
30
|
}
|
|
32
31
|
throw new Error(`No resolver registered for ${fqEntryName}`);
|
|
33
32
|
}
|
|
33
|
+
|
|
34
|
+
setSubscriptionFn(setSubscriptionEvent);
|
package/src/runtime/state.ts
CHANGED
|
@@ -93,6 +93,15 @@ export const ConfigSchema = z.object({
|
|
|
93
93
|
}),
|
|
94
94
|
])
|
|
95
95
|
.optional(),
|
|
96
|
+
openapi: z
|
|
97
|
+
.array(
|
|
98
|
+
z.object({
|
|
99
|
+
specUrl: z.string(),
|
|
100
|
+
baseUrl: z.string().optional(),
|
|
101
|
+
name: z.string(),
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
.optional(),
|
|
96
105
|
});
|
|
97
106
|
|
|
98
107
|
export type Config = z.infer<typeof ConfigSchema>;
|
package/src/runtime/util.ts
CHANGED
|
@@ -472,3 +472,25 @@ export function areSetsEqual<T>(set1: Set<T>, set2: Set<T>): boolean {
|
|
|
472
472
|
}
|
|
473
473
|
return true;
|
|
474
474
|
}
|
|
475
|
+
|
|
476
|
+
const ReservedNames = new Set([
|
|
477
|
+
'if',
|
|
478
|
+
'else',
|
|
479
|
+
'for',
|
|
480
|
+
'or',
|
|
481
|
+
'and',
|
|
482
|
+
'entity',
|
|
483
|
+
'record',
|
|
484
|
+
'event',
|
|
485
|
+
'workflow',
|
|
486
|
+
'create',
|
|
487
|
+
'delete',
|
|
488
|
+
'update',
|
|
489
|
+
'upsert',
|
|
490
|
+
'agent',
|
|
491
|
+
'resolver',
|
|
492
|
+
]);
|
|
493
|
+
|
|
494
|
+
export function isReservedName(s: string): boolean {
|
|
495
|
+
return ReservedNames.has(s);
|
|
496
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Monarch syntax highlighting for the agentlang language.
|
|
2
2
|
export default {
|
|
3
3
|
keywords: [
|
|
4
|
-
'@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
|
|
4
|
+
'@actions','@after','@as','@async','@before','@catch','@distinct','@enum','@expr','@from','@into','@meta','@oneof','@rbac','@ref','@subs','@then','@upsert','@with_unique','agent','allow','and','await','between','contains','create','delete','else','entity','error','event','extends','false','for','if','import','in','like','module','not','not_found','onSubscription','or','purge','query','read','record','relationship','resolver','return','roles','subscribe','true','update','upsert','where','workflow'
|
|
5
5
|
],
|
|
6
6
|
operators: [
|
|
7
7
|
'!=','*','+',',','-','.','/',':',';','<','<=','<>','=','>','>=','?','@'
|
package/out/cli/docs.d.ts
DELETED
package/out/cli/docs.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/cli/docs.ts"],"names":[],"mappings":"AA8OA,eAAO,MAAM,kBAAkB,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,IAAI,CAcvE,CAAC"}
|