amalgm 0.1.51 → 0.1.52

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 (70) hide show
  1. package/lib/tunnel-events.js +48 -23
  2. package/package.json +2 -2
  3. package/runtime/lib/harnesses.js +12 -4
  4. package/runtime/scripts/amalgm-mcp/agents/store.js +5 -5
  5. package/runtime/scripts/amalgm-mcp/{artifacts → apps}/advertise.js +39 -24
  6. package/runtime/scripts/amalgm-mcp/apps/rest.js +144 -0
  7. package/runtime/scripts/amalgm-mcp/apps/store.js +171 -0
  8. package/runtime/scripts/amalgm-mcp/apps/supervisor.js +439 -0
  9. package/runtime/scripts/amalgm-mcp/apps/tools.js +176 -0
  10. package/runtime/scripts/amalgm-mcp/automations/cell-references.js +237 -0
  11. package/runtime/scripts/amalgm-mcp/automations/context.js +41 -0
  12. package/runtime/scripts/amalgm-mcp/automations/rest.js +148 -0
  13. package/runtime/scripts/amalgm-mcp/automations/runner.js +613 -0
  14. package/runtime/scripts/amalgm-mcp/automations/scheduler.js +90 -0
  15. package/runtime/scripts/amalgm-mcp/automations/store.js +1125 -0
  16. package/runtime/scripts/amalgm-mcp/automations/tool-actions.js +177 -0
  17. package/runtime/scripts/amalgm-mcp/automations/tools.js +418 -0
  18. package/runtime/scripts/amalgm-mcp/automations/validator.js +225 -0
  19. package/runtime/scripts/amalgm-mcp/browser/agent-browser.js +505 -0
  20. package/runtime/scripts/amalgm-mcp/browser/electron-bridge.js +222 -0
  21. package/runtime/scripts/amalgm-mcp/browser/page.js +13 -631
  22. package/runtime/scripts/amalgm-mcp/browser/tools.js +9 -7
  23. package/runtime/scripts/amalgm-mcp/config.js +33 -48
  24. package/runtime/scripts/amalgm-mcp/deps.js +1 -31
  25. package/runtime/scripts/amalgm-mcp/events/ingress.js +50 -42
  26. package/runtime/scripts/amalgm-mcp/events/internal-workflows.js +169 -0
  27. package/runtime/scripts/amalgm-mcp/events/matcher.js +45 -14
  28. package/runtime/scripts/amalgm-mcp/events/store.js +106 -57
  29. package/runtime/scripts/amalgm-mcp/index.js +12 -14
  30. package/runtime/scripts/amalgm-mcp/lib/prefs.js +229 -65
  31. package/runtime/scripts/amalgm-mcp/lib/tool-result.js +13 -27
  32. package/runtime/scripts/amalgm-mcp/server/core-tools.js +2 -3
  33. package/runtime/scripts/amalgm-mcp/server/http.js +106 -56
  34. package/runtime/scripts/amalgm-mcp/slack/inbound.js +1 -1
  35. package/runtime/scripts/amalgm-mcp/state/db.js +119 -0
  36. package/runtime/scripts/amalgm-mcp/state/snapshot.js +16 -3
  37. package/runtime/scripts/amalgm-mcp/tasks/executor.js +1 -1
  38. package/runtime/scripts/amalgm-mcp/tests/automations-store-runner.test.js +348 -0
  39. package/runtime/scripts/amalgm-mcp/tests/events-matcher.test.js +23 -0
  40. package/runtime/scripts/amalgm-mcp/tests/workflows-store-runner.test.js +67 -0
  41. package/runtime/scripts/amalgm-mcp/toolbox/tools.js +16 -3
  42. package/runtime/scripts/amalgm-mcp/workflows/compiler.js +222 -0
  43. package/runtime/scripts/amalgm-mcp/workflows/runner.js +593 -0
  44. package/runtime/scripts/amalgm-mcp/workflows/store.js +237 -0
  45. package/runtime/scripts/chat-core/adapters/claude.js +2 -1
  46. package/runtime/scripts/chat-core/auth.js +82 -12
  47. package/runtime/scripts/chat-core/contract.js +5 -1
  48. package/runtime/scripts/chat-core/engine.js +103 -62
  49. package/runtime/scripts/chat-core/event-schema.js +8 -0
  50. package/runtime/scripts/chat-core/events.js +5 -0
  51. package/runtime/scripts/chat-core/normalizers/codex.js +13 -1
  52. package/runtime/scripts/chat-core/parts.js +21 -6
  53. package/runtime/scripts/chat-core/sse.js +3 -0
  54. package/runtime/scripts/chat-core/tests/auth.test.js +84 -6
  55. package/runtime/scripts/chat-core/tests/engine.test.js +312 -0
  56. package/runtime/scripts/chat-core/tests/native-config.test.js +23 -0
  57. package/runtime/scripts/chat-core/tool-shape.js +4 -4
  58. package/runtime/scripts/chat-core/tooling/active-memory.js +5 -4
  59. package/runtime/scripts/chat-core/tooling/native-config.js +34 -3
  60. package/runtime/scripts/local-gateway.js +34 -27
  61. package/runtime/scripts/platform-context.txt +76 -94
  62. package/runtime/scripts/amalgm-mcp/artifacts/rest.js +0 -103
  63. package/runtime/scripts/amalgm-mcp/artifacts/store.js +0 -157
  64. package/runtime/scripts/amalgm-mcp/artifacts/supervisor.js +0 -439
  65. package/runtime/scripts/amalgm-mcp/artifacts/tools.js +0 -176
  66. package/runtime/scripts/amalgm-mcp/events/executor.js +0 -258
  67. package/runtime/scripts/amalgm-mcp/events/rest.js +0 -214
  68. package/runtime/scripts/amalgm-mcp/events/tools.js +0 -323
  69. package/runtime/scripts/amalgm-mcp/tasks/rest.js +0 -110
  70. package/runtime/scripts/amalgm-mcp/tasks/tools.js +0 -416
