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,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowEngine v2 - Main entry point for v2 workflow system
|
|
3
|
+
* Supports JSON and JS workflow formats
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { JsonRunner } = require('./json-runner');
|
|
7
|
+
const { JsRunner } = require('./js-runner');
|
|
8
|
+
|
|
9
|
+
class FlowEngine {
|
|
10
|
+
constructor(framework) {
|
|
11
|
+
this.framework = framework;
|
|
12
|
+
this._jsonRunner = new JsonRunner(framework);
|
|
13
|
+
this._jsRunner = new JsRunner(framework);
|
|
14
|
+
this._log = require('../../../src/common/logger').logger.child('FlowEngine');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Execute a workflow
|
|
19
|
+
* @param {Object|string} workflow - Workflow definition
|
|
20
|
+
* @param {Object} input - Input data
|
|
21
|
+
* @param {string} sessionId - Session ID
|
|
22
|
+
* @returns {Promise<Object>} execution result
|
|
23
|
+
*/
|
|
24
|
+
async execute(workflow, input = {}, sessionId = null) {
|
|
25
|
+
// Parse workflow if string
|
|
26
|
+
if (typeof workflow === 'string') {
|
|
27
|
+
try {
|
|
28
|
+
workflow = JSON.parse(workflow);
|
|
29
|
+
// It's JSON, use JsonRunner
|
|
30
|
+
return await this._jsonRunner.execute(workflow, input, sessionId);
|
|
31
|
+
} catch {
|
|
32
|
+
// Not JSON, treat as JS workflow
|
|
33
|
+
return await this._jsRunner.execute(workflow, input, sessionId);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Object format detection
|
|
38
|
+
// v2 JSON: has flow + stages
|
|
39
|
+
if (workflow.flow && Array.isArray(workflow.stages)) {
|
|
40
|
+
return await this._jsonRunner.execute(workflow, input, sessionId);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Assume JS format if it's a function (exported)
|
|
44
|
+
if (typeof workflow === 'function') {
|
|
45
|
+
return await this._jsRunner.execute(workflow, input, sessionId);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
throw new Error(`Invalid workflow format. Expected { flow, stages } or JS function.`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the JSON runner for direct access
|
|
53
|
+
*/
|
|
54
|
+
getJsonRunner() {
|
|
55
|
+
return this._jsonRunner;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get the JS runner for direct access
|
|
60
|
+
*/
|
|
61
|
+
getJsRunner() {
|
|
62
|
+
return this._jsRunner;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = { FlowEngine };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic Sequential Workflow (JS Format)
|
|
3
|
+
* Demonstrates basic tool execution with $.tool
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Start: Fetch IP
|
|
8
|
+
$.push('start', async function($) {
|
|
9
|
+
const result = await $.tool.execute('fetch', {
|
|
10
|
+
url: 'https://api.ipify.org?format=json'
|
|
11
|
+
});
|
|
12
|
+
$.send({ ipData: result });
|
|
13
|
+
$.next('log');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Log the result
|
|
17
|
+
$.push('log', function($) {
|
|
18
|
+
const ip = $.data.ipData?.body?.ip || 'unknown';
|
|
19
|
+
$.tool.execute('log_event', {
|
|
20
|
+
event: 'ip_fetched',
|
|
21
|
+
ip: ip
|
|
22
|
+
});
|
|
23
|
+
$.next('notify');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Send notification
|
|
27
|
+
$.push('notify', function($) {
|
|
28
|
+
const ip = $.data.ipData?.body?.ip || 'unknown';
|
|
29
|
+
$.tool.execute('notification_send', {
|
|
30
|
+
title: 'IP Fetched',
|
|
31
|
+
message: 'Your public IP is: ' + ip
|
|
32
|
+
});
|
|
33
|
+
$.next('done');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Done
|
|
37
|
+
$.push('done', function($) {
|
|
38
|
+
$.destroy();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
$.next('start');
|
|
42
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "basic-sequential",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "Basic sequential workflow - demonstrates tool chain",
|
|
5
|
+
"stages": [
|
|
6
|
+
{
|
|
7
|
+
"name": "fetch-ip",
|
|
8
|
+
"tool": "fetch",
|
|
9
|
+
"args": {
|
|
10
|
+
"url": "https://api.ipify.org?format=json"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "log-ip",
|
|
15
|
+
"tool": "log_event",
|
|
16
|
+
"args": {
|
|
17
|
+
"event": "ip_fetched",
|
|
18
|
+
"ip": "{{fetch-ip.body.ip}}"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "notify",
|
|
23
|
+
"tool": "notification_send",
|
|
24
|
+
"args": {
|
|
25
|
+
"title": "IP Fetched",
|
|
26
|
+
"message": "Your public IP is: {{fetch-ip.body.ip}}"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Router Workflow (JS Format)
|
|
3
|
+
* Demonstrates conditional routing with choice logic
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Check user status
|
|
8
|
+
$.push('check-status', async function($) {
|
|
9
|
+
const result = await $.tool.execute('fetch', {
|
|
10
|
+
url: 'https://api.example.com/users/' + $.input.userId
|
|
11
|
+
});
|
|
12
|
+
$.send({ status: result });
|
|
13
|
+
$.next('route');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Stage 2: Route based on status
|
|
17
|
+
$.push('route', function($) {
|
|
18
|
+
const status = $.data.status?.body?.status || 'unknown';
|
|
19
|
+
|
|
20
|
+
if (status === 'active') {
|
|
21
|
+
$.next('handle-active');
|
|
22
|
+
} else if (status === 'pending') {
|
|
23
|
+
$.next('handle-pending');
|
|
24
|
+
} else if (status === 'inactive') {
|
|
25
|
+
$.next('handle-inactive');
|
|
26
|
+
} else {
|
|
27
|
+
$.next('handle-unknown');
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Stage 3a: Handle active user
|
|
32
|
+
$.push('handle-active', function($) {
|
|
33
|
+
$.tool.execute('log_event', {
|
|
34
|
+
event: 'user_active',
|
|
35
|
+
userId: $.input.userId
|
|
36
|
+
});
|
|
37
|
+
$.next('done');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Stage 3b: Handle pending user
|
|
41
|
+
$.push('handle-pending', function($) {
|
|
42
|
+
$.tool.execute('log_event', {
|
|
43
|
+
event: 'user_pending',
|
|
44
|
+
userId: $.input.userId
|
|
45
|
+
});
|
|
46
|
+
$.next('done');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Stage 3c: Handle inactive user
|
|
50
|
+
$.push('handle-inactive', function($) {
|
|
51
|
+
$.tool.execute('log_event', {
|
|
52
|
+
event: 'user_inactive',
|
|
53
|
+
userId: $.input.userId
|
|
54
|
+
});
|
|
55
|
+
$.next('done');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Stage 3d: Handle unknown status
|
|
59
|
+
$.push('handle-unknown', function($) {
|
|
60
|
+
$.tool.execute('notification_send', {
|
|
61
|
+
title: 'Unknown Status',
|
|
62
|
+
message: 'User ' + $.input.userId + ' has unknown status'
|
|
63
|
+
});
|
|
64
|
+
$.next('done');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Done
|
|
68
|
+
$.push('done', function($) {
|
|
69
|
+
$.destroy();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Start with userId from input
|
|
73
|
+
const userId = $.input.userId || 1;
|
|
74
|
+
$.next('check-status');
|
|
75
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "status-router",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "Choice/conditional workflow - routes based on status",
|
|
5
|
+
"input": {
|
|
6
|
+
"userId": 1,
|
|
7
|
+
"action": "process"
|
|
8
|
+
},
|
|
9
|
+
"stages": [
|
|
10
|
+
{
|
|
11
|
+
"name": "check-status",
|
|
12
|
+
"tool": "fetch",
|
|
13
|
+
"args": {
|
|
14
|
+
"url": "https://api.example.com/users/{{input.userId}}"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "route",
|
|
19
|
+
"choice": [
|
|
20
|
+
{ "when": "check-status.body.status == 'active'", "do": "handle-active" },
|
|
21
|
+
{ "when": "check-status.body.status == 'pending'", "do": "handle-pending" },
|
|
22
|
+
{ "when": "check-status.body.status == 'inactive'", "do": "handle-inactive" }
|
|
23
|
+
],
|
|
24
|
+
"default": "handle-unknown"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "handle-active",
|
|
28
|
+
"tool": "log_event",
|
|
29
|
+
"args": {
|
|
30
|
+
"event": "user_active",
|
|
31
|
+
"userId": "{{input.userId}}"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "handle-pending",
|
|
36
|
+
"tool": "log_event",
|
|
37
|
+
"args": {
|
|
38
|
+
"event": "user_pending",
|
|
39
|
+
"userId": "{{input.userId}}"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "handle-inactive",
|
|
44
|
+
"tool": "log_event",
|
|
45
|
+
"args": {
|
|
46
|
+
"event": "user_inactive",
|
|
47
|
+
"userId": "{{input.userId}}"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "handle-unknown",
|
|
52
|
+
"tool": "notification_send",
|
|
53
|
+
"args": {
|
|
54
|
+
"title": "Unknown Status",
|
|
55
|
+
"message": "User {{input.userId}} has unknown status"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain-Style API Demo (JS Format)
|
|
3
|
+
* Demonstrates all chain-style APIs: tool, extension, workflow, agent, prompt, skill
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: List available tools and extensions
|
|
8
|
+
$.push('list-resources', function($) {
|
|
9
|
+
const tools = $.tool.list();
|
|
10
|
+
const extensions = $.extension.list();
|
|
11
|
+
const workflows = $.workflow.list();
|
|
12
|
+
const skills = $.skill.list();
|
|
13
|
+
|
|
14
|
+
console.log('Available tools:', tools.length);
|
|
15
|
+
console.log('Available extensions:', extensions.length);
|
|
16
|
+
console.log('Available workflows:', workflows);
|
|
17
|
+
console.log('Available skills:', skills);
|
|
18
|
+
|
|
19
|
+
$.send({ resources: { tools: tools.length, extensions: extensions.length } });
|
|
20
|
+
$.next('use-extension');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Stage 2: Use extension.execute()
|
|
24
|
+
$.push('use-extension', async function($) {
|
|
25
|
+
try {
|
|
26
|
+
// Call gate-trading extension
|
|
27
|
+
const balance = await $.extension.execute('gate', 'get_balance', {
|
|
28
|
+
currency: 'USDT'
|
|
29
|
+
});
|
|
30
|
+
console.log('Gate balance:', balance);
|
|
31
|
+
$.send({ balance });
|
|
32
|
+
} catch (err) {
|
|
33
|
+
console.log('Extension call failed:', err.message);
|
|
34
|
+
$.send({ balance: null });
|
|
35
|
+
}
|
|
36
|
+
$.next('use-skill');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Stage 3: Use skill.execute()
|
|
40
|
+
$.push('use-skill', async function($) {
|
|
41
|
+
try {
|
|
42
|
+
// Call ambient skill
|
|
43
|
+
const result = await $.skill.execute('ambient', 'goals', {
|
|
44
|
+
command: '-a list'
|
|
45
|
+
});
|
|
46
|
+
console.log('Skill result:', result);
|
|
47
|
+
$.send({ skillResult: result });
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.log('Skill call failed:', err.message);
|
|
50
|
+
$.send({ skillResult: null });
|
|
51
|
+
}
|
|
52
|
+
$.next('use-workflow');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Stage 4: Use workflow.execute()
|
|
56
|
+
$.push('use-workflow', async function($) {
|
|
57
|
+
try {
|
|
58
|
+
// Call sub-workflow
|
|
59
|
+
const result = await $.workflow.execute('log_event', {
|
|
60
|
+
input: {
|
|
61
|
+
event: 'chain_js_demo',
|
|
62
|
+
source: 'chain-style-flow.js'
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
console.log('Workflow result:', result);
|
|
66
|
+
$.send({ workflowResult: result });
|
|
67
|
+
} catch (err) {
|
|
68
|
+
console.log('Workflow call failed:', err.message);
|
|
69
|
+
$.send({ workflowResult: null });
|
|
70
|
+
}
|
|
71
|
+
$.next('use-agent');
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Stage 5: Use agent.chat()
|
|
75
|
+
$.push('use-agent', async function($) {
|
|
76
|
+
try {
|
|
77
|
+
const response = await $.agent.chat({
|
|
78
|
+
message: 'What is 2 + 2? Reply in one word.',
|
|
79
|
+
role: 'assistant'
|
|
80
|
+
});
|
|
81
|
+
console.log('Agent response:', response);
|
|
82
|
+
$.send({ agentResponse: response });
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.log('Agent call failed:', err.message);
|
|
85
|
+
$.send({ agentResponse: null });
|
|
86
|
+
}
|
|
87
|
+
$.next('use-prompt');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Stage 6: Use prompt.send()
|
|
91
|
+
$.push('use-prompt', async function($) {
|
|
92
|
+
try {
|
|
93
|
+
const response = await $.prompt.send({
|
|
94
|
+
message: 'Say "Workflow Complete" if you receive this.',
|
|
95
|
+
role: 'assistant'
|
|
96
|
+
});
|
|
97
|
+
console.log('Prompt response:', response);
|
|
98
|
+
$.send({ promptResponse: response });
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.log('Prompt call failed:', err.message);
|
|
101
|
+
$.send({ promptResponse: null });
|
|
102
|
+
}
|
|
103
|
+
$.next('done');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Done
|
|
107
|
+
$.push('done', function($) {
|
|
108
|
+
console.log('Chain-style demo complete!');
|
|
109
|
+
console.log('Final data:', $.data);
|
|
110
|
+
$.destroy();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
$.next('list-resources');
|
|
114
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "process-items",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "Each loop workflow - processes multiple items",
|
|
5
|
+
"input": {
|
|
6
|
+
"items": ["item1", "item2", "item3", "item4", "item5"]
|
|
7
|
+
},
|
|
8
|
+
"stages": [
|
|
9
|
+
{
|
|
10
|
+
"name": "initialize",
|
|
11
|
+
"action": "script",
|
|
12
|
+
"script": "return input.items || [];"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "process-list",
|
|
16
|
+
"each": "{{initialize}}",
|
|
17
|
+
"as": "item",
|
|
18
|
+
"index": "idx",
|
|
19
|
+
"maxIterations": 10,
|
|
20
|
+
"stages": [
|
|
21
|
+
{
|
|
22
|
+
"name": "log-item",
|
|
23
|
+
"tool": "log_event",
|
|
24
|
+
"args": {
|
|
25
|
+
"event": "processing_item",
|
|
26
|
+
"index": "{{idx}}",
|
|
27
|
+
"item": "{{item}}"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "complete",
|
|
34
|
+
"tool": "notification_send",
|
|
35
|
+
"args": {
|
|
36
|
+
"title": "Processing Complete",
|
|
37
|
+
"message": "Processed {{initialize.length}} items"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parallel Processing Workflow (JS Format)
|
|
3
|
+
* Demonstrates parallel stage execution
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Start: Fetch multiple sources in parallel
|
|
8
|
+
$.push('start', async function($) {
|
|
9
|
+
// These could be parallel, but JS format runs sequentially
|
|
10
|
+
// The parallel execution is mainly for JSON format
|
|
11
|
+
const [user, config, status] = await Promise.all([
|
|
12
|
+
$.tool.execute('fetch', { url: 'https://api.example.com/user/1' }),
|
|
13
|
+
$.tool.execute('fetch', { url: 'https://api.example.com/config' }),
|
|
14
|
+
$.tool.execute('fetch', { url: 'https://api.example.com/status' })
|
|
15
|
+
]);
|
|
16
|
+
|
|
17
|
+
$.send({ user, config, status });
|
|
18
|
+
$.next('aggregate');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Aggregate results
|
|
22
|
+
$.push('aggregate', function($) {
|
|
23
|
+
const userId = $.data.user?.body?.id || 'unknown';
|
|
24
|
+
const version = $.data.config?.body?.version || 'unknown';
|
|
25
|
+
const ok = $.data.status?.body?.ok || false;
|
|
26
|
+
|
|
27
|
+
$.tool.execute('log_event', {
|
|
28
|
+
event: 'parallel_fetch_complete',
|
|
29
|
+
userId: userId,
|
|
30
|
+
configVersion: version,
|
|
31
|
+
statusOk: ok
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
$.next('notify');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// Send notification
|
|
38
|
+
$.push('notify', function($) {
|
|
39
|
+
$.tool.execute('notification_send', {
|
|
40
|
+
title: 'Parallel Fetch Complete',
|
|
41
|
+
message: 'Fetched 3 sources concurrently. Check logs for details.'
|
|
42
|
+
});
|
|
43
|
+
$.next('done');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Done
|
|
47
|
+
$.push('done', function($) {
|
|
48
|
+
$.destroy();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
$.next('start');
|
|
52
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "parallel-fetch",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "Parallel workflow - fetches multiple sources concurrently",
|
|
5
|
+
"stages": [
|
|
6
|
+
{
|
|
7
|
+
"name": "fetch-all",
|
|
8
|
+
"parallel": [
|
|
9
|
+
{
|
|
10
|
+
"name": "fetch-user",
|
|
11
|
+
"tool": "fetch",
|
|
12
|
+
"args": {
|
|
13
|
+
"url": "https://api.example.com/user/1"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "fetch-config",
|
|
18
|
+
"tool": "fetch",
|
|
19
|
+
"args": {
|
|
20
|
+
"url": "https://api.example.com/config"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "fetch-status",
|
|
25
|
+
"tool": "fetch",
|
|
26
|
+
"args": {
|
|
27
|
+
"url": "https://api.example.com/status"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "aggregate",
|
|
34
|
+
"tool": "log_event",
|
|
35
|
+
"args": {
|
|
36
|
+
"event": "parallel_fetch_complete",
|
|
37
|
+
"userId": "{{fetch-user.body.id}}",
|
|
38
|
+
"configVersion": "{{fetch-config.body.version}}",
|
|
39
|
+
"statusOk": "{{fetch-status.body.ok}}"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "notify",
|
|
44
|
+
"tool": "notification_send",
|
|
45
|
+
"args": {
|
|
46
|
+
"title": "Parallel Fetch Complete",
|
|
47
|
+
"message": "Fetched 3 sources concurrently"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"flow": "chain-style-demo",
|
|
3
|
+
"version": "2.0",
|
|
4
|
+
"description": "Chain-style workflow - demonstrates extension, skill, workflow calls",
|
|
5
|
+
"stages": [
|
|
6
|
+
{
|
|
7
|
+
"name": "start",
|
|
8
|
+
"tool": "log_event",
|
|
9
|
+
"args": {
|
|
10
|
+
"event": "chain_style_demo_started"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "use-extension",
|
|
15
|
+
"description": "Using extension.execute() to call gate-trading",
|
|
16
|
+
"extension": "gate",
|
|
17
|
+
"tool": "get_balance",
|
|
18
|
+
"args": {
|
|
19
|
+
"currency": "USDT"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "use-skill",
|
|
24
|
+
"description": "Using skill.execute() to call ambient agent",
|
|
25
|
+
"skill": "ambient",
|
|
26
|
+
"command": "goals",
|
|
27
|
+
"args": {
|
|
28
|
+
"command": "-a list"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "use-workflow",
|
|
33
|
+
"description": "Using workflow.execute() to call sub-workflow",
|
|
34
|
+
"workflow": "log_event",
|
|
35
|
+
"args": {
|
|
36
|
+
"input": {
|
|
37
|
+
"event": "called_from_chain_style",
|
|
38
|
+
"source": "chain-style-demo"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "use-agent",
|
|
44
|
+
"description": "Using agent.chat()",
|
|
45
|
+
"agent": "chat",
|
|
46
|
+
"args": {
|
|
47
|
+
"message": "What is the current time?",
|
|
48
|
+
"role": "assistant"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "use-prompt",
|
|
53
|
+
"description": "Using prompt.send()",
|
|
54
|
+
"prompt": "send",
|
|
55
|
+
"args": {
|
|
56
|
+
"message": "Say hello in one word",
|
|
57
|
+
"role": "assistant"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "complete",
|
|
62
|
+
"tool": "log_event",
|
|
63
|
+
"args": {
|
|
64
|
+
"event": "chain_style_demo_completed"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each Loop Workflow (JS Format)
|
|
3
|
+
* Demonstrates iteration over items
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
FLOW(function($) {
|
|
7
|
+
// Stage 1: Initialize items
|
|
8
|
+
$.push('init', function($) {
|
|
9
|
+
const items = $.input.items || ['item1', 'item2', 'item3', 'item4', 'item5'];
|
|
10
|
+
$.send({ items, processed: [] });
|
|
11
|
+
$.next('process-loop');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
// Stage 2: Process items one by one (simulating each loop)
|
|
15
|
+
$.push('process-loop', async function($) {
|
|
16
|
+
const items = $.data.items;
|
|
17
|
+
const processed = $.data.processed || [];
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < items.length; i++) {
|
|
20
|
+
const item = items[i];
|
|
21
|
+
|
|
22
|
+
// Log each item
|
|
23
|
+
await $.tool.execute('log_event', {
|
|
24
|
+
event: 'processing_item',
|
|
25
|
+
index: i,
|
|
26
|
+
item: item
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Add to processed list
|
|
30
|
+
processed.push({ index: i, item: item, status: 'done' });
|
|
31
|
+
|
|
32
|
+
// Small delay between items
|
|
33
|
+
await $.wait(100);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$.send({ items, processed });
|
|
37
|
+
$.next('complete');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Stage 3: Complete
|
|
41
|
+
$.push('complete', function($) {
|
|
42
|
+
const count = $.data.processed?.length || 0;
|
|
43
|
+
|
|
44
|
+
$.tool.execute('notification_send', {
|
|
45
|
+
title: 'Processing Complete',
|
|
46
|
+
message: 'Processed ' + count + ' items'
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
$.tool.execute('log_event', {
|
|
50
|
+
event: 'loop_complete',
|
|
51
|
+
totalProcessed: count,
|
|
52
|
+
items: $.data.processed
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
$.next('done');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Done
|
|
59
|
+
$.push('done', function($) {
|
|
60
|
+
$.destroy();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Start
|
|
64
|
+
$.next('init');
|
|
65
|
+
});
|