@substrate-ai/factory 0.19.54 → 0.20.1
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/dist/config.d.ts +4 -4
- package/package.json +8 -2
- package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts +0 -16
- package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts.map +0 -1
- package/dist/twins/__tests__/integration/health-monitor-integration.test.js +0 -183
- package/dist/twins/__tests__/integration/health-monitor-integration.test.js.map +0 -1
package/dist/config.d.ts
CHANGED
|
@@ -56,11 +56,11 @@ export declare const FactoryExtendedConfigSchema: z.ZodObject<{
|
|
|
56
56
|
}>>;
|
|
57
57
|
global: z.ZodObject<{
|
|
58
58
|
log_level: z.ZodEnum<{
|
|
59
|
-
error: "error";
|
|
60
59
|
trace: "trace";
|
|
61
60
|
debug: "debug";
|
|
62
61
|
info: "info";
|
|
63
62
|
warn: "warn";
|
|
63
|
+
error: "error";
|
|
64
64
|
fatal: "fatal";
|
|
65
65
|
}>;
|
|
66
66
|
max_concurrent_tasks: z.ZodNumber;
|
|
@@ -74,9 +74,9 @@ export declare const FactoryExtendedConfigSchema: z.ZodObject<{
|
|
|
74
74
|
enabled: z.ZodBoolean;
|
|
75
75
|
cli_path: z.ZodOptional<z.ZodString>;
|
|
76
76
|
subscription_routing: z.ZodEnum<{
|
|
77
|
-
auto: "auto";
|
|
78
77
|
subscription: "subscription";
|
|
79
78
|
api: "api";
|
|
79
|
+
auto: "auto";
|
|
80
80
|
disabled: "disabled";
|
|
81
81
|
}>;
|
|
82
82
|
max_concurrent: z.ZodNumber;
|
|
@@ -91,9 +91,9 @@ export declare const FactoryExtendedConfigSchema: z.ZodObject<{
|
|
|
91
91
|
enabled: z.ZodBoolean;
|
|
92
92
|
cli_path: z.ZodOptional<z.ZodString>;
|
|
93
93
|
subscription_routing: z.ZodEnum<{
|
|
94
|
-
auto: "auto";
|
|
95
94
|
subscription: "subscription";
|
|
96
95
|
api: "api";
|
|
96
|
+
auto: "auto";
|
|
97
97
|
disabled: "disabled";
|
|
98
98
|
}>;
|
|
99
99
|
max_concurrent: z.ZodNumber;
|
|
@@ -108,9 +108,9 @@ export declare const FactoryExtendedConfigSchema: z.ZodObject<{
|
|
|
108
108
|
enabled: z.ZodBoolean;
|
|
109
109
|
cli_path: z.ZodOptional<z.ZodString>;
|
|
110
110
|
subscription_routing: z.ZodEnum<{
|
|
111
|
-
auto: "auto";
|
|
112
111
|
subscription: "subscription";
|
|
113
112
|
api: "api";
|
|
113
|
+
auto: "auto";
|
|
114
114
|
disabled: "disabled";
|
|
115
115
|
}>;
|
|
116
116
|
max_concurrent: z.ZodNumber;
|
package/package.json
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrate-ai/factory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/johnplanow/substrate.git",
|
|
9
|
+
"directory": "packages/factory"
|
|
10
|
+
},
|
|
5
11
|
"main": "./dist/index.js",
|
|
6
12
|
"types": "./dist/index.d.ts",
|
|
7
13
|
"exports": {
|
|
@@ -14,7 +20,7 @@
|
|
|
14
20
|
"dist"
|
|
15
21
|
],
|
|
16
22
|
"dependencies": {
|
|
17
|
-
"@substrate-ai/core": "0.
|
|
23
|
+
"@substrate-ai/core": "0.20.1",
|
|
18
24
|
"@ts-graphviz/ast": "^3.0.6",
|
|
19
25
|
"ajv": "^6.12.6",
|
|
20
26
|
"glob": "^10.5.0",
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for TwinHealthMonitor with ScenarioRunner health gate.
|
|
3
|
-
*
|
|
4
|
-
* Verifies:
|
|
5
|
-
* 1. Unhealthy twin aborts ScenarioRunner before execution
|
|
6
|
-
* 2. Healthy twin allows runner to proceed
|
|
7
|
-
* 3. 3 consecutive failures yield twin:health-failed, polling stops
|
|
8
|
-
* 4. Success-then-fail-then-recover: status returns to healthy, no health-failed emitted
|
|
9
|
-
* 5. Polling stops after hard failure (fetch called exactly 3 times, not 4)
|
|
10
|
-
*
|
|
11
|
-
* Uses vi.useFakeTimers() for all tests to control health check polling intervals.
|
|
12
|
-
*
|
|
13
|
-
* Story 47-8, Task 3 (AC2, AC3).
|
|
14
|
-
*/
|
|
15
|
-
export {};
|
|
16
|
-
//# sourceMappingURL=health-monitor-integration.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"health-monitor-integration.test.d.ts","sourceRoot":"","sources":["../../../../src/twins/__tests__/integration/health-monitor-integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration tests for TwinHealthMonitor with ScenarioRunner health gate.
|
|
3
|
-
*
|
|
4
|
-
* Verifies:
|
|
5
|
-
* 1. Unhealthy twin aborts ScenarioRunner before execution
|
|
6
|
-
* 2. Healthy twin allows runner to proceed
|
|
7
|
-
* 3. 3 consecutive failures yield twin:health-failed, polling stops
|
|
8
|
-
* 4. Success-then-fail-then-recover: status returns to healthy, no health-failed emitted
|
|
9
|
-
* 5. Polling stops after hard failure (fetch called exactly 3 times, not 4)
|
|
10
|
-
*
|
|
11
|
-
* Uses vi.useFakeTimers() for all tests to control health check polling intervals.
|
|
12
|
-
*
|
|
13
|
-
* Story 47-8, Task 3 (AC2, AC3).
|
|
14
|
-
*/
|
|
15
|
-
import fs from 'node:fs';
|
|
16
|
-
import os from 'node:os';
|
|
17
|
-
import path from 'node:path';
|
|
18
|
-
import crypto from 'node:crypto';
|
|
19
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
20
|
-
import { createTwinHealthMonitor } from '../../health-monitor.js';
|
|
21
|
-
import { createScenarioRunner } from '../../../scenarios/runner.js';
|
|
22
|
-
import { makeLocalstackTwinDef, makeTmpScenario } from './helpers.js';
|
|
23
|
-
// ---------------------------------------------------------------------------
|
|
24
|
-
// Setup / Teardown
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
let cleanupFn = null;
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
vi.useFakeTimers();
|
|
29
|
-
cleanupFn = null;
|
|
30
|
-
});
|
|
31
|
-
afterEach(() => {
|
|
32
|
-
vi.useRealTimers();
|
|
33
|
-
vi.unstubAllGlobals();
|
|
34
|
-
cleanupFn?.();
|
|
35
|
-
cleanupFn = null;
|
|
36
|
-
});
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
// Helpers
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
function makeSpyEventBus() {
|
|
41
|
-
return { emit: vi.fn(), on: vi.fn(), off: vi.fn() };
|
|
42
|
-
}
|
|
43
|
-
function makePassingScript(tmpDir) {
|
|
44
|
-
const scriptPath = path.join(tmpDir, `scenario-${crypto.randomUUID()}.sh`);
|
|
45
|
-
fs.writeFileSync(scriptPath, '#!/bin/sh\nexit 0\n');
|
|
46
|
-
fs.chmodSync(scriptPath, 0o755);
|
|
47
|
-
const checksum = crypto.createHash('sha256').update(fs.readFileSync(scriptPath)).digest('hex');
|
|
48
|
-
return { name: path.basename(scriptPath), path: scriptPath, checksum };
|
|
49
|
-
}
|
|
50
|
-
// ---------------------------------------------------------------------------
|
|
51
|
-
// Tests
|
|
52
|
-
// ---------------------------------------------------------------------------
|
|
53
|
-
describe('health monitor integration — ScenarioRunner health gate', () => {
|
|
54
|
-
it('Test 1 — unhealthy twin aborts ScenarioRunner before any scenario executes', async () => {
|
|
55
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tw-integ-hm-'));
|
|
56
|
-
cleanupFn = () => fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
57
|
-
const mockMonitor = {
|
|
58
|
-
start: vi.fn(),
|
|
59
|
-
stop: vi.fn(),
|
|
60
|
-
getStatus: vi.fn().mockReturnValue({ localstack: 'unhealthy' }),
|
|
61
|
-
};
|
|
62
|
-
const scenario = makePassingScript(tmpDir);
|
|
63
|
-
const manifest = {
|
|
64
|
-
scenarios: [scenario],
|
|
65
|
-
capturedAt: Date.now(),
|
|
66
|
-
twins: ['localstack'],
|
|
67
|
-
};
|
|
68
|
-
const runner = createScenarioRunner({ twinHealthMonitor: mockMonitor });
|
|
69
|
-
const result = await runner.run(manifest, tmpDir);
|
|
70
|
-
expect(result.summary.failed).toBeGreaterThan(0);
|
|
71
|
-
expect(result.summary.passed).toBe(0);
|
|
72
|
-
expect(result.scenarios[0].stderr).toContain("Twin 'localstack' is unhealthy");
|
|
73
|
-
});
|
|
74
|
-
it('Test 2 — healthy twin allows runner to proceed normally', async () => {
|
|
75
|
-
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tw-integ-hm-'));
|
|
76
|
-
cleanupFn = () => fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
77
|
-
const mockMonitor = {
|
|
78
|
-
start: vi.fn(),
|
|
79
|
-
stop: vi.fn(),
|
|
80
|
-
getStatus: vi.fn().mockReturnValue({ localstack: 'healthy' }),
|
|
81
|
-
};
|
|
82
|
-
const scenario = makePassingScript(tmpDir);
|
|
83
|
-
const manifest = {
|
|
84
|
-
scenarios: [scenario],
|
|
85
|
-
capturedAt: Date.now(),
|
|
86
|
-
twins: ['localstack'],
|
|
87
|
-
};
|
|
88
|
-
const runner = createScenarioRunner({ twinHealthMonitor: mockMonitor });
|
|
89
|
-
const result = await runner.run(manifest, tmpDir);
|
|
90
|
-
expect(result.summary.passed).toBeGreaterThan(0);
|
|
91
|
-
expect(result.summary.failed).toBe(0);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
describe('health monitor integration — polling and failure detection', () => {
|
|
95
|
-
it('Test 3 — 3 consecutive failures emit twin:health-failed and mark twin unhealthy', async () => {
|
|
96
|
-
const mockFetch = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
97
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
98
|
-
const eventBus = makeSpyEventBus();
|
|
99
|
-
const monitor = createTwinHealthMonitor(eventBus, {
|
|
100
|
-
monitorIntervalMs: 1000,
|
|
101
|
-
maxConsecutiveFailures: 3,
|
|
102
|
-
});
|
|
103
|
-
monitor.start([makeLocalstackTwinDef()]);
|
|
104
|
-
await vi.advanceTimersByTimeAsync(3100);
|
|
105
|
-
expect(eventBus.emit).toHaveBeenCalledWith('twin:health-failed', expect.objectContaining({ twinName: 'localstack' }));
|
|
106
|
-
expect(monitor.getStatus()['localstack']).toBe('unhealthy');
|
|
107
|
-
monitor.stop();
|
|
108
|
-
});
|
|
109
|
-
it('Test 4 — success-then-fail-then-recover: status returns healthy, no health-failed emitted', async () => {
|
|
110
|
-
let callCount = 0;
|
|
111
|
-
const mockFetch = vi.fn().mockImplementation(() => {
|
|
112
|
-
callCount++;
|
|
113
|
-
if (callCount === 1) {
|
|
114
|
-
return Promise.reject(new Error('ECONNREFUSED'));
|
|
115
|
-
}
|
|
116
|
-
return Promise.resolve({ ok: true });
|
|
117
|
-
});
|
|
118
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
119
|
-
const eventBus = makeSpyEventBus();
|
|
120
|
-
const monitor = createTwinHealthMonitor(eventBus, {
|
|
121
|
-
monitorIntervalMs: 1000,
|
|
122
|
-
maxConsecutiveFailures: 3,
|
|
123
|
-
});
|
|
124
|
-
monitor.start([makeLocalstackTwinDef()]);
|
|
125
|
-
// First poll (t=1000): fail → warning. Second poll (t=2000): success → healthy
|
|
126
|
-
await vi.advanceTimersByTimeAsync(2100);
|
|
127
|
-
const emitCalls = eventBus.emit.mock.calls;
|
|
128
|
-
const failedCalls = emitCalls.filter((args) => args[0] === 'twin:health-failed');
|
|
129
|
-
expect(failedCalls).toHaveLength(0);
|
|
130
|
-
expect(monitor.getStatus()['localstack']).toBe('healthy');
|
|
131
|
-
monitor.stop();
|
|
132
|
-
});
|
|
133
|
-
it('Test 5 — polling stops after hard failure — fetch called exactly 3 times, not 4', async () => {
|
|
134
|
-
const mockFetch = vi.fn().mockRejectedValue(new Error('ECONNREFUSED'));
|
|
135
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
136
|
-
const eventBus = makeSpyEventBus();
|
|
137
|
-
const monitor = createTwinHealthMonitor(eventBus, {
|
|
138
|
-
monitorIntervalMs: 1000,
|
|
139
|
-
maxConsecutiveFailures: 3,
|
|
140
|
-
});
|
|
141
|
-
monitor.start([makeLocalstackTwinDef()]);
|
|
142
|
-
// Advance 4 intervals — polling stops after 3rd failure
|
|
143
|
-
await vi.advanceTimersByTimeAsync(4000);
|
|
144
|
-
expect(mockFetch).toHaveBeenCalledTimes(3);
|
|
145
|
-
monitor.stop();
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
describe('health monitor integration — mid-run crash detection (AC3)', () => {
|
|
149
|
-
it('AC3 — 1 success + 3 failures: 2 warnings, 1 health-failed, status unhealthy, no further polls', async () => {
|
|
150
|
-
let callCount = 0;
|
|
151
|
-
const mockFetch = vi.fn().mockImplementation(() => {
|
|
152
|
-
callCount++;
|
|
153
|
-
if (callCount === 1) {
|
|
154
|
-
return Promise.resolve({ ok: true });
|
|
155
|
-
}
|
|
156
|
-
return Promise.reject(new Error('ECONNREFUSED'));
|
|
157
|
-
});
|
|
158
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
159
|
-
const eventBus = makeSpyEventBus();
|
|
160
|
-
const monitor = createTwinHealthMonitor(eventBus, {
|
|
161
|
-
monitorIntervalMs: 1000,
|
|
162
|
-
maxConsecutiveFailures: 3,
|
|
163
|
-
});
|
|
164
|
-
const { manifest, cleanup } = makeTmpScenario(['localstack']);
|
|
165
|
-
cleanupFn = cleanup;
|
|
166
|
-
monitor.start([makeLocalstackTwinDef()]);
|
|
167
|
-
// 4 polls: t=1000 success, t=2000 fail(1), t=3000 fail(2), t=4000 fail(3)=health-failed
|
|
168
|
-
await vi.advanceTimersByTimeAsync(4100);
|
|
169
|
-
const emitCalls = eventBus.emit.mock.calls;
|
|
170
|
-
const warningCalls = emitCalls.filter((args) => args[0] === 'twin:health-warning');
|
|
171
|
-
const failedCalls = emitCalls.filter((args) => args[0] === 'twin:health-failed');
|
|
172
|
-
expect(warningCalls).toHaveLength(2);
|
|
173
|
-
expect(failedCalls).toHaveLength(1);
|
|
174
|
-
expect(monitor.getStatus()['localstack']).toBe('unhealthy');
|
|
175
|
-
// Advance more — no further polls should fire
|
|
176
|
-
await vi.advanceTimersByTimeAsync(2000);
|
|
177
|
-
// Still 3 failures + 1 success = 4 calls total
|
|
178
|
-
expect(mockFetch).toHaveBeenCalledTimes(4);
|
|
179
|
-
monitor.stop();
|
|
180
|
-
void manifest; // suppress unused variable warning
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
//# sourceMappingURL=health-monitor-integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"health-monitor-integration.test.js","sourceRoot":"","sources":["../../../../src/twins/__tests__/integration/health-monitor-integration.test.ts"],"names":[],"mappings":"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"}
|