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/language/parser.ts
CHANGED
|
@@ -103,16 +103,37 @@ export async function parseWorkflow(workflowDef: string): Promise<WorkflowDefini
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
export function maybeGetValidationErrors(document: LangiumDocument): string[] | undefined {
|
|
107
|
+
const validationErrors = (document.diagnostics ?? []).filter(e => e.severity === 1);
|
|
108
|
+
|
|
109
|
+
const sls = new Set<number>();
|
|
110
|
+
const scs = new Set<number>();
|
|
111
|
+
if (validationErrors.length > 0) {
|
|
112
|
+
const lineErrs = new Array<string>();
|
|
113
|
+
for (const validationError of validationErrors) {
|
|
114
|
+
if (
|
|
115
|
+
!sls.has(validationError.range.start.line) &&
|
|
116
|
+
!scs.has(validationError.range.start.character)
|
|
117
|
+
) {
|
|
118
|
+
const s = document.textDocument.getText(validationError.range);
|
|
119
|
+
lineErrs.push(
|
|
120
|
+
`Error on line ${validationError.range.start.line + 1}, column ${validationError.range.start.character + 1}, unexpected token(s) '${s}'`
|
|
121
|
+
);
|
|
122
|
+
sls.add(validationError.range.start.line);
|
|
123
|
+
scs.add(validationError.range.start.character);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return lineErrs;
|
|
128
|
+
} else {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
106
133
|
function maybeRaiseParserErrors(document: LangiumDocument) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
errs.push(v.message);
|
|
111
|
-
});
|
|
112
|
-
document.parseResult.parserErrors.forEach((v: any) => {
|
|
113
|
-
errs.push(v.message);
|
|
114
|
-
});
|
|
115
|
-
throw new Error(`There were parser errors: \n ${errs.join('\n')}`);
|
|
134
|
+
const errs = maybeGetValidationErrors(document);
|
|
135
|
+
if (errs) {
|
|
136
|
+
throw new Error(errs.join('\n'));
|
|
116
137
|
}
|
|
117
138
|
}
|
|
118
139
|
|
|
@@ -145,9 +145,12 @@ are invalid, because the alias 'employee' is not defined:
|
|
|
145
145
|
|
|
146
146
|
A fix for the reference-error is shown below:
|
|
147
147
|
|
|
148
|
-
{Employee {id? 101}} @as employee;
|
|
148
|
+
{Employee {id? 101}} @as [employee];
|
|
149
149
|
{SendEmail {to employee.email, body "hello"}}
|
|
150
150
|
|
|
151
|
+
Note that the alias for the query is '[employee]' so that the resultset is destructured to select exactly one instance of Employee
|
|
152
|
+
selected into the reference. You must follow this pattern if your goal is to select exactly a single instance.
|
|
153
|
+
|
|
151
154
|
Keep in mind that the only valid syntax for the 'if' condition is:
|
|
152
155
|
|
|
153
156
|
if (<expr>) {
|
|
@@ -12,8 +12,64 @@ export interface AnthropicConfig {
|
|
|
12
12
|
defaultHeaders?: Record<string, string>;
|
|
13
13
|
[key: string]: any;
|
|
14
14
|
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Enable prompt caching to reuse context across API calls.
|
|
18
|
+
* This reduces latency and costs by caching static portions of prompts.
|
|
19
|
+
* Cache has a 5-minute lifetime by default, refreshed on each use.
|
|
20
|
+
* Minimum cacheable length: 1024 tokens for Claude 3.5+, 2048 for Haiku.
|
|
21
|
+
* Beta header: prompt-caching-2024-07-31
|
|
22
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching
|
|
23
|
+
*/
|
|
15
24
|
enablePromptCaching?: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Cache control type for prompt caching.
|
|
28
|
+
* Currently only 'ephemeral' is supported with 5-minute TTL.
|
|
29
|
+
* Can be extended to 1-hour with extended-cache-ttl-2025-04-11 beta.
|
|
30
|
+
*/
|
|
16
31
|
cacheControl?: 'ephemeral';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Enable extended thinking mode for Claude to show its reasoning process.
|
|
35
|
+
* When enabled, responses include thinking blocks showing Claude's thought process.
|
|
36
|
+
* Requires minimum budgetTokens of 1024 and counts towards maxTokens.
|
|
37
|
+
* Useful for complex reasoning, problem-solving, and transparency.
|
|
38
|
+
* @see https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking
|
|
39
|
+
*/
|
|
40
|
+
enableThinking?: boolean;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Token budget for thinking mode (minimum 1024).
|
|
44
|
+
* Determines how many tokens Claude can use for internal reasoning.
|
|
45
|
+
* Larger budgets enable more thorough analysis for complex problems.
|
|
46
|
+
* Must be less than maxTokens.
|
|
47
|
+
*/
|
|
48
|
+
budgetTokens?: number;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Enable extended output to generate up to 128,000 tokens in a single response.
|
|
52
|
+
* Useful for long-form content, detailed reports, extensive code generation.
|
|
53
|
+
* Beta header: output-128k-2025-02-19
|
|
54
|
+
* Note: Use streaming to avoid timeouts with long outputs.
|
|
55
|
+
*/
|
|
56
|
+
enableExtendedOutput?: boolean;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Enable interleaved thinking to see Claude's reasoning in real-time during streaming.
|
|
60
|
+
* When combined with extended thinking, thinking blocks are streamed alongside content.
|
|
61
|
+
* Provides transparency into Claude's problem-solving process as it happens.
|
|
62
|
+
* Beta header: interleaved-thinking-2025-05-14
|
|
63
|
+
*/
|
|
64
|
+
enableInterleavedThinking?: boolean;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Enable fine-grained tool streaming for more responsive tool use.
|
|
68
|
+
* Streams partial JSON updates and character-by-character tool parameters.
|
|
69
|
+
* Improves UI responsiveness when Claude invokes tools.
|
|
70
|
+
* Beta header: fine-grained-tool-streaming-2025-05-14
|
|
71
|
+
*/
|
|
72
|
+
enableFineGrainedToolStreaming?: boolean;
|
|
17
73
|
}
|
|
18
74
|
|
|
19
75
|
export class AnthropicProvider implements AgentServiceProvider {
|
|
@@ -38,16 +94,58 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
38
94
|
chatConfig.clientOptions = this.config.clientOptions;
|
|
39
95
|
}
|
|
40
96
|
|
|
97
|
+
// Configure beta headers based on enabled features
|
|
98
|
+
const betaFeatures: string[] = [];
|
|
99
|
+
|
|
100
|
+
// Prompt caching: Reuse static content across API calls
|
|
101
|
+
// Reduces costs by 90% for cached content, improves latency
|
|
41
102
|
if (this.config.enablePromptCaching) {
|
|
103
|
+
betaFeatures.push('prompt-caching-2024-07-31');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Extended output: Generate up to 128k tokens (vs standard 8k)
|
|
107
|
+
// Essential for long-form content generation
|
|
108
|
+
if (this.config.enableExtendedOutput) {
|
|
109
|
+
betaFeatures.push('output-128k-2025-02-19');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Interleaved thinking: Stream thinking blocks alongside regular content
|
|
113
|
+
// Shows Claude's reasoning process in real-time during streaming
|
|
114
|
+
if (this.config.enableInterleavedThinking) {
|
|
115
|
+
betaFeatures.push('interleaved-thinking-2025-05-14');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Fine-grained tool streaming: Stream partial tool parameters
|
|
119
|
+
// Provides character-by-character updates for better UX
|
|
120
|
+
if (this.config.enableFineGrainedToolStreaming) {
|
|
121
|
+
betaFeatures.push('fine-grained-tool-streaming-2025-05-14');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (betaFeatures.length > 0) {
|
|
42
125
|
chatConfig.clientOptions = {
|
|
43
126
|
...chatConfig.clientOptions,
|
|
44
127
|
defaultHeaders: {
|
|
45
128
|
...chatConfig.clientOptions?.defaultHeaders,
|
|
46
|
-
'anthropic-beta': '
|
|
129
|
+
'anthropic-beta': betaFeatures.join(','),
|
|
47
130
|
},
|
|
48
131
|
};
|
|
49
132
|
}
|
|
50
133
|
|
|
134
|
+
// Validate thinking configuration if enabled
|
|
135
|
+
// Thinking mode requires careful token budget management
|
|
136
|
+
if (this.config.enableThinking) {
|
|
137
|
+
// Validate budget tokens (minimum 1024 required by API)
|
|
138
|
+
const budgetTokens = Math.max(1024, this.config.budgetTokens || 1024);
|
|
139
|
+
|
|
140
|
+
// Ensure budget tokens don't exceed max tokens
|
|
141
|
+
// This prevents API errors and ensures proper token allocation
|
|
142
|
+
if (budgetTokens >= (this.config.maxTokens || 8192)) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`budgetTokens (${budgetTokens}) must be less than maxTokens (${this.config.maxTokens || 8192})`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
51
149
|
this.model = new ChatAnthropic(chatConfig);
|
|
52
150
|
}
|
|
53
151
|
|
|
@@ -59,6 +157,11 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
59
157
|
maxRetries: 2,
|
|
60
158
|
enablePromptCaching: false,
|
|
61
159
|
cacheControl: 'ephemeral',
|
|
160
|
+
enableThinking: false,
|
|
161
|
+
budgetTokens: 1024, // Minimum budget tokens for thinking mode
|
|
162
|
+
enableExtendedOutput: false,
|
|
163
|
+
enableInterleavedThinking: false,
|
|
164
|
+
enableFineGrainedToolStreaming: false,
|
|
62
165
|
};
|
|
63
166
|
|
|
64
167
|
if (!config) {
|
|
@@ -81,6 +184,31 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
81
184
|
defaultConfig.enablePromptCaching,
|
|
82
185
|
cacheControl:
|
|
83
186
|
config.get('cacheControl') || config.get('cache_control') || defaultConfig.cacheControl,
|
|
187
|
+
enableThinking:
|
|
188
|
+
config.get('enableThinking') ||
|
|
189
|
+
config.get('enable_thinking') ||
|
|
190
|
+
config.get('thinking') ||
|
|
191
|
+
defaultConfig.enableThinking,
|
|
192
|
+
budgetTokens:
|
|
193
|
+
config.get('budgetTokens') ||
|
|
194
|
+
config.get('budget_tokens') ||
|
|
195
|
+
config.get('thinking_budget') ||
|
|
196
|
+
defaultConfig.budgetTokens,
|
|
197
|
+
enableExtendedOutput:
|
|
198
|
+
config.get('enableExtendedOutput') ||
|
|
199
|
+
config.get('enable_extended_output') ||
|
|
200
|
+
config.get('extendedOutput') ||
|
|
201
|
+
defaultConfig.enableExtendedOutput,
|
|
202
|
+
enableInterleavedThinking:
|
|
203
|
+
config.get('enableInterleavedThinking') ||
|
|
204
|
+
config.get('enable_interleaved_thinking') ||
|
|
205
|
+
config.get('interleavedThinking') ||
|
|
206
|
+
defaultConfig.enableInterleavedThinking,
|
|
207
|
+
enableFineGrainedToolStreaming:
|
|
208
|
+
config.get('enableFineGrainedToolStreaming') ||
|
|
209
|
+
config.get('enable_fine_grained_tool_streaming') ||
|
|
210
|
+
config.get('fineGrainedToolStreaming') ||
|
|
211
|
+
defaultConfig.enableFineGrainedToolStreaming,
|
|
84
212
|
apiKey,
|
|
85
213
|
clientOptions: config.get('clientOptions') || config.get('client_options'),
|
|
86
214
|
};
|
|
@@ -99,9 +227,25 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
99
227
|
processedMessages = this.applyCacheControl(messages);
|
|
100
228
|
}
|
|
101
229
|
|
|
102
|
-
|
|
230
|
+
// Add thinking configuration to the invoke options if enabled
|
|
231
|
+
// Thinking mode is passed as a parameter during invocation, not in constructor
|
|
232
|
+
const invokeOptions: any = {};
|
|
233
|
+
if (this.config.enableThinking) {
|
|
234
|
+
const budgetTokens = Math.max(1024, this.config.budgetTokens || 1024);
|
|
235
|
+
invokeOptions.thinking = {
|
|
236
|
+
type: 'enabled',
|
|
237
|
+
budget_tokens: budgetTokens,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return asAIResponse(await this.model.invoke(processedMessages, invokeOptions));
|
|
103
242
|
}
|
|
104
243
|
|
|
244
|
+
/**
|
|
245
|
+
* Apply cache control to messages for prompt caching optimization.
|
|
246
|
+
* Caches system messages with substantial content (>1000 chars) to reduce costs.
|
|
247
|
+
* Cache hits cost 90% less than regular input tokens.
|
|
248
|
+
*/
|
|
105
249
|
private applyCacheControl(messages: BaseMessage[]): BaseMessage[] {
|
|
106
250
|
// Apply cache control to the last system message if present
|
|
107
251
|
// This follows Anthropic's recommendation to cache long context at the end of system messages
|
|
@@ -112,7 +256,7 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
112
256
|
// Find the last system message and apply cache control
|
|
113
257
|
for (let i = processedMessages.length - 1; i >= 0; i--) {
|
|
114
258
|
const message = processedMessages[i];
|
|
115
|
-
if (message._getType() === 'system') {
|
|
259
|
+
if ((message as any)._getType() === 'system') {
|
|
116
260
|
// Apply cache control to system message content
|
|
117
261
|
const content = message.content;
|
|
118
262
|
if (typeof content === 'string' && content.length > 1000) {
|
|
@@ -151,16 +295,58 @@ export class AnthropicProvider implements AgentServiceProvider {
|
|
|
151
295
|
chatConfig.clientOptions = this.config.clientOptions;
|
|
152
296
|
}
|
|
153
297
|
|
|
298
|
+
// Configure beta headers based on enabled features
|
|
299
|
+
const betaFeatures: string[] = [];
|
|
300
|
+
|
|
301
|
+
// Prompt caching: Reuse static content across API calls
|
|
302
|
+
// Reduces costs by 90% for cached content, improves latency
|
|
154
303
|
if (this.config.enablePromptCaching) {
|
|
304
|
+
betaFeatures.push('prompt-caching-2024-07-31');
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Extended output: Generate up to 128k tokens (vs standard 8k)
|
|
308
|
+
// Essential for long-form content generation
|
|
309
|
+
if (this.config.enableExtendedOutput) {
|
|
310
|
+
betaFeatures.push('output-128k-2025-02-19');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Interleaved thinking: Stream thinking blocks alongside regular content
|
|
314
|
+
// Shows Claude's reasoning process in real-time during streaming
|
|
315
|
+
if (this.config.enableInterleavedThinking) {
|
|
316
|
+
betaFeatures.push('interleaved-thinking-2025-05-14');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Fine-grained tool streaming: Stream partial tool parameters
|
|
320
|
+
// Provides character-by-character updates for better UX
|
|
321
|
+
if (this.config.enableFineGrainedToolStreaming) {
|
|
322
|
+
betaFeatures.push('fine-grained-tool-streaming-2025-05-14');
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (betaFeatures.length > 0) {
|
|
155
326
|
chatConfig.clientOptions = {
|
|
156
327
|
...chatConfig.clientOptions,
|
|
157
328
|
defaultHeaders: {
|
|
158
329
|
...chatConfig.clientOptions?.defaultHeaders,
|
|
159
|
-
'anthropic-beta': '
|
|
330
|
+
'anthropic-beta': betaFeatures.join(','),
|
|
160
331
|
},
|
|
161
332
|
};
|
|
162
333
|
}
|
|
163
334
|
|
|
335
|
+
// Validate thinking configuration if enabled
|
|
336
|
+
// Thinking mode requires careful token budget management
|
|
337
|
+
if (this.config.enableThinking) {
|
|
338
|
+
// Validate budget tokens (minimum 1024 required by API)
|
|
339
|
+
const budgetTokens = Math.max(1024, this.config.budgetTokens || 1024);
|
|
340
|
+
|
|
341
|
+
// Ensure budget tokens don't exceed max tokens
|
|
342
|
+
// This prevents API errors and ensures proper token allocation
|
|
343
|
+
if (budgetTokens >= (this.config.maxTokens || 8192)) {
|
|
344
|
+
throw new Error(
|
|
345
|
+
`budgetTokens (${budgetTokens}) must be less than maxTokens (${this.config.maxTokens || 8192})`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
164
350
|
this.model = new ChatAnthropic(chatConfig);
|
|
165
351
|
}
|
|
166
352
|
}
|
|
@@ -400,7 +400,7 @@ export class CognitoAuth implements AgentlangAuth {
|
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
-
async confirmSignup(username: string, confirmationCode: string,
|
|
403
|
+
async confirmSignup(username: string, confirmationCode: string, _: Environment): Promise<void> {
|
|
404
404
|
try {
|
|
405
405
|
const client = new CognitoIdentityProviderClient({
|
|
406
406
|
region: process.env.AWS_REGION || 'us-west-2',
|
package/src/runtime/defs.ts
CHANGED
|
@@ -76,3 +76,15 @@ export class CodeMismatchError extends Error {
|
|
|
76
76
|
super(message || 'The verification code is incorrect. Please try again.', options);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
|
|
80
|
+
export let FetchModuleFn: any = undefined;
|
|
81
|
+
|
|
82
|
+
export function setModuleFnFetcher(f: Function) {
|
|
83
|
+
FetchModuleFn = f;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export let SetSubscription: any = undefined;
|
|
87
|
+
|
|
88
|
+
export function setSubscriptionFn(f: Function) {
|
|
89
|
+
SetSubscription = f;
|
|
90
|
+
}
|
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
DefaultModuleName,
|
|
55
55
|
escapeFqName,
|
|
56
56
|
escapeQueryName,
|
|
57
|
+
escapeSpecialChars,
|
|
57
58
|
fqNameFromPath,
|
|
58
59
|
isFqName,
|
|
59
60
|
isPath,
|
|
@@ -80,6 +81,7 @@ import {
|
|
|
80
81
|
setTimerRunning,
|
|
81
82
|
} from './modules/core.js';
|
|
82
83
|
import { invokeModuleFn } from './jsmodules.js';
|
|
84
|
+
import { invokeOpenApiEvent, isOpenApiEventInstance } from './openapi.js';
|
|
83
85
|
|
|
84
86
|
export type Result = any;
|
|
85
87
|
|
|
@@ -545,6 +547,15 @@ export async function evaluate(
|
|
|
545
547
|
}
|
|
546
548
|
await evaluateStatements(wf.statements, env, continuation);
|
|
547
549
|
return env.getLastResult();
|
|
550
|
+
} else if (isOpenApiEventInstance(eventInstance)) {
|
|
551
|
+
env = new Environment(eventInstance.name + '.env', activeEnv);
|
|
552
|
+
await handleOpenApiEvent(eventInstance, env);
|
|
553
|
+
const r = env.getLastResult();
|
|
554
|
+
if (continuation) continuation(r);
|
|
555
|
+
return r;
|
|
556
|
+
} else {
|
|
557
|
+
if (continuation) continuation(null);
|
|
558
|
+
return null;
|
|
548
559
|
}
|
|
549
560
|
} else {
|
|
550
561
|
throw new Error('Not an event - ' + eventInstance.name);
|
|
@@ -1180,6 +1191,7 @@ async function evaluateCrudMap(crud: CrudMap, env: Environment): Promise<void> {
|
|
|
1180
1191
|
}
|
|
1181
1192
|
} else if (isEventInstance(inst)) {
|
|
1182
1193
|
if (isAgentEventInstance(inst)) await handleAgentInvocation(inst, env);
|
|
1194
|
+
else if (isOpenApiEventInstance(inst)) await handleOpenApiEvent(inst, env);
|
|
1183
1195
|
else await evaluate(inst, (result: Result) => env.setLastResult(result), env);
|
|
1184
1196
|
} else {
|
|
1185
1197
|
env.setLastResult(inst);
|
|
@@ -1299,46 +1311,88 @@ async function walkJoinQueryPattern(
|
|
|
1299
1311
|
}
|
|
1300
1312
|
}
|
|
1301
1313
|
|
|
1314
|
+
const MAX_PLANNER_RETRIES = 3;
|
|
1315
|
+
|
|
1302
1316
|
async function handleAgentInvocation(agentEventInst: Instance, env: Environment): Promise<void> {
|
|
1303
1317
|
const agent: AgentInstance = await findAgentByName(agentEventInst.name, env);
|
|
1304
1318
|
await agent.invoke(agentEventInst.lookup('message'), env);
|
|
1305
1319
|
const r: string | undefined = env.getLastResult();
|
|
1306
1320
|
const isPlanner = agent.isPlanner();
|
|
1307
|
-
|
|
1321
|
+
let result: string | undefined = isPlanner ? cleanupAgentResponse(r) : r;
|
|
1308
1322
|
if (result) {
|
|
1309
1323
|
if (isPlanner) {
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
isWf
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1324
|
+
let retries = 0;
|
|
1325
|
+
while (true) {
|
|
1326
|
+
logger.debug(`Agent ${agent.name} generated pattern: ${result}`);
|
|
1327
|
+
try {
|
|
1328
|
+
let rs: string = result ? result.trim() : '';
|
|
1329
|
+
let isWf = rs.startsWith('workflow');
|
|
1330
|
+
if (isWf && !agent.runWorkflows) {
|
|
1331
|
+
await parseWorkflow(rs);
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
const isGrp = rs.startsWith('[');
|
|
1335
|
+
if (!isWf && !isGrp && rs.indexOf(';') > 0) {
|
|
1336
|
+
rs = `workflow T {${rs}}`;
|
|
1337
|
+
isWf = true;
|
|
1338
|
+
} else if (!isWf && isGrp) {
|
|
1339
|
+
const stmts = rs.substring(1, rs.length - 1);
|
|
1340
|
+
rs = `workflow T {${stmts}}`;
|
|
1341
|
+
isWf = true;
|
|
1342
|
+
}
|
|
1343
|
+
if (isWf) {
|
|
1344
|
+
const wf = await parseWorkflow(rs);
|
|
1326
1345
|
await evaluateStatements(wf.statements, env);
|
|
1346
|
+
} else {
|
|
1347
|
+
env.setLastResult(await parseAndEvaluateStatement(rs, undefined, env));
|
|
1348
|
+
}
|
|
1349
|
+
break;
|
|
1350
|
+
} catch (err: any) {
|
|
1351
|
+
if (retries < MAX_PLANNER_RETRIES) {
|
|
1352
|
+
await agent.invoke(`Please fix these errors:\n ${err}`, env);
|
|
1353
|
+
const r: string | undefined = env.getLastResult();
|
|
1354
|
+
result = cleanupAgentResponse(r);
|
|
1355
|
+
++retries;
|
|
1356
|
+
} else {
|
|
1357
|
+
logger.error(
|
|
1358
|
+
`Failed to evaluate pattern generated by agent ${agent.name} - ${result}, ${err}`
|
|
1359
|
+
);
|
|
1360
|
+
break;
|
|
1327
1361
|
}
|
|
1328
|
-
} else {
|
|
1329
|
-
env.setLastResult(await parseAndEvaluateStatement(rs, undefined, env));
|
|
1330
1362
|
}
|
|
1331
|
-
} catch (err: any) {
|
|
1332
|
-
logger.error(
|
|
1333
|
-
`Failed to evaluate pattern generated by agent ${agent.name} - ${result}, ${err}`
|
|
1334
|
-
);
|
|
1335
1363
|
}
|
|
1336
1364
|
}
|
|
1365
|
+
if (agent.output) {
|
|
1366
|
+
await pushToAgent(agent.output, env.getLastResult(), env);
|
|
1367
|
+
}
|
|
1337
1368
|
} else {
|
|
1338
1369
|
logger.warn(`Agent ${agent.name} failed to generate a response`);
|
|
1339
1370
|
}
|
|
1340
1371
|
}
|
|
1341
1372
|
|
|
1373
|
+
function agentInputAsString(result: any): string {
|
|
1374
|
+
if (!isString(result)) {
|
|
1375
|
+
if (result instanceof Instance) {
|
|
1376
|
+
return JSON.stringify((result as Instance).asObject());
|
|
1377
|
+
} else if (result instanceof Array) {
|
|
1378
|
+
return `[${(result as Array<any>)
|
|
1379
|
+
.map((r: any) => {
|
|
1380
|
+
return agentInputAsString(r);
|
|
1381
|
+
})
|
|
1382
|
+
.join(',')}]`;
|
|
1383
|
+
} else {
|
|
1384
|
+
return JSON.stringify(result);
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
return result;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
async function pushToAgent(agentName: string, result: any, env: Environment) {
|
|
1391
|
+
const r = escapeSpecialChars(agentInputAsString(result));
|
|
1392
|
+
const pat = `{${agentName} {message "\n${r}"}}`;
|
|
1393
|
+
env.setLastResult(await parseAndEvaluateStatement(pat, undefined, env));
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1342
1396
|
function cleanupAgentResponse(response: string | undefined): string | undefined {
|
|
1343
1397
|
if (response) {
|
|
1344
1398
|
const resp = response.trim();
|
|
@@ -1371,6 +1425,15 @@ function cleanupAgentResponse(response: string | undefined): string | undefined
|
|
|
1371
1425
|
}
|
|
1372
1426
|
}
|
|
1373
1427
|
|
|
1428
|
+
async function handleOpenApiEvent(eventInst: Instance, env: Environment): Promise<void> {
|
|
1429
|
+
const r = await invokeOpenApiEvent(
|
|
1430
|
+
eventInst.moduleName,
|
|
1431
|
+
eventInst.name,
|
|
1432
|
+
eventInst.attributesAsObject()
|
|
1433
|
+
);
|
|
1434
|
+
env.setLastResult(r);
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1374
1437
|
async function evaluateUpsert(crud: CrudMap, env: Environment): Promise<void> {
|
|
1375
1438
|
env.setInUpsertMode(true);
|
|
1376
1439
|
try {
|
|
@@ -1634,7 +1697,7 @@ async function runPrePostEvents(
|
|
|
1634
1697
|
if (env.hasHandlers()) {
|
|
1635
1698
|
throw reason;
|
|
1636
1699
|
} else {
|
|
1637
|
-
|
|
1700
|
+
throw new Error(`${prefix}: ${reason}`);
|
|
1638
1701
|
}
|
|
1639
1702
|
};
|
|
1640
1703
|
if (trigInfo.async) {
|
package/src/runtime/jsmodules.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { logger } from './logger.js';
|
|
2
|
-
import { setSubscription } from './resolvers/registry.js';
|
|
3
2
|
import { now, splitRefs } from './util.js';
|
|
4
3
|
import { isNodeEnv } from '../utils/runtime.js';
|
|
4
|
+
import { setModuleFnFetcher } from './defs.js';
|
|
5
5
|
|
|
6
6
|
let dirname: any = undefined;
|
|
7
7
|
let sep: any = undefined;
|
|
@@ -26,39 +26,37 @@ const importedModules = new Map<string, any>();
|
|
|
26
26
|
|
|
27
27
|
// Usage: importModule("./mymodels/acme.js")
|
|
28
28
|
export async function importModule(path: string, name: string, moduleFileName?: string) {
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (moduleFileName) {
|
|
33
|
-
let s: string = dirname(moduleFileName);
|
|
34
|
-
if (s.startsWith('./')) {
|
|
35
|
-
s = s.substring(2);
|
|
29
|
+
if (isNodeEnv) {
|
|
30
|
+
if (importedModules.has(name)) {
|
|
31
|
+
logger.warn(`Alias '${name}' will overwrite a previously imported module`);
|
|
36
32
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
if (moduleFileName) {
|
|
34
|
+
let s: string = dirname(moduleFileName);
|
|
35
|
+
if (s.startsWith('./')) {
|
|
36
|
+
s = s.substring(2);
|
|
37
|
+
} else if (s == '.') {
|
|
38
|
+
s = process.cwd();
|
|
39
|
+
}
|
|
40
|
+
path = `${s}${sep}${path}`;
|
|
41
|
+
}
|
|
42
|
+
if (!(path.startsWith(sep) || path.startsWith('.'))) {
|
|
43
|
+
path = process.cwd() + sep + path;
|
|
44
|
+
}
|
|
45
|
+
const m = await import(/* @vite-ignore */ path);
|
|
46
|
+
importedModules.set(name, m);
|
|
47
|
+
// e.g of dynamic fn-call:
|
|
48
|
+
//// let f = eval("(a, b) => m.add(a, b)");
|
|
49
|
+
//// console.log(f(10, 20))
|
|
50
|
+
return m;
|
|
51
|
+
} else {
|
|
52
|
+
return {};
|
|
41
53
|
}
|
|
42
|
-
const m = await import(/* @vite-ignore */ path);
|
|
43
|
-
importedModules.set(name, m);
|
|
44
|
-
// e.g of dynamic fn-call:
|
|
45
|
-
//// let f = eval("(a, b) => m.add(a, b)");
|
|
46
|
-
//// console.log(f(10, 20))
|
|
47
|
-
return m;
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
export function moduleImported(moduleName: string): boolean {
|
|
51
57
|
return importedModules.has(moduleName);
|
|
52
58
|
}
|
|
53
59
|
|
|
54
|
-
const ReservedImports = new Set<string>(['resolvers']);
|
|
55
|
-
|
|
56
|
-
export function validateImportName(n: string) {
|
|
57
|
-
if (ReservedImports.has(n)) {
|
|
58
|
-
throw new Error(`${n} is an import reserved by the runtime`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
60
|
function maybeEvalFunction(fnName: string): Function | undefined {
|
|
63
61
|
try {
|
|
64
62
|
return eval(fnName);
|
|
@@ -68,14 +66,6 @@ function maybeEvalFunction(fnName: string): Function | undefined {
|
|
|
68
66
|
}
|
|
69
67
|
}
|
|
70
68
|
|
|
71
|
-
function invokeReservedFn(moduleName: string, fnName: string, args: Array<any> | null) {
|
|
72
|
-
if (moduleName == 'resolvers' && fnName == 'setSubscription' && args != null) {
|
|
73
|
-
return setSubscription(args[0], args[1]);
|
|
74
|
-
} else {
|
|
75
|
-
throw new Error(`Failed to call ${moduleName}.${fnName} with the given arguments`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
69
|
async function invokeBuiltInFn(fnName: string, args: Array<any> | null, isAsync: boolean = false) {
|
|
80
70
|
if (fnName == 'now') {
|
|
81
71
|
return now();
|
|
@@ -112,9 +102,6 @@ export async function invokeModuleFn(
|
|
|
112
102
|
}
|
|
113
103
|
}
|
|
114
104
|
const mname = refs[0];
|
|
115
|
-
if (ReservedImports.has(mname)) {
|
|
116
|
-
return invokeReservedFn(mname, refs[1], args);
|
|
117
|
-
}
|
|
118
105
|
const m = importedModules.get(mname);
|
|
119
106
|
if (m != undefined) {
|
|
120
107
|
const f = m[refs[1]];
|
|
@@ -151,3 +138,5 @@ export function getModuleFn(fqFnName: string): Function | undefined {
|
|
|
151
138
|
return m[refs[1]];
|
|
152
139
|
} else return undefined;
|
|
153
140
|
}
|
|
141
|
+
|
|
142
|
+
setModuleFnFetcher(getModuleFn);
|