@@ -0,0 +1,222 @@
1
+ 'use strict';
2
+
3
+ const vm = require('vm');
4
+
5
+ const COMPILE_TIMEOUT_MS = 1000;
6
+
7
+ function isObject(value) {
8
+ return !!value && typeof value === 'object' && !Array.isArray(value);
9
+ }
10
+
11
+ function splitEventRef(ref) {
12
+ const value = String(ref || '').trim();
13
+ if (!value) return { source: '*', event: '*', ref: '*.*' };
14
+ const dot = value.indexOf('.');
15
+ if (dot === -1) return { source: value, event: '*', ref: `${value}.*` };
16
+ const source = value.slice(0, dot).trim() || '*';
17
+ const event = value.slice(dot + 1).trim() || '*';
18
+ return { source, event, ref: `${source}.${event}` };
19
+ }
20
+
21
+ function serializeValue(value) {
22
+ if (typeof value === 'function') {
23
+ return { $fn: value.toString() };
24
+ }
25
+ if (Array.isArray(value)) return value.map(serializeValue);
26
+ if (isObject(value)) {
27
+ const out = {};
28
+ for (const [key, child] of Object.entries(value)) {
29
+ if (child !== undefined) out[key] = serializeValue(child);
30
+ }
31
+ return out;
32
+ }
33
+ return value;
34
+ }
35
+
36
+ function splitToolActionRef(ref) {
37
+ const value = String(ref || '').trim();
38
+ let index = -1;
39
+ for (const separator of ['.', ':', '/']) {
40
+ index = Math.max(index, value.lastIndexOf(separator));
41
+ }
42
+ if (index === -1) return { toolId: value, actionName: '' };
43
+ return {
44
+ toolId: value.slice(0, index).trim(),
45
+ actionName: value.slice(index + 1).trim(),
46
+ };
47
+ }
48
+
49
+ function normalizeSource(sourceText) {
50
+ let source = String(sourceText || '').trim();
51
+ if (!source) throw new Error('Workflow script is empty.');
52
+
53
+ if (/^\s*export\s+default\s+workflow\s*\(/.test(source)) {
54
+ source = source.replace(/^\s*export\s+default\s+workflow\s*\(/, '__workflow = workflow(');
55
+ } else if (/^\s*module\.exports\s*=\s*workflow\s*\(/.test(source)) {
56
+ source = source.replace(/^\s*module\.exports\s*=\s*workflow\s*\(/, '__workflow = workflow(');
57
+ } else if (/^\s*workflow\s*\(/.test(source)) {
58
+ source = `__workflow = ${source}`;
59
+ }
60
+
61
+ return source;
62
+ }
63
+
64
+ function makeBuilders() {
65
+ const builders = {};
66
+
67
+ builders.event = (ref, options = {}) => ({
68
+ ...splitEventRef(ref),
69
+ ...(isObject(options) ? serializeValue(options) : {}),
70
+ });
71
+
72
+ builders.code = (name, fn, options = {}) => {
73
+ if (typeof name !== 'string' || !name.trim()) throw new Error('code() needs a cell name.');
74
+ if (typeof fn !== 'function') throw new Error(`code("${name}") needs a function.`);
75
+ return {
76
+ kind: 'code',
77
+ name: name.trim(),
78
+ code: fn.toString(),
79
+ ...(isObject(options) ? serializeValue(options) : {}),
80
+ };
81
+ };
82
+
83
+ builders.cli = (name, config = {}) => {
84
+ if (typeof name !== 'string' || !name.trim()) throw new Error('cli() needs a cell name.');
85
+ return {
86
+ kind: 'cli',
87
+ name: name.trim(),
88
+ config: serializeValue(config || {}),
89
+ };
90
+ };
91
+
92
+ builders.tool = (name, toolRef, actionOrArgs = {}, argsOrOptions = {}, maybeOptions = {}) => {
93
+ if (typeof name !== 'string' || !name.trim()) throw new Error('tool() needs a cell name.');
94
+ let toolId = '';
95
+ let actionName = '';
96
+ let args = {};
97
+ let options = {};
98
+
99
+ if (isObject(toolRef)) {
100
+ const ref = toolRef.ref || toolRef.action || toolRef.tool || toolRef.call;
101
+ const parsed = ref ? splitToolActionRef(ref) : {};
102
+ toolId = String(toolRef.toolId || toolRef.tool_id || parsed.toolId || '').trim();
103
+ actionName = String(toolRef.actionName || toolRef.action_name || parsed.actionName || '').trim();
104
+ args = toolRef.args || toolRef.input || {};
105
+ options = toolRef.options || {};
106
+ } else if (typeof actionOrArgs === 'string') {
107
+ toolId = String(toolRef || '').trim();
108
+ actionName = actionOrArgs.trim();
109
+ args = argsOrOptions || {};
110
+ options = maybeOptions || {};
111
+ } else {
112
+ const parsed = splitToolActionRef(toolRef);
113
+ toolId = parsed.toolId;
114
+ actionName = parsed.actionName;
115
+ args = actionOrArgs || {};
116
+ options = argsOrOptions || {};
117
+ }
118
+
119
+ if (typeof toolId !== 'string' || !toolId.trim()) throw new Error(`tool("${name}") needs a tool id.`);
120
+ if (typeof actionName !== 'string' || !actionName.trim()) {
121
+ throw new Error(`tool("${name}") needs an action name.`);
122
+ }
123
+ return {
124
+ kind: 'tool',
125
+ name: name.trim(),
126
+ toolId: toolId.trim(),
127
+ actionName: actionName.trim(),
128
+ args: serializeValue(args || {}),
129
+ ...(isObject(options) ? serializeValue(options) : {}),
130
+ };
131
+ };
132
+
133
+ builders.http = (name, config = {}) => builders.tool(name, 'http', 'fetch', config);
134
+
135
+ builders.agent = (name, agent, promptOrArgs = {}, options = {}) => {
136
+ const args = isObject(promptOrArgs)
137
+ ? { agent, ...promptOrArgs }
138
+ : { agent, prompt: String(promptOrArgs || '') };
139
+ return builders.tool(name, 'amalgm.talk_to_agent', args, options);
140
+ };
141
+
142
+ builders.workflow = (definition) => definition;
143
+
144
+ return builders;
145
+ }
146
+
147
+ function normalizeCell(cell, index, names) {
148
+ if (!isObject(cell)) throw new Error(`Cell ${index + 1} is not a valid workflow cell.`);
149
+ if (!['code', 'cli', 'tool'].includes(cell.kind)) {
150
+ throw new Error(`Cell "${cell.name || index + 1}" has unsupported kind "${cell.kind}".`);
151
+ }
152
+ if (typeof cell.name !== 'string' || !cell.name.trim()) {
153
+ throw new Error(`Cell ${index + 1} is missing a name.`);
154
+ }
155
+ const name = cell.name.trim();
156
+ if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(name)) {
157
+ throw new Error(`Cell "${name}" must start with a letter or underscore and only use letters, numbers, "_" or "-".`);
158
+ }
159
+ if (names.has(name)) throw new Error(`Duplicate workflow cell name "${name}".`);
160
+ names.add(name);
161
+
162
+ return {
163
+ id: cell.id || name,
164
+ ...cell,
165
+ name,
166
+ };
167
+ }
168
+
169
+ function normalizeWorkflow(definition) {
170
+ if (!isObject(definition)) throw new Error('workflow() needs an object.');
171
+ const trigger = isObject(definition.trigger)
172
+ ? definition.trigger
173
+ : splitEventRef(definition.trigger || '*.*');
174
+ const names = new Set();
175
+ const cells = Array.isArray(definition.cells)
176
+ ? definition.cells.map((cell, index) => normalizeCell(cell, index, names))
177
+ : [];
178
+ if (cells.length === 0) throw new Error('Workflow needs at least one cell.');
179
+
180
+ return {
181
+ version: 1,
182
+ trigger: {
183
+ ...splitEventRef(trigger.ref || `${trigger.source || '*'}.${trigger.event || '*'}`),
184
+ ...serializeValue(trigger),
185
+ },
186
+ cells,
187
+ allowlist: isObject(definition.allowlist) ? serializeValue(definition.allowlist) : {},
188
+ limits: isObject(definition.limits) ? serializeValue(definition.limits) : {},
189
+ };
190
+ }
191
+
192
+ function compileWorkflowText(workflowText) {
193
+ const source = normalizeSource(workflowText);
194
+ const builders = makeBuilders();
195
+ const sandbox = {
196
+ ...builders,
197
+ __workflow: null,
198
+ };
199
+ const context = vm.createContext(sandbox, {
200
+ name: 'amalgm-workflow-compile',
201
+ codeGeneration: { strings: true, wasm: false },
202
+ });
203
+
204
+ try {
205
+ const script = new vm.Script(source, { filename: 'workflow.dsl.js' });
206
+ script.runInContext(context, { timeout: COMPILE_TIMEOUT_MS });
207
+ } catch (error) {
208
+ throw new Error(`Workflow compile failed: ${error.message}`);
209
+ }
210
+
211
+ if (!sandbox.__workflow) {
212
+ throw new Error('Workflow script must export or return workflow({...}).');
213
+ }
214
+
215
+ return normalizeWorkflow(sandbox.__workflow);
216
+ }
217
+
218
+ module.exports = {
219
+ compileWorkflowText,
220
+ splitEventRef,
221
+ splitToolActionRef,
222
+ };