@onetype/framework 2.0.40 → 2.0.42

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.
Files changed (120) hide show
  1. package/addons/ai/agents/addon.js +23 -0
  2. package/addons/ai/agents/functions/parse.js +129 -0
  3. package/addons/ai/agents/item/functions/run.js +218 -0
  4. package/addons/ai/agents/load.js +8 -0
  5. package/addons/ai/orchestrator/addon.js +25 -0
  6. package/addons/ai/orchestrator/item/functions/run.js +277 -0
  7. package/addons/ai/orchestrator/item/functions/state/agent.js +41 -0
  8. package/addons/ai/orchestrator/item/functions/state/conclusion.js +27 -0
  9. package/addons/ai/orchestrator/item/functions/state/done.js +40 -0
  10. package/addons/ai/orchestrator/item/functions/state/execute.js +16 -0
  11. package/addons/ai/orchestrator/item/functions/state/goal.js +34 -0
  12. package/addons/ai/orchestrator/item/functions/state/input.js +55 -0
  13. package/addons/ai/orchestrator/item/functions/state/summary.js +26 -0
  14. package/addons/ai/orchestrator/items/agents/achievable.js +37 -0
  15. package/addons/ai/orchestrator/items/agents/agent.js +46 -0
  16. package/addons/ai/orchestrator/items/agents/conclusion.js +41 -0
  17. package/addons/ai/orchestrator/items/agents/done.js +40 -0
  18. package/addons/ai/orchestrator/items/agents/goal.js +58 -0
  19. package/addons/ai/orchestrator/items/agents/input.js +34 -0
  20. package/addons/ai/orchestrator/items/agents/planner.js +30 -0
  21. package/addons/ai/orchestrator/items/agents/summary.js +29 -0
  22. package/addons/ai/orchestrator/items/chat.js +10 -0
  23. package/addons/ai/orchestrator/load.js +25 -0
  24. package/addons/ai/providers/addon.js +16 -0
  25. package/addons/ai/providers/functions/default.js +14 -0
  26. package/addons/ai/providers/item/functions/request.js +62 -0
  27. package/addons/ai/providers/items/nue.js +98 -0
  28. package/addons/ai/providers/load.js +10 -0
  29. package/addons/render/elements/front/functions/runtime.js +25 -0
  30. package/addons/render/transforms/item/functions/run.js +6 -2
  31. package/lib/browser.js +1 -24
  32. package/lib/items/directives/160-slot.js +1 -1
  33. package/lib/items/directives/500-click-outside.js +43 -43
  34. package/lib/items/elements/ai/chat/chat.css +710 -0
  35. package/lib/items/elements/ai/chat/chat.js +429 -0
  36. package/lib/items/elements/cards/pricing/pricing.css +174 -0
  37. package/lib/items/elements/{sections → cards}/pricing/pricing.js +30 -11
  38. package/lib/items/elements/form/button/button.css +250 -0
  39. package/lib/items/elements/form/button/button.js +15 -20
  40. package/lib/items/elements/form/checkbox/checkbox.css +109 -0
  41. package/lib/items/elements/form/checkbox/checkbox.js +58 -54
  42. package/lib/items/elements/form/color/color.css +128 -0
  43. package/lib/items/elements/form/color/color.js +100 -0
  44. package/lib/items/elements/form/date/date.css +84 -0
  45. package/lib/items/elements/form/date/date.js +69 -0
  46. package/lib/items/elements/form/field/field.css +33 -57
  47. package/lib/items/elements/form/field/field.js +4 -4
  48. package/lib/items/elements/form/input/input.css +59 -84
  49. package/lib/items/elements/form/input/input.js +84 -75
  50. package/lib/items/elements/form/radio/radio.css +118 -0
  51. package/lib/items/elements/form/radio/radio.js +58 -54
  52. package/lib/items/elements/form/rating/rating.css +28 -66
  53. package/lib/items/elements/form/rating/rating.js +17 -21
  54. package/lib/items/elements/form/section/section.css +30 -73
  55. package/lib/items/elements/form/section/section.js +5 -5
  56. package/lib/items/elements/form/select/select.css +186 -0
  57. package/lib/items/elements/form/select/select.js +165 -0
  58. package/lib/items/elements/form/slider/slider.css +55 -176
  59. package/lib/items/elements/form/slider/slider.js +14 -10
  60. package/lib/items/elements/form/tags/tags.css +152 -0
  61. package/lib/items/elements/form/tags/tags.js +166 -0
  62. package/lib/items/elements/form/textarea/textarea.css +55 -92
  63. package/lib/items/elements/form/textarea/textarea.js +74 -66
  64. package/lib/items/elements/form/toggle/toggle.css +101 -0
  65. package/lib/items/elements/form/toggle/toggle.js +67 -0
  66. package/lib/items/elements/global/code/code.css +39 -8
  67. package/lib/items/elements/global/code/code.js +7 -2
  68. package/lib/items/elements/global/faq/faq.css +38 -16
  69. package/lib/items/elements/global/faq/faq.js +14 -2
  70. package/lib/items/elements/global/heading/heading.css +37 -14
  71. package/lib/items/elements/global/heading/heading.js +9 -4
  72. package/lib/items/elements/global/markdown/markdown.css +22 -15
  73. package/lib/items/elements/global/markdown/markdown.js +4 -4
  74. package/lib/items/elements/global/menu/menu.css +173 -0
  75. package/lib/items/elements/global/menu/menu.js +103 -0
  76. package/lib/items/elements/global/notice/notice.css +27 -61
  77. package/lib/items/elements/global/notice/notice.js +4 -4
  78. package/lib/items/elements/global/parameters/parameters.css +33 -14
  79. package/lib/items/elements/global/parameters/parameters.js +15 -6
  80. package/lib/items/elements/global/tags/tags.css +18 -5
  81. package/lib/items/elements/global/tags/tags.js +10 -2
  82. package/lib/items/elements/navigation/navbar/navbar.css +39 -17
  83. package/lib/items/elements/navigation/navbar/navbar.js +19 -9
  84. package/lib/items/elements/navigation/sidebar/sidebar.css +25 -39
  85. package/lib/items/elements/navigation/sidebar/sidebar.js +28 -6
  86. package/lib/items/elements/navigation/tabs/tabs.css +35 -16
  87. package/lib/items/elements/navigation/tabs/tabs.js +16 -2
  88. package/lib/items/elements/status/code/code.css +21 -12
  89. package/lib/items/elements/status/empty/empty.css +22 -17
  90. package/lib/items/elements/status/empty/empty.js +1 -1
  91. package/lib/items/elements/status/error/error.css +22 -12
  92. package/lib/items/elements/status/error/error.js +1 -1
  93. package/lib/items/elements/status/loading/loading.css +24 -14
  94. package/lib/items/elements/status/loading/loading.js +4 -4
  95. package/lib/load.js +14 -6
  96. package/lib/styles/reset.css +1 -1
  97. package/lists.md +586 -0
  98. package/orchestrator.md +288 -0
  99. package/package.json +9 -3
  100. package/lib/items/elements/form/button/styles/base.css +0 -176
  101. package/lib/items/elements/form/button/styles/sizes.css +0 -78
  102. package/lib/items/elements/form/button/styles/variants.css +0 -421
  103. package/lib/items/elements/form/checkbox/styles/base.css +0 -52
  104. package/lib/items/elements/form/checkbox/styles/sizes.css +0 -39
  105. package/lib/items/elements/form/checkbox/styles/variants.css +0 -121
  106. package/lib/items/elements/form/input/styles/base.css +0 -26
  107. package/lib/items/elements/form/input/styles/sizes.css +0 -15
  108. package/lib/items/elements/form/input/styles/variants.css +0 -98
  109. package/lib/items/elements/form/radio/styles/base.css +0 -48
  110. package/lib/items/elements/form/radio/styles/sizes.css +0 -36
  111. package/lib/items/elements/form/radio/styles/variants.css +0 -121
  112. package/lib/items/elements/global/card/card.css +0 -57
  113. package/lib/items/elements/global/card/card.js +0 -48
  114. package/lib/items/elements/sections/footer/footer.css +0 -205
  115. package/lib/items/elements/sections/footer/footer.js +0 -109
  116. package/lib/items/elements/sections/hero/hero.css +0 -100
  117. package/lib/items/elements/sections/hero/hero.js +0 -54
  118. package/lib/items/elements/sections/pricing/pricing.css +0 -148
  119. package/lib/items/elements/sections/stats/stats.css +0 -34
  120. package/lib/items/elements/sections/stats/stats.js +0 -74
@@ -0,0 +1,23 @@
1
+ import onetype from 'onetype';
2
+
3
+ const agents = onetype.Addon('agents', (addon) =>
4
+ {
5
+ addon.Field('id', ['string|number']);
6
+ addon.Field('name', ['string', 'JSON']);
7
+ addon.Field('description', ['string', '']);
8
+ addon.Field('instructions', ['string', '']);
9
+ addon.Field('context', ['object|function', {}]);
10
+ addon.Field('commands', ['array', []]);
11
+ addon.Field('tokens', ['number', 8000]);
12
+ addon.Field('provider', ['string', '']);
13
+ addon.Field('model', ['string', '']);
14
+ addon.Field('input', ['object', {}]);
15
+ addon.Field('output', ['object', {}]);
16
+ addon.Field('stop', ['function']);
17
+ addon.Field('callback', ['function']);
18
+ addon.Field('onRun', ['function']);
19
+ addon.Field('onSuccess', ['function']);
20
+ addon.Field('onFail', ['function']);
21
+ });
22
+
23
+ export default agents;
@@ -0,0 +1,129 @@
1
+ import agents from '#agents/addon.js';
2
+
3
+ agents.Fn('parse', function(content)
4
+ {
5
+ let text = (content || '').trim();
6
+
7
+ text = text.replace(/^```(?:json)?\n?/i, '').replace(/\n?```$/i, '');
8
+
9
+ /* Find first balanced JSON object */
10
+ const start = text.indexOf('{');
11
+
12
+ if (start === -1)
13
+ {
14
+ console.log('[PARSE ERROR] No JSON found in response:', text);
15
+ throw new Error('Invalid JSON response');
16
+ }
17
+
18
+ let depth = 0;
19
+ let inString = false;
20
+ let escape = false;
21
+ let end = -1;
22
+
23
+ for (let i = start; i < text.length; i++)
24
+ {
25
+ const char = text[i];
26
+
27
+ if (escape)
28
+ {
29
+ escape = false;
30
+ continue;
31
+ }
32
+
33
+ if (char === '\\' && inString)
34
+ {
35
+ escape = true;
36
+ continue;
37
+ }
38
+
39
+ if (char === '"')
40
+ {
41
+ inString = !inString;
42
+ continue;
43
+ }
44
+
45
+ if (!inString)
46
+ {
47
+ if (char === '{') depth++;
48
+ if (char === '}') depth--;
49
+
50
+ if (depth === 0)
51
+ {
52
+ end = i;
53
+ break;
54
+ }
55
+ }
56
+ }
57
+
58
+ if (end === -1)
59
+ {
60
+ console.log('[PARSE ERROR] No balanced JSON found in response:', text);
61
+ throw new Error('Invalid JSON response');
62
+ }
63
+
64
+ let json = text.slice(start, end + 1);
65
+
66
+ /* Clean string contents */
67
+ let result = '';
68
+ inString = false;
69
+ escape = false;
70
+
71
+ for (let i = 0; i < json.length; i++)
72
+ {
73
+ const char = json[i];
74
+
75
+ if (escape)
76
+ {
77
+ result += char;
78
+ escape = false;
79
+ continue;
80
+ }
81
+
82
+ if (char === '\\')
83
+ {
84
+ result += char;
85
+ escape = true;
86
+ continue;
87
+ }
88
+
89
+ if (char === '"')
90
+ {
91
+ inString = !inString;
92
+ result += char;
93
+ continue;
94
+ }
95
+
96
+ if (inString)
97
+ {
98
+ if (/[\u201C\u201D\u201E\u201F]/.test(char)) { result += '\\"'; continue; }
99
+ if (/[\u2018\u2019\u201A\u201B]/.test(char)) { result += "'"; continue; }
100
+ if (char === '\n') { result += '\\n'; continue; }
101
+ if (char === '\r') { result += '\\r'; continue; }
102
+ if (char === '\t') { result += '\\t'; continue; }
103
+ }
104
+
105
+ result += char;
106
+ }
107
+
108
+ try
109
+ {
110
+ return JSON.parse(result);
111
+ }
112
+ catch
113
+ {
114
+ /* Fix wrapped strings: "key": { "value" } → "key": "value" */
115
+ const fixed = result.replace(/:\s*\{\s*("(?:[^"\\]|\\.)*?")\s*\}/g, ': $1');
116
+
117
+ try
118
+ {
119
+ return JSON.parse(fixed);
120
+ }
121
+ catch (error)
122
+ {
123
+ console.log('[PARSE ERROR] Raw response:', text);
124
+ console.log('[PARSE ERROR] Cleaned result:', result);
125
+ console.log('[PARSE ERROR] Fixed attempt:', fixed);
126
+ throw error;
127
+ }
128
+ }
129
+ });
@@ -0,0 +1,218 @@
1
+ import onetype from 'onetype';
2
+ import agents from '#agents/addon.js';
3
+ import providers from '#providers/addon.js';
4
+
5
+ agents.Fn('item.run', async function(agent, data = {})
6
+ {
7
+ this.methods.schema = (agent) =>
8
+ {
9
+ const schema = {};
10
+
11
+ for (const [key, value] of Object.entries(agent.Get('output')))
12
+ {
13
+ if (value.populate !== false)
14
+ {
15
+ schema[key] = value;
16
+ }
17
+ }
18
+
19
+ return schema;
20
+ };
21
+
22
+ this.methods.system = (agent) =>
23
+ {
24
+ return agent.Get('instructions');
25
+ };
26
+
27
+ this.methods.context = (agent, data) =>
28
+ {
29
+ const context = agent.Get('context');
30
+
31
+ if (typeof context === 'function')
32
+ {
33
+ return context({ data });
34
+ }
35
+
36
+ return context;
37
+ };
38
+
39
+ this.methods.content = async (agent, data) =>
40
+ {
41
+ let content = '';
42
+
43
+ const context = await this.methods.context(agent, data);
44
+
45
+ if (context && Object.keys(context).length > 0)
46
+ {
47
+ content += JSON.stringify(context, null, 2) + '\n\n';
48
+ }
49
+
50
+ if (Object.keys(data).length > 0)
51
+ {
52
+ content += JSON.stringify(data, null, 2);
53
+ }
54
+
55
+ return content.trim();
56
+ };
57
+
58
+ this.methods.output = (schema) =>
59
+ {
60
+ const keys = Object.keys(schema);
61
+
62
+ if (keys.length === 0)
63
+ {
64
+ return 'Respond with a JSON object.';
65
+ }
66
+
67
+ let text = 'Respond with a single-line JSON object containing:\n';
68
+
69
+ for (const [key, field] of Object.entries(schema))
70
+ {
71
+ const type = field.type || 'string';
72
+ const required = field.required === false ? 'optional' : 'required';
73
+ const description = field.description || '';
74
+
75
+ text += `- "${key}" (${type}, ${required})${description ? ': ' + description : ''}\n`;
76
+ }
77
+
78
+ return text.trim();
79
+ };
80
+
81
+ this.methods.example = (schema) =>
82
+ {
83
+ const example = {};
84
+
85
+ for (const [key, field] of Object.entries(schema))
86
+ {
87
+ const type = field.type || 'string';
88
+
89
+ if (type === 'number')
90
+ {
91
+ example[key] = 0;
92
+ }
93
+ else if (type === 'boolean')
94
+ {
95
+ example[key] = false;
96
+ }
97
+ else if (type === 'array')
98
+ {
99
+ example[key] = [];
100
+ }
101
+ else if (type === 'object')
102
+ {
103
+ example[key] = {};
104
+ }
105
+ else
106
+ {
107
+ example[key] = '';
108
+ }
109
+ }
110
+
111
+ return JSON.stringify(example);
112
+ };
113
+
114
+ this.methods.format = () =>
115
+ {
116
+ return { type: 'json_object' };
117
+ };
118
+
119
+ this.methods.payload = async (agent, data) =>
120
+ {
121
+ const schema = this.methods.schema(agent);
122
+ const system = this.methods.system(agent);
123
+ const content = await this.methods.content(agent, data);
124
+ const output = this.methods.output(schema);
125
+ const example = this.methods.example(schema);
126
+ const format = this.methods.format(agent, schema);
127
+
128
+ const messages = [
129
+ { role: 'system', content: system },
130
+ { role: 'assistant', content: 'What data do you have?' },
131
+ { role: 'user', content: content },
132
+ { role: 'assistant', content: 'How should I format my response?' },
133
+ { role: 'user', content: output + '\n\nExample: ' + example }
134
+ ];
135
+
136
+ return {
137
+ model: agent.Get('model'),
138
+ messages,
139
+ max_tokens: agent.Get('tokens') || 1000,
140
+ temperature: 0.7,
141
+ top_p: 0.8,
142
+ top_k: 20,
143
+ presence_penalty: 1.5,
144
+ response_format: format
145
+ };
146
+ };
147
+
148
+ this.methods.validate = (data, schema, type) =>
149
+ {
150
+ if (Object.keys(schema).length === 0)
151
+ {
152
+ return data;
153
+ }
154
+
155
+ try
156
+ {
157
+ return onetype.DataDefine(data, schema);
158
+ }
159
+ catch (error)
160
+ {
161
+ throw new Error(`Agent ${type} Error: ${error.message}`);
162
+ }
163
+ };
164
+
165
+ const validated = this.methods.validate(data, agent.Get('input'), 'Input');
166
+ const payload = await this.methods.payload(agent, validated);
167
+
168
+ const providerId = agent.Get('provider');
169
+ const provider = providerId ? providers.ItemGet(providerId) : providers.Fn('default');
170
+
171
+ if (!provider)
172
+ {
173
+ throw new Error(`Provider not found: ${providerId || 'default'}`);
174
+ }
175
+
176
+ try
177
+ {
178
+ agent.Get('onRun') && await agent.Get('onRun')({ payload });
179
+
180
+ const result = await provider.Fn('request', payload);
181
+ let parsed = agents.Fn('parse', result.content);
182
+
183
+ if (agent.Get('callback'))
184
+ {
185
+ await agent.Get('callback')({ input: validated, output: parsed });
186
+ parsed = this.methods.validate(parsed, agent.Get('output'), 'Output Post-Callback');
187
+ }
188
+ else
189
+ {
190
+ parsed = this.methods.validate(parsed, agent.Get('output'), 'Output');
191
+ }
192
+
193
+ const missing = Object.keys(agent.Get('output')).filter(k => agent.Get('output')[k].populate !== false && parsed[k] === undefined);
194
+
195
+ if (missing.length > 0)
196
+ {
197
+ throw new Error(`Missing output fields: ${missing.join(', ')}`);
198
+ }
199
+
200
+ const meta = {
201
+ time: result.time,
202
+ tokens: result.tokens,
203
+ tps: result.tps,
204
+ reasoning: result.reasoning
205
+ };
206
+
207
+ agent.Get('onSuccess') && await agent.Get('onSuccess')({ payload, parsed, meta });
208
+
209
+ parsed._meta = meta;
210
+
211
+ return parsed;
212
+ }
213
+ catch (error)
214
+ {
215
+ agent.Get('onFail') && await agent.Get('onFail')({ payload, error });
216
+ throw error;
217
+ }
218
+ });
@@ -0,0 +1,8 @@
1
+ import '#providers/load.js';
2
+ import agents from '#agents/addon.js';
3
+
4
+ /* Functions */
5
+ import '#agents/functions/parse.js';
6
+ import '#agents/item/functions/run.js';
7
+
8
+ export default agents;
@@ -0,0 +1,25 @@
1
+ import onetype from 'onetype';
2
+
3
+ const orchestrator = onetype.Addon('orchestrator', (addon) =>
4
+ {
5
+ addon.Field('id', ['string|number']);
6
+
7
+ addon.Field('data', ['object', {}]);
8
+ addon.Field('task', ['string']);
9
+
10
+ addon.Field('steps', ['number', 10]);
11
+ addon.Field('agents', ['array', []]);
12
+ addon.Field('status', ['string', 'idle']);
13
+ addon.Field('state', ['object', null]);
14
+
15
+ addon.Field('onDone', ['function', null]);
16
+ addon.Field('onAgent', ['function', null]);
17
+ addon.Field('onGoal', ['function', null]);
18
+ addon.Field('onConclusion', ['function', null]);
19
+ addon.Field('onStep', ['function', null]);
20
+ addon.Field('onStop', ['function', null]);
21
+ addon.Field('onSuccess', ['function', null]);
22
+ addon.Field('onFail', ['function', null]);
23
+ });
24
+
25
+ export default orchestrator;
@@ -0,0 +1,277 @@
1
+ import onetype from 'onetype';
2
+ import orchestrator from '#orchestrator/addon.js';
3
+ import agents from '#agents/addon.js';
4
+
5
+ const dim = (s) => `\x1b[2m${s}\x1b[0m`;
6
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
7
+ const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
8
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
9
+ const yellow = (s) => `\x1b[33m${s}\x1b[0m`;
10
+ const red = (s) => `\x1b[31m${s}\x1b[0m`;
11
+ const magenta = (s) => `\x1b[35m${s}\x1b[0m`;
12
+
13
+ orchestrator.Fn('item.run', async function(item)
14
+ {
15
+ const state = {
16
+ data: item.Get('data'),
17
+ task: item.Get('task'),
18
+ agents: item.Get('agents').map((agent) =>
19
+ {
20
+ agent = agents.ItemGet(agent);
21
+
22
+ if(!agent)
23
+ {
24
+ return false;
25
+ }
26
+
27
+ return {
28
+ id: agent.Get('id'),
29
+ description: agent.Get('description'),
30
+ config: agent.Get('input')
31
+ }
32
+ }).filter(Boolean),
33
+
34
+ stop: false,
35
+ done: false,
36
+ agent: null,
37
+ goal: null,
38
+ input: {},
39
+ output: {},
40
+ conclusion: null,
41
+ summary: null,
42
+ history: [],
43
+
44
+ steps: { count: 0, total: item.Get('steps') },
45
+ tokens: { input: 0, output: 0 }
46
+ };
47
+
48
+ const prev = { input: 0, output: 0 };
49
+
50
+ const tks = () =>
51
+ {
52
+ const input = state.tokens.input - prev.input;
53
+ const output = state.tokens.output - prev.output;
54
+
55
+ prev.input = state.tokens.input;
56
+ prev.output = state.tokens.output;
57
+
58
+ return dim(`[${input}in/${output}out]`);
59
+ };
60
+
61
+ const truncate = (s, max = 120) => s.length > max ? s.slice(0, max) + '…' : s;
62
+
63
+ console.log('');
64
+ console.log(bold('ORCHESTRATOR') + dim(` — ${state.task}`));
65
+ // console.log(dim(`agents: ${state.agents.map(a => a.id).join(', ')}`));
66
+ console.log(dim(`max steps: ${state.steps.total}`));
67
+ console.log('');
68
+
69
+ item.Set('status', 'running');
70
+ item.Set('state', state);
71
+
72
+ const start = Date.now();
73
+
74
+ try
75
+ {
76
+ /* Planner */
77
+
78
+ const planner = await agents.ItemGet('orchestrator-planner').Fn('run', {
79
+ prompt: state.task
80
+ });
81
+
82
+ state.plan = planner.tasks;
83
+ state.tokens.input += planner._meta.tokens.input;
84
+ state.tokens.output += planner._meta.tokens.output;
85
+
86
+ console.log(bold(yellow('PLAN')) + dim(` — ${state.plan.length} tasks`));
87
+
88
+ for (const task of state.plan)
89
+ {
90
+ console.log(dim(` [${task.order}] `) + dim(task.task));
91
+ }
92
+
93
+ console.log('');
94
+
95
+ /* Achievable */
96
+
97
+ const check = await agents.ItemGet('orchestrator-achievable').Fn('run', {
98
+ tasks: state.plan,
99
+ agents: state.agents.map(a => ({ id: a.id, description: a.description }))
100
+ });
101
+
102
+ state.tokens.input += check._meta.tokens.input;
103
+ state.tokens.output += check._meta.tokens.output;
104
+
105
+ if (!check.achievable)
106
+ {
107
+ const rejected = check.rejected || [];
108
+
109
+ console.log(bold(red('NOT ACHIEVABLE')));
110
+
111
+ for (const r of rejected)
112
+ {
113
+ console.log(red(' ✗ ') + dim(r.task) + dim(` — ${r.reason}`));
114
+ }
115
+
116
+ console.log('');
117
+
118
+ item.Set('status', 'failed');
119
+
120
+ return state;
121
+ }
122
+
123
+ console.log(bold(green('ACHIEVABLE')));
124
+ console.log('');
125
+
126
+ return state;
127
+
128
+ while (state.steps.count < state.steps.total)
129
+ {
130
+ if (state.history.length > 0)
131
+ {
132
+ await item.Fn('state.done', state);
133
+
134
+ const { actions } = state.debug;
135
+ const pending = actions.filter(a => !a.confirmed).map(a => a.action);
136
+ const info = dim(` — ${state.debug.confirmed}/${state.debug.total}`) + (pending.length ? dim(` pending: ${pending.join(', ')}`) : '');
137
+
138
+ if (state.done)
139
+ {
140
+ console.log(green(' done') + info + ` ${tks()}`);
141
+ break;
142
+ }
143
+
144
+ console.log(dim(' done') + info + ` ${tks()}`);
145
+ }
146
+
147
+ if(state.stop)
148
+ {
149
+ const onStop = item.Get('onStop');
150
+
151
+ if(onStop)
152
+ {
153
+ await onStop({ state });
154
+ }
155
+
156
+ break;
157
+ }
158
+
159
+ state.steps.count++;
160
+
161
+ console.log(bold(cyan(`STEP ${state.steps.count}/${state.steps.total}`)));
162
+
163
+ /* Agent + Goal */
164
+
165
+ await item.Fn('state.agent', state);
166
+ console.log(yellow(' agent') + dim(` — ${state.agent}`) + ` ${tks()}`);
167
+ console.log(dim(` goal — ${state.goal}`));
168
+
169
+ /* Input */
170
+
171
+ await item.Fn('state.input', state);
172
+
173
+ const fields = Object.keys(state.input);
174
+
175
+ if (fields.length > 0)
176
+ {
177
+ const pairs = fields.map(k => `${k}: ${JSON.stringify(state.input[k])}`).join(', ');
178
+ console.log(magenta(' input') + dim(` — ${pairs}`) + ` ${tks()}`);
179
+ }
180
+ else
181
+ {
182
+ console.log(dim(' input — (none)') + ` ${tks()}`);
183
+ }
184
+
185
+ /* Execute */
186
+
187
+ await item.Fn('state.execute', state);
188
+
189
+ const keys = Object.keys(state.output);
190
+ const preview = keys.map(k =>
191
+ {
192
+ const v = JSON.stringify(state.output[k]);
193
+ return `${k}: ${v.length > 60 ? v.slice(0, 60) + '…' : v}`;
194
+ }).join(', ');
195
+
196
+ console.log(cyan(' exec ') + dim(` — ${truncate(preview, 200)}`) + ` ${tks()}`);
197
+
198
+ /* Conclusion */
199
+
200
+ await item.Fn('state.conclusion', state);
201
+ console.log(green(' concl') + dim(` — ${state.conclusion}`) + ` ${tks()}`);
202
+
203
+ state.history.push({
204
+ agent: state.agent,
205
+ step: state.steps.count,
206
+ goal: state.goal,
207
+ input: { ...state.input },
208
+ output: { ...state.output },
209
+ conclusion: state.conclusion
210
+ });
211
+
212
+ const onStep = item.Get('onStep');
213
+
214
+ if(onStep)
215
+ {
216
+ await onStep({ state });
217
+ }
218
+
219
+ console.log('');
220
+ }
221
+
222
+ if(state.stop)
223
+ {
224
+ item.Set('status', 'stopped');
225
+
226
+ return state;
227
+ }
228
+
229
+ if(!state.done)
230
+ {
231
+ throw onetype.Error(422, `Max steps (${state.steps.total}) reached without completing task`, {state});
232
+ }
233
+
234
+ /* Summary */
235
+
236
+ await item.Fn('state.summary', state);
237
+
238
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
239
+
240
+ console.log('');
241
+ console.log(bold(green('COMPLETE')) + dim(` — ${state.steps.count} steps, ${elapsed}s`));
242
+ console.log(dim(`tokens: ${state.tokens.input}in / ${state.tokens.output}out`));
243
+ console.log(green('summary') + dim(` — ${state.summary}`));
244
+ console.log('');
245
+
246
+ item.Set('status', 'completed');
247
+
248
+ const onSuccess = item.Get('onSuccess');
249
+
250
+ if(onSuccess)
251
+ {
252
+ await onSuccess({ state });
253
+ }
254
+
255
+ return state;
256
+ }
257
+ catch (error)
258
+ {
259
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
260
+
261
+ console.log('');
262
+ console.log(bold(red('FAILED')) + dim(` — step ${state.steps.count}, ${elapsed}s`));
263
+ console.log(red(error.message));
264
+ console.log('');
265
+
266
+ item.Set('status', 'failed');
267
+
268
+ const onFail = item.Get('onFail');
269
+
270
+ if(onFail)
271
+ {
272
+ await onFail({ state, error });
273
+ }
274
+
275
+ throw error;
276
+ }
277
+ });