foliko 2.0.5 → 2.0.7
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/.claude/settings.local.json +4 -1
- package/.cli_default_systemPrompt.md +291 -0
- package/CLAUDE.md +3 -0
- package/README.md +20 -3
- package/docs/architecture.md +34 -2
- package/docs/extensions.md +199 -0
- package/docs/migration.md +100 -0
- package/docs/public-api.md +280 -24
- package/docs/usage.md +122 -30
- package/package.json +1 -1
- package/plugins/core/audit/index.js +1 -1
- package/plugins/core/default/bootstrap.js +44 -19
- package/plugins/core/python-loader/index.js +43 -25
- package/plugins/core/scheduler/index.js +1 -0
- package/plugins/core/skill-manager/PROMPT.md +6 -0
- package/plugins/core/skill-manager/index.js +402 -115
- package/plugins/core/sub-agent/PROMPT.md +10 -0
- package/plugins/core/sub-agent/index.js +36 -3
- package/plugins/core/think/index.js +1 -0
- package/plugins/core/workflow/context.js +941 -0
- package/plugins/core/workflow/engine.js +66 -0
- package/plugins/core/workflow/examples/01-basic.js +42 -0
- package/plugins/core/workflow/examples/01-basic.json +30 -0
- package/plugins/core/workflow/examples/02-choice.js +75 -0
- package/plugins/core/workflow/examples/02-choice.json +59 -0
- package/plugins/core/workflow/examples/03-chain-style.js +114 -0
- package/plugins/core/workflow/examples/03-each.json +41 -0
- package/plugins/core/workflow/examples/04-parallel.js +52 -0
- package/plugins/core/workflow/examples/04-parallel.json +51 -0
- package/plugins/core/workflow/examples/05-chain-style.json +68 -0
- package/plugins/core/workflow/examples/05-each.js +65 -0
- package/plugins/core/workflow/examples/06-script.js +82 -0
- package/plugins/core/workflow/examples/07-module-export.js +43 -0
- package/plugins/core/workflow/examples/08-default-export.js +29 -0
- package/plugins/core/workflow/examples/09-next-with-args.js +50 -0
- package/plugins/core/workflow/examples/10-logger.js +34 -0
- package/plugins/core/workflow/examples/11-storage.js +68 -0
- package/plugins/core/workflow/examples/simple.js +77 -0
- package/plugins/core/workflow/examples/simple.json +75 -0
- package/plugins/core/workflow/index.js +204 -78
- package/plugins/core/workflow/js-runner.js +318 -0
- package/plugins/core/workflow/json-runner.js +323 -0
- package/plugins/core/workflow/stages/action.js +211 -0
- package/plugins/core/workflow/stages/choice.js +74 -0
- package/plugins/core/workflow/stages/delay.js +73 -0
- package/plugins/core/workflow/stages/each.js +123 -0
- package/plugins/core/workflow/stages/parallel.js +69 -0
- package/plugins/core/workflow/stages/try.js +142 -0
- package/plugins/executors/data-splitter/PROMPT.md +13 -0
- package/plugins/executors/data-splitter/index.js +8 -6
- package/plugins/executors/extension/extension-registry.js +145 -0
- package/plugins/executors/extension/index.js +405 -437
- package/plugins/executors/extension/prompt-builder.js +359 -0
- package/plugins/executors/extension/skill-helper.js +143 -0
- package/plugins/messaging/feishu/index.js +5 -3
- package/plugins/messaging/qq/index.js +6 -4
- package/plugins/messaging/telegram/index.js +6 -3
- package/plugins/messaging/weixin/index.js +5 -3
- package/plugins/tools/PROMPT.md +26 -0
- package/plugins/tools/index.js +6 -5
- package/sandbox/check-context.js +5 -0
- package/sandbox/test-context.js +27 -0
- package/sandbox/test-fixes.js +40 -0
- package/sandbox/test-hello-js.js +46 -0
- package/skills/foliko/AGENTS.md +196 -43
- package/skills/foliko/SKILL.md +157 -28
- package/skills/mcp/SKILL.md +77 -118
- package/skills/plugins/SKILL.md +89 -3
- package/skills/python/SKILL.md +57 -39
- package/skills/skill-guide/SKILL.md +42 -34
- package/skills/workflows/SKILL.md +753 -436
- package/src/agent/chat.js +56 -28
- package/src/agent/main.js +39 -14
- package/src/agent/prompt-registry.js +56 -16
- package/src/agent/prompts/PROMPT.md +3 -0
- package/src/agent/sub.js +1 -1
- package/src/cli/ui/chat-ui-old.js +5 -2
- package/src/cli/ui/chat-ui.js +9 -5
- package/src/common/constants.js +12 -0
- package/src/common/error-capture.js +91 -0
- package/src/common/json-safe.js +20 -0
- package/src/common/logger.js +2 -2
- package/src/context/compressor.js +6 -2
- package/src/executors/mcp-executor.js +105 -125
- package/src/framework/framework.js +78 -12
- package/src/index.js +4 -0
- package/src/plugin/base.js +908 -5
- package/src/plugin/manager.js +124 -9
- package/src/tool/schema.js +32 -9
- package/src/utils/sandbox.js +1 -1
- package/website/index.html +821 -0
- package/skills/workflows/workflow-troubleshooting/DEBUGGING.md +0 -197
- package/skills/workflows/workflow-troubleshooting/SKILL.md +0 -391
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Script Workflow (JS Format)
|
|
3
|
+
* Demonstrates script execution and data transformation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Initialize data
|
|
8
|
+
$.push('init', function($) {
|
|
9
|
+
const rawData = {
|
|
10
|
+
users: [
|
|
11
|
+
{ id: 1, name: 'Alice', age: 30, active: true },
|
|
12
|
+
{ id: 2, name: 'Bob', age: 25, active: false },
|
|
13
|
+
{ id: 3, name: 'Charlie', age: 35, active: true }
|
|
14
|
+
],
|
|
15
|
+
threshold: 28
|
|
16
|
+
};
|
|
17
|
+
$.send({ rawData });
|
|
18
|
+
$.next('filter');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Stage 2: Filter with script
|
|
22
|
+
$.push('filter', function($) {
|
|
23
|
+
const { users, threshold } = $.data.rawData;
|
|
24
|
+
|
|
25
|
+
// Use script to filter users by age
|
|
26
|
+
const filtered = users.filter(u => u.age >= threshold);
|
|
27
|
+
|
|
28
|
+
$.send({ filtered, total: users.length, filteredCount: filtered.length });
|
|
29
|
+
$.next('transform');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Stage 3: Transform with script
|
|
33
|
+
$.push('transform', function($) {
|
|
34
|
+
const { filtered } = $.data;
|
|
35
|
+
|
|
36
|
+
// Transform to summary format
|
|
37
|
+
const summary = filtered.map(u => ({
|
|
38
|
+
displayName: u.name.toUpperCase(),
|
|
39
|
+
age: u.age,
|
|
40
|
+
status: u.active ? 'Active' : 'Inactive'
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
$.send({ summary });
|
|
44
|
+
$.next('log');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Stage 4: Log results
|
|
48
|
+
$.push('log', function($) {
|
|
49
|
+
const { summary, filteredCount, total } = $.data;
|
|
50
|
+
|
|
51
|
+
$.tool.execute('log_event', {
|
|
52
|
+
event: 'filter_complete',
|
|
53
|
+
total: total,
|
|
54
|
+
filtered: filteredCount,
|
|
55
|
+
summary: JSON.stringify(summary)
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
$.next('notify');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Stage 5: Notify
|
|
62
|
+
$.push('notify', function($) {
|
|
63
|
+
const { summary } = $.data;
|
|
64
|
+
const message = summary
|
|
65
|
+
.map(u => `${u.displayName} (${u.age}) - ${u.status}`)
|
|
66
|
+
.join('\n');
|
|
67
|
+
|
|
68
|
+
$.tool.execute('notification_send', {
|
|
69
|
+
title: 'Filtered Users',
|
|
70
|
+
message: message || 'No users matched criteria'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
$.next('done');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Done
|
|
77
|
+
$.push('done', function($) {
|
|
78
|
+
$.destroy();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
$.next('init');
|
|
82
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Export Workflow Example
|
|
3
|
+
* Demonstrates module.exports = function($) {} format
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports = function ($) {
|
|
7
|
+
// Initialize
|
|
8
|
+
$.push('init', function ($) {
|
|
9
|
+
const data = {
|
|
10
|
+
userId: $.input.userId || 1,
|
|
11
|
+
action: 'process'
|
|
12
|
+
};
|
|
13
|
+
$.send({ data });
|
|
14
|
+
$.next('fetch');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
// Fetch user data
|
|
18
|
+
$.push('fetch', async function ($) {
|
|
19
|
+
const result = await $.tool.execute('fetch', {
|
|
20
|
+
url: 'https://api.example.com/users/' + $.data.data.userId
|
|
21
|
+
});
|
|
22
|
+
$.send({ user: result });
|
|
23
|
+
$.next('process');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Process based on status
|
|
27
|
+
$.push('process', function ($) {
|
|
28
|
+
const status = $.data.user?.body?.status || 'unknown';
|
|
29
|
+
$.tool.execute('log_event', {
|
|
30
|
+
event: 'user_processed',
|
|
31
|
+
userId: $.data.data.userId,
|
|
32
|
+
status: status
|
|
33
|
+
});
|
|
34
|
+
$.next('done');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Done
|
|
38
|
+
$.push('done', function ($) {
|
|
39
|
+
$.destroy();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
$.next('init');
|
|
43
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Export Workflow Example
|
|
3
|
+
* Demonstrates module.exports.default = function($) {} format
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
module.exports.default = function ($) {
|
|
7
|
+
$.push('start', async function ($) {
|
|
8
|
+
const result = await $.tool.execute('fetch', {
|
|
9
|
+
url: 'https://api.ipify.org?format=json'
|
|
10
|
+
});
|
|
11
|
+
$.send({ ip: result });
|
|
12
|
+
$.next('notify');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
$.push('notify', function ($) {
|
|
16
|
+
const ip = $.data.ip?.body?.ip || 'unknown';
|
|
17
|
+
$.tool.execute('notification_send', {
|
|
18
|
+
title: 'IP Address',
|
|
19
|
+
message: 'Your IP is: ' + ip
|
|
20
|
+
});
|
|
21
|
+
$.next('done');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
$.push('done', function ($) {
|
|
25
|
+
$.destroy();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
$.next('start');
|
|
29
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* $.next() with Arguments - Function Parameters Demo
|
|
3
|
+
* Demonstrates $.next('stage', arg1, arg2, ...) and function($, a, b, ...) receiving args
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Fetch and pass data directly to next stage
|
|
8
|
+
$.push('fetch', async function($, ip) {
|
|
9
|
+
// ip is undefined in first call, use default value
|
|
10
|
+
const url = ip || 'https://api.ipify.org?format=json';
|
|
11
|
+
|
|
12
|
+
const result = await $.tool.execute('fetch', { url: url });
|
|
13
|
+
const ipAddress = result?.body?.ip || 'unknown';
|
|
14
|
+
|
|
15
|
+
// Pass result directly to next stage - no need for $.send()
|
|
16
|
+
$.next('process', ipAddress);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Stage 2: Receive IP directly as function parameter
|
|
20
|
+
$.push('process', function($, ip) {
|
|
21
|
+
// ip is received directly from $.next('process', ip)
|
|
22
|
+
|
|
23
|
+
$.tool.execute('log_event', {
|
|
24
|
+
event: 'ip_processed',
|
|
25
|
+
ip: ip
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Pass multiple values to next stage
|
|
29
|
+
$.next('notify', ip, 'success', new Date().toISOString());
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Stage 3: Receive multiple parameters as function arguments
|
|
33
|
+
$.push('notify', function($, ip, status, timestamp) {
|
|
34
|
+
// ip = '1.2.3.4', status = 'success', timestamp = '2024-...'
|
|
35
|
+
|
|
36
|
+
$.tool.execute('notification_send', {
|
|
37
|
+
title: 'IP Address',
|
|
38
|
+
message: `IP: ${ip}, Status: ${status}, Time: ${timestamp}`
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
$.next('done');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Done
|
|
45
|
+
$.push('done', function($) {
|
|
46
|
+
$.destroy();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
$.next('fetch');
|
|
50
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger Example - Demonstrates $.logger usage
|
|
3
|
+
* Shows different log levels and logger.child()
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Logging demo
|
|
8
|
+
$.push('logging-demo', async function($) {
|
|
9
|
+
// Use different log levels
|
|
10
|
+
$.logger.debug('Debug: Starting workflow execution');
|
|
11
|
+
$.logger.info('Info: User input received', { userId: $.input.userId || 1 });
|
|
12
|
+
$.logger.warn('Warn: This is a warning example');
|
|
13
|
+
$.logger.error('Error: This is an error example');
|
|
14
|
+
|
|
15
|
+
// Use logger.child() for module-specific logging
|
|
16
|
+
const dbLogger = $.logger.child('database');
|
|
17
|
+
dbLogger.info('Connecting to database...');
|
|
18
|
+
dbLogger.info('Query executed successfully');
|
|
19
|
+
|
|
20
|
+
const apiLogger = $.logger.child('api');
|
|
21
|
+
apiLogger.debug('API request sent');
|
|
22
|
+
apiLogger.info('API response received', { status: 200 });
|
|
23
|
+
|
|
24
|
+
$.next('done');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Done
|
|
28
|
+
$.push('done', function($) {
|
|
29
|
+
$.logger.info('Workflow completed');
|
|
30
|
+
$.destroy();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
$.next('logging-demo');
|
|
34
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Example - Demonstrates $.storage usage
|
|
3
|
+
* Shows set, get, list, delete operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Store data
|
|
8
|
+
$.push('store-data', async function($) {
|
|
9
|
+
// Store user preferences
|
|
10
|
+
await $.storage.set('preferences', {
|
|
11
|
+
theme: 'dark',
|
|
12
|
+
language: 'zh-CN'
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Store with custom namespace
|
|
16
|
+
await $.storage.set('session', {
|
|
17
|
+
userId: 12345,
|
|
18
|
+
loginTime: new Date().toISOString()
|
|
19
|
+
}, 'user');
|
|
20
|
+
|
|
21
|
+
$.next('retrieve-data');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// Stage 2: Retrieve data
|
|
25
|
+
$.push('retrieve-data', async function($) {
|
|
26
|
+
// Get preferences
|
|
27
|
+
const prefs = await $.storage.get('preferences');
|
|
28
|
+
$.logger.info('Preferences:', prefs?.data);
|
|
29
|
+
|
|
30
|
+
// Get user session from namespace
|
|
31
|
+
const session = await $.storage.get('session', 'user');
|
|
32
|
+
$.logger.info('User session:', session?.data);
|
|
33
|
+
|
|
34
|
+
// Store processed result
|
|
35
|
+
const processedData = {
|
|
36
|
+
preferences: prefs?.data,
|
|
37
|
+
session: session?.data,
|
|
38
|
+
processed: true
|
|
39
|
+
};
|
|
40
|
+
await $.storage.set('processed', processedData);
|
|
41
|
+
|
|
42
|
+
$.next('list-keys');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Stage 3: List and cleanup
|
|
46
|
+
$.push('list-keys', async function($) {
|
|
47
|
+
// List all keys in default namespace
|
|
48
|
+
const allKeys = await $.storage.list();
|
|
49
|
+
$.logger.info('All keys:', allKeys?.data);
|
|
50
|
+
|
|
51
|
+
// List keys in user namespace
|
|
52
|
+
const userKeys = await $.storage.list('user');
|
|
53
|
+
$.logger.info('User namespace keys:', userKeys?.data);
|
|
54
|
+
|
|
55
|
+
// Delete temporary data
|
|
56
|
+
await $.storage.delete('processed');
|
|
57
|
+
|
|
58
|
+
$.next('done');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Done
|
|
62
|
+
$.push('done', function($) {
|
|
63
|
+
$.logger.info('Storage workflow completed');
|
|
64
|
+
$.destroy();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
$.next('store-data');
|
|
68
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple User Onboarding Workflow (JS Format - Total.js Style)
|
|
3
|
+
* Demonstrates $.next() with arguments and function parameter receiving
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Fetch user data
|
|
8
|
+
$.push('fetch-user', async function($, userId) {
|
|
9
|
+
const id = userId || $.input.userId || 1;
|
|
10
|
+
|
|
11
|
+
const result = await $.tool.execute('fetch', {
|
|
12
|
+
url: 'https://api.example.com/users/' + id
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Pass user data directly to next stage
|
|
16
|
+
$.next('validate', result);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Stage 2: Validate user - receives result as function parameter
|
|
20
|
+
$.push('validate', function($, result) {
|
|
21
|
+
const user = result?.body || {};
|
|
22
|
+
const status = user.status || 'unknown';
|
|
23
|
+
|
|
24
|
+
// Route based on status - pass user to target stage
|
|
25
|
+
if (status === 'active') {
|
|
26
|
+
$.next('welcome', user);
|
|
27
|
+
} else if (status === 'pending') {
|
|
28
|
+
$.next('send-verification', user);
|
|
29
|
+
} else if (status === 'inactive') {
|
|
30
|
+
$.next('re-engage', user);
|
|
31
|
+
} else {
|
|
32
|
+
$.next('unknown-status', user);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Stage 3: Welcome active user - receives user directly
|
|
37
|
+
$.push('welcome', function($, user) {
|
|
38
|
+
$.extension.execute('notify', 'send_email', {
|
|
39
|
+
template: 'welcome',
|
|
40
|
+
userId: user.id
|
|
41
|
+
});
|
|
42
|
+
$.next('done');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Stage 4: Send verification
|
|
46
|
+
$.push('send-verification', function($, user) {
|
|
47
|
+
$.skill.execute('ambient', 'send-verification', {
|
|
48
|
+
userId: user.id
|
|
49
|
+
});
|
|
50
|
+
$.next('done');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Stage 5: Re-engage inactive user
|
|
54
|
+
$.push('re-engage', function($, user) {
|
|
55
|
+
$.extension.execute('notify', 'send_email', {
|
|
56
|
+
template: 're-engage',
|
|
57
|
+
userId: user.id
|
|
58
|
+
});
|
|
59
|
+
$.next('done');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Stage 6: Handle unknown status
|
|
63
|
+
$.push('unknown-status', function($, user) {
|
|
64
|
+
$.tool.execute('notify_admin', {
|
|
65
|
+
message: 'Unknown user status for user ' + user.id
|
|
66
|
+
});
|
|
67
|
+
$.next('done');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Done
|
|
71
|
+
$.push('done', function($) {
|
|
72
|
+
$.destroy();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// Start with userId from input
|
|
76
|
+
$.next('fetch-user', 1);
|
|
77
|
+
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "user-onboarding",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "User onboarding workflow demonstrating action, choice stages and chain-style accessors",
|
|
5
|
+
"stages": [
|
|
6
|
+
{
|
|
7
|
+
"name": "fetch-user",
|
|
8
|
+
"tool": "fetch",
|
|
9
|
+
"args": {
|
|
10
|
+
"url": "https://api.example.com/users/{{input.userId}}"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "validate",
|
|
15
|
+
"action": "script",
|
|
16
|
+
"script": "return input.status === 'active' || input.status === 'pending'"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "route",
|
|
20
|
+
"choice": [
|
|
21
|
+
{ "when": "validate == true && fetch-user.status == 'active'", "do": "welcome" },
|
|
22
|
+
{ "when": "fetch-user.status == 'pending'", "do": "send-verification" },
|
|
23
|
+
{ "when": "fetch-user.status == 'inactive'", "do": "re-engage" }
|
|
24
|
+
],
|
|
25
|
+
"default": "unknown-status"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "welcome",
|
|
29
|
+
"description": "Using extension.execute()",
|
|
30
|
+
"extension": "notify",
|
|
31
|
+
"tool": "send_email",
|
|
32
|
+
"args": {
|
|
33
|
+
"template": "welcome",
|
|
34
|
+
"userId": "{{input.userId}}"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "send-verification",
|
|
39
|
+
"description": "Using skill.execute()",
|
|
40
|
+
"skill": "ambient",
|
|
41
|
+
"command": "send-verification",
|
|
42
|
+
"args": {
|
|
43
|
+
"userId": "{{input.userId}}"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "re-engage",
|
|
48
|
+
"description": "Using extension.execute()",
|
|
49
|
+
"extension": "notify",
|
|
50
|
+
"tool": "send_email",
|
|
51
|
+
"args": {
|
|
52
|
+
"template": "re-engage",
|
|
53
|
+
"userId": "{{input.userId}}"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "unknown-status",
|
|
58
|
+
"description": "Using tool.execute()",
|
|
59
|
+
"tool": "notify_admin",
|
|
60
|
+
"args": {
|
|
61
|
+
"message": "Unknown user status for user {{input.userId}}"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "log-completion",
|
|
66
|
+
"description": "Using workflow.execute()",
|
|
67
|
+
"workflow": "log_event",
|
|
68
|
+
"args": {
|
|
69
|
+
"event": "onboarding_complete",
|
|
70
|
+
"userId": "{{input.userId}}",
|
|
71
|
+
"finalStatus": "{{route}}"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|