apcore-js 0.21.1 → 0.22.0
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/README.md +33 -3
- package/dist/acl-handlers.d.ts.map +1 -1
- package/dist/acl-handlers.js +5 -0
- package/dist/acl-handlers.js.map +1 -1
- package/dist/async-task.d.ts +49 -14
- package/dist/async-task.d.ts.map +1 -1
- package/dist/async-task.js +134 -39
- package/dist/async-task.js.map +1 -1
- package/dist/bindings.d.ts +1 -1
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +8 -5
- package/dist/bindings.js.map +1 -1
- package/dist/browser/index.d.ts +2 -2
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +2 -2
- package/dist/browser/index.js.map +1 -1
- package/dist/builtin-steps.d.ts +14 -12
- package/dist/builtin-steps.d.ts.map +1 -1
- package/dist/builtin-steps.js +81 -28
- package/dist/builtin-steps.js.map +1 -1
- package/dist/cancel.d.ts +23 -2
- package/dist/cancel.d.ts.map +1 -1
- package/dist/cancel.js +31 -6
- package/dist/cancel.js.map +1 -1
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -3
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +27 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +33 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +36 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +94 -11
- package/dist/context.js.map +1 -1
- package/dist/errors.d.ts +64 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +101 -7
- package/dist/errors.js.map +1 -1
- package/dist/events/emitter.d.ts +46 -12
- package/dist/events/emitter.d.ts.map +1 -1
- package/dist/events/emitter.js +146 -56
- package/dist/events/emitter.js.map +1 -1
- package/dist/events/index.d.ts +2 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/events/index.js.map +1 -1
- package/dist/events/retry.d.ts +35 -0
- package/dist/events/retry.d.ts.map +1 -0
- package/dist/events/retry.js +52 -0
- package/dist/events/retry.js.map +1 -0
- package/dist/events/subscribers.d.ts +52 -9
- package/dist/events/subscribers.d.ts.map +1 -1
- package/dist/events/subscribers.js +96 -63
- package/dist/events/subscribers.js.map +1 -1
- package/dist/executor.d.ts +4 -1
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +143 -16
- package/dist/executor.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/middleware/circuit-breaker.d.ts +2 -2
- package/dist/middleware/circuit-breaker.d.ts.map +1 -1
- package/dist/middleware/circuit-breaker.js +19 -19
- package/dist/middleware/circuit-breaker.js.map +1 -1
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/manager.d.ts +6 -2
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +36 -1
- package/dist/middleware/manager.js.map +1 -1
- package/dist/middleware/platform-notify.d.ts +2 -3
- package/dist/middleware/platform-notify.d.ts.map +1 -1
- package/dist/middleware/platform-notify.js +5 -6
- package/dist/middleware/platform-notify.js.map +1 -1
- package/dist/pipeline.d.ts +1 -1
- package/dist/pipeline.js +11 -11
- package/dist/pipeline.js.map +1 -1
- package/dist/registry/registry.d.ts +46 -2
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +271 -31
- package/dist/registry/registry.js.map +1 -1
- package/dist/schema/ref-resolver.d.ts.map +1 -1
- package/dist/schema/ref-resolver.js +2 -2
- package/dist/schema/ref-resolver.js.map +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +1 -1
- package/dist/schema/types.js.map +1 -1
- package/dist/schema/validator.d.ts.map +1 -1
- package/dist/schema/validator.js +11 -20
- package/dist/schema/validator.js.map +1 -1
- package/dist/streaming.d.ts +21 -0
- package/dist/streaming.d.ts.map +1 -0
- package/dist/streaming.js +32 -0
- package/dist/streaming.js.map +1 -0
- package/dist/sys-modules/registration.d.ts.map +1 -1
- package/dist/sys-modules/registration.js +18 -8
- package/dist/sys-modules/registration.js.map +1 -1
- package/package.json +6 -3
- package/dist/registry/index.d.ts +0 -15
- package/dist/registry/index.d.ts.map +0 -1
- package/dist/registry/index.js +0 -11
- package/dist/registry/index.js.map +0 -1
- package/dist/schema/index.d.ts +0 -11
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -9
- package/dist/schema/index.js.map +0 -1
|
@@ -2,41 +2,48 @@
|
|
|
2
2
|
* Event subscribers for webhook, A2A, file, stdout, and filter delivery.
|
|
3
3
|
*/
|
|
4
4
|
import * as fs from 'node:fs';
|
|
5
|
+
import { DEFAULT_RETRY, fnmatch } from './retry.js';
|
|
5
6
|
const SEVERITY_ORDER = { info: 0, warn: 1, error: 2, fatal: 3 };
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return '.*';
|
|
14
|
-
if (c === '?')
|
|
15
|
-
return '.';
|
|
16
|
-
return c.replace(/[$()*+.?[\]^{|}-]/g, '\\$&');
|
|
17
|
-
})
|
|
18
|
-
.join('');
|
|
19
|
-
regex = new RegExp(`^${regexStr}$`);
|
|
20
|
-
_patternCache.set(pattern, regex);
|
|
21
|
-
}
|
|
22
|
-
return regex.test(text);
|
|
7
|
+
// Per-type monotonic counters for auto-generated subscriber IDs.
|
|
8
|
+
// Pattern: `^{type}-[0-9]+$` per spec event_delivery_semantics fixture.
|
|
9
|
+
const _subscriberCounters = new Map();
|
|
10
|
+
function _nextSubscriberId(typeName) {
|
|
11
|
+
const next = (_subscriberCounters.get(typeName) ?? 0);
|
|
12
|
+
_subscriberCounters.set(typeName, next + 1);
|
|
13
|
+
return `${typeName}-${next}`;
|
|
23
14
|
}
|
|
24
15
|
/**
|
|
25
16
|
* Delivers events via HTTP POST to a webhook URL.
|
|
26
17
|
*
|
|
27
|
-
* Retries on 5xx and connection errors
|
|
28
|
-
*
|
|
18
|
+
* Retries on 5xx and connection errors. As of v0.22.0 finding A-D-EVT-001,
|
|
19
|
+
* the retry policy is unified across event subscribers: the subscriber MUST
|
|
20
|
+
* NOT loop internally. Instead, it rethrows on 5xx / network errors and the
|
|
21
|
+
* outer `EventEmitter._deliver` applies the spec retry policy declared via
|
|
22
|
+
* the `retry` field (defaults to `DEFAULT_RETRY` — 3 attempts, 100 ms initial
|
|
23
|
+
* backoff, 2× multiplier, 30 s cap). 4xx responses are treated as
|
|
24
|
+
* non-retryable: a warning is logged and the call returns normally.
|
|
29
25
|
*/
|
|
30
26
|
export class WebhookSubscriber {
|
|
27
|
+
/** Declared subscriber kind for DLQ payloads (A-D-029). */
|
|
28
|
+
subscriberType = 'webhook';
|
|
29
|
+
subscriberId;
|
|
30
|
+
retry;
|
|
31
31
|
_url;
|
|
32
32
|
_headers;
|
|
33
|
-
_retryCount;
|
|
34
33
|
_timeoutMs;
|
|
35
|
-
constructor(url, headers,
|
|
34
|
+
constructor(url, headers, timeoutMsOrOpts = 5000, id) {
|
|
35
|
+
if (typeof timeoutMsOrOpts === 'number') {
|
|
36
|
+
this._timeoutMs = timeoutMsOrOpts;
|
|
37
|
+
this.retry = { ...DEFAULT_RETRY };
|
|
38
|
+
this.subscriberId = id ?? _nextSubscriberId('webhook');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this._timeoutMs = timeoutMsOrOpts.timeoutMs ?? 5000;
|
|
42
|
+
this.retry = { ...DEFAULT_RETRY, ...(timeoutMsOrOpts.retry ?? {}) };
|
|
43
|
+
this.subscriberId = timeoutMsOrOpts.id ?? id ?? _nextSubscriberId('webhook');
|
|
44
|
+
}
|
|
36
45
|
this._url = url;
|
|
37
46
|
this._headers = headers ?? {};
|
|
38
|
-
this._retryCount = retryCount;
|
|
39
|
-
this._timeoutMs = timeoutMs;
|
|
40
47
|
}
|
|
41
48
|
async onEvent(event) {
|
|
42
49
|
const payload = {
|
|
@@ -50,38 +57,26 @@ export class WebhookSubscriber {
|
|
|
50
57
|
'Content-Type': 'application/json',
|
|
51
58
|
...this._headers,
|
|
52
59
|
};
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
65
|
-
if (response.status < 500) {
|
|
66
|
-
if (response.status >= 400) {
|
|
67
|
-
console.warn('[apcore:events]', `Webhook ${this._url} returned ${response.status} for event ${event.eventType}`);
|
|
68
|
-
}
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// 5xx -- retry
|
|
72
|
-
lastError = new Error(`Webhook returned ${response.status}`);
|
|
73
|
-
console.warn('[apcore:events]', `Webhook ${this._url} returned ${response.status} (attempt ${attempt + 1}/${attempts})`);
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
lastError = err;
|
|
77
|
-
console.warn('[apcore:events]', `Webhook ${this._url} failed (attempt ${attempt + 1}/${attempts}):`, err);
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
const timer = setTimeout(() => controller.abort(), this._timeoutMs);
|
|
62
|
+
try {
|
|
63
|
+
const response = await fetch(this._url, {
|
|
64
|
+
method: 'POST',
|
|
65
|
+
headers: mergedHeaders,
|
|
66
|
+
body: JSON.stringify(payload),
|
|
67
|
+
signal: controller.signal,
|
|
68
|
+
});
|
|
69
|
+
if (response.status >= 500) {
|
|
70
|
+
// Server error — rethrow so the EventEmitter retry policy applies.
|
|
71
|
+
throw new Error(`Webhook ${this._url} returned ${response.status}`);
|
|
78
72
|
}
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
if (response.status >= 400) {
|
|
74
|
+
// Client error — non-retryable; log and return.
|
|
75
|
+
console.warn('[apcore:events]', `Webhook ${this._url} returned ${response.status} for event ${event.eventType}`);
|
|
81
76
|
}
|
|
82
77
|
}
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
finally {
|
|
79
|
+
clearTimeout(timer);
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
82
|
}
|
|
@@ -89,20 +84,41 @@ export class WebhookSubscriber {
|
|
|
89
84
|
* Delivers events via the A2A protocol to the platform.
|
|
90
85
|
*
|
|
91
86
|
* Sends a POST with `skillId="apevo.event_receiver"` and the
|
|
92
|
-
* serialized event in the payload.
|
|
87
|
+
* serialized event in the payload. As of v0.22.0 finding A-D-EVT-001 the
|
|
88
|
+
* subscriber no longer silently swallows errors: it rethrows on any
|
|
89
|
+
* status >=400 or network error so the unified `EventEmitter._deliver`
|
|
90
|
+
* retry policy applies (defaults to `DEFAULT_RETRY` — 3 attempts, 100 ms
|
|
91
|
+
* initial backoff, 2× multiplier, 30 s cap). After exhaustion the
|
|
92
|
+
* EventEmitter routes the failure through the DLQ + `onFailure` path.
|
|
93
93
|
*/
|
|
94
94
|
export class A2ASubscriber {
|
|
95
|
+
/** Declared subscriber kind for DLQ payloads (A-D-029). */
|
|
96
|
+
subscriberType = 'a2a';
|
|
97
|
+
subscriberId;
|
|
98
|
+
retry;
|
|
95
99
|
_platformUrl;
|
|
96
100
|
_auth;
|
|
97
101
|
_timeoutMs;
|
|
98
|
-
|
|
102
|
+
_skillId;
|
|
103
|
+
constructor(platformUrl, auth, timeoutMsOrOpts = 5000, id, skillId = 'apevo.event_receiver') {
|
|
104
|
+
if (typeof timeoutMsOrOpts === 'number') {
|
|
105
|
+
this._timeoutMs = timeoutMsOrOpts;
|
|
106
|
+
this.retry = { ...DEFAULT_RETRY };
|
|
107
|
+
this.subscriberId = id ?? _nextSubscriberId('a2a');
|
|
108
|
+
this._skillId = skillId;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this._timeoutMs = timeoutMsOrOpts.timeoutMs ?? 5000;
|
|
112
|
+
this.retry = { ...DEFAULT_RETRY, ...(timeoutMsOrOpts.retry ?? {}) };
|
|
113
|
+
this.subscriberId = timeoutMsOrOpts.id ?? id ?? _nextSubscriberId('a2a');
|
|
114
|
+
this._skillId = timeoutMsOrOpts.skillId ?? skillId;
|
|
115
|
+
}
|
|
99
116
|
this._platformUrl = platformUrl;
|
|
100
117
|
this._auth = auth;
|
|
101
|
-
this._timeoutMs = timeoutMs;
|
|
102
118
|
}
|
|
103
119
|
async onEvent(event) {
|
|
104
120
|
const payload = {
|
|
105
|
-
skillId:
|
|
121
|
+
skillId: this._skillId,
|
|
106
122
|
event: {
|
|
107
123
|
eventType: event.eventType,
|
|
108
124
|
moduleId: event.moduleId,
|
|
@@ -138,12 +154,10 @@ export class A2ASubscriber {
|
|
|
138
154
|
signal: controller.signal,
|
|
139
155
|
});
|
|
140
156
|
if (response.status >= 400) {
|
|
141
|
-
|
|
157
|
+
// Rethrow so the EventEmitter unified retry/DLQ policy applies.
|
|
158
|
+
throw new Error(`A2A delivery to ${this._platformUrl} failed with status ${response.status}`);
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
|
-
catch (err) {
|
|
145
|
-
console.warn('[apcore:events]', `A2A delivery to ${this._platformUrl} failed for event ${event.eventType}:`, err);
|
|
146
|
-
}
|
|
147
161
|
finally {
|
|
148
162
|
clearTimeout(timer);
|
|
149
163
|
}
|
|
@@ -151,11 +165,15 @@ export class A2ASubscriber {
|
|
|
151
165
|
}
|
|
152
166
|
/** Writes events to a local file (built-in type: 'file'). */
|
|
153
167
|
export class FileSubscriber {
|
|
168
|
+
/** Declared subscriber kind for DLQ payloads (A-D-029). */
|
|
169
|
+
subscriberType = 'file';
|
|
170
|
+
subscriberId;
|
|
154
171
|
_path;
|
|
155
172
|
_append;
|
|
156
173
|
_format;
|
|
157
174
|
_rotateBytes;
|
|
158
|
-
constructor(path, append = true, format = 'json', rotateBytes) {
|
|
175
|
+
constructor(path, append = true, format = 'json', rotateBytes, id) {
|
|
176
|
+
this.subscriberId = id ?? _nextSubscriberId('file');
|
|
159
177
|
this._path = path;
|
|
160
178
|
this._append = append;
|
|
161
179
|
this._format = format;
|
|
@@ -192,9 +210,13 @@ export class FileSubscriber {
|
|
|
192
210
|
}
|
|
193
211
|
/** Writes events to stdout (built-in type: 'stdout'). */
|
|
194
212
|
export class StdoutSubscriber {
|
|
213
|
+
/** Declared subscriber kind for DLQ payloads (A-D-029). */
|
|
214
|
+
subscriberType = 'stdout';
|
|
215
|
+
subscriberId;
|
|
195
216
|
_format;
|
|
196
217
|
_levelFilter;
|
|
197
|
-
constructor(format = 'text', levelFilter) {
|
|
218
|
+
constructor(format = 'text', levelFilter, id) {
|
|
219
|
+
this.subscriberId = id ?? _nextSubscriberId('stdout');
|
|
198
220
|
this._format = format;
|
|
199
221
|
if (levelFilter !== undefined && !(levelFilter in SEVERITY_ORDER)) {
|
|
200
222
|
console.warn(`[apcore:events] StdoutSubscriber: unknown level_filter '${levelFilter}' — valid values: info, warn, error, fatal. All events will pass.`);
|
|
@@ -229,13 +251,24 @@ export class StdoutSubscriber {
|
|
|
229
251
|
* 3. If neither is set, forward all events.
|
|
230
252
|
*/
|
|
231
253
|
export class FilterSubscriber {
|
|
254
|
+
/** Declared subscriber kind for DLQ payloads (A-D-029). */
|
|
255
|
+
subscriberType = 'filter';
|
|
256
|
+
/** Stable identity for DLQ payloads and dedup (A-D-022). */
|
|
257
|
+
subscriberId;
|
|
258
|
+
/** Retry policy applied by EventEmitter._deliver (A-D-022). */
|
|
259
|
+
retry;
|
|
232
260
|
_delegate;
|
|
233
261
|
_includeEvents;
|
|
234
262
|
_excludeEvents;
|
|
235
|
-
constructor(delegate, includeEvents, excludeEvents) {
|
|
263
|
+
constructor(delegate, includeEvents, excludeEvents, opts) {
|
|
236
264
|
this._delegate = delegate;
|
|
237
265
|
this._includeEvents = includeEvents ?? null;
|
|
238
266
|
this._excludeEvents = excludeEvents ?? null;
|
|
267
|
+
// Mirror the id/retry surface of the other subscriber types (A-D-022;
|
|
268
|
+
// Python subscribers.py FilterSubscriber accepts id + retry too). When
|
|
269
|
+
// retry is omitted, delivery uses DEFAULT_RETRY via EventEmitter._deliver.
|
|
270
|
+
this.subscriberId = opts?.id ?? _nextSubscriberId('filter');
|
|
271
|
+
this.retry = { ...DEFAULT_RETRY, ...(opts?.retry ?? {}) };
|
|
239
272
|
}
|
|
240
273
|
async onEvent(event) {
|
|
241
274
|
if (this._matches(event.eventType)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../src/events/subscribers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"subscribers.js","sourceRoot":"","sources":["../../src/events/subscribers.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { ACL } from './acl.js';
|
|
8
8
|
import type { ApprovalHandler } from './approval.js';
|
|
9
9
|
import type { Config } from './config.js';
|
|
10
|
+
import { type EventEmitter } from './events/emitter.js';
|
|
10
11
|
import { Context } from './context.js';
|
|
11
12
|
import { type Middleware } from './middleware/index.js';
|
|
12
13
|
import type { PreflightResult } from './module.js';
|
|
@@ -27,6 +28,7 @@ export declare class Executor {
|
|
|
27
28
|
private _config;
|
|
28
29
|
private _approvalHandler;
|
|
29
30
|
private _toggleState;
|
|
31
|
+
private _eventEmitter;
|
|
30
32
|
private _strategy;
|
|
31
33
|
private _pipelineEngine;
|
|
32
34
|
/** Global strategy registry for name-based resolution. */
|
|
@@ -39,6 +41,7 @@ export declare class Executor {
|
|
|
39
41
|
config?: Config | null;
|
|
40
42
|
approvalHandler?: ApprovalHandler | null;
|
|
41
43
|
toggleState?: ToggleState | null;
|
|
44
|
+
eventEmitter?: EventEmitter | null;
|
|
42
45
|
});
|
|
43
46
|
/** Build the dependency bag for strategy factories. */
|
|
44
47
|
private _buildStrategyDeps;
|
|
@@ -82,7 +85,7 @@ export declare class Executor {
|
|
|
82
85
|
*/
|
|
83
86
|
callWithTrace(moduleId: string, inputs?: Record<string, unknown> | null, context?: Context | null, options?: {
|
|
84
87
|
strategy?: ExecutionStrategy | null;
|
|
85
|
-
} | null): Promise<[Record<string, unknown>, PipelineTrace]>;
|
|
88
|
+
} | null, versionHint?: string | null): Promise<[Record<string, unknown>, PipelineTrace]>;
|
|
86
89
|
/**
|
|
87
90
|
* Streaming execution pipeline. If the module exposes a stream() async generator,
|
|
88
91
|
* yields each chunk. Otherwise falls back to call() and yields a single chunk.
|
package/dist/executor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAYrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.js
CHANGED
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { BuiltinACLCheck, BuiltinApprovalGate, buildInternalStrategy, buildMinimalStrategy, buildPerformanceStrategy, buildStandardStrategy, buildTestingStrategy, } from './builtin-steps.js';
|
|
8
8
|
import { ExecutionCancelledError } from './cancel.js';
|
|
9
|
+
// Import directly from emitter.js (browser-safe) — NOT events/index.js, which
|
|
10
|
+
// re-exports subscribers.ts (Node-only: node:fs, process) and would drag
|
|
11
|
+
// Node-only code into the browser dependency graph.
|
|
12
|
+
import { createEvent } from './events/emitter.js';
|
|
9
13
|
import { Context } from './context.js';
|
|
10
|
-
import { InvalidInputError, ModuleError, ModuleTimeoutError } from './errors.js';
|
|
14
|
+
import { ContextBindingError, InvalidInputError, ModuleError, ModuleTimeoutError } from './errors.js';
|
|
11
15
|
import { AfterMiddleware, BeforeMiddleware, RetrySignal, } from './middleware/index.js';
|
|
12
16
|
import { MiddlewareChainError, MiddlewareManager } from './middleware/manager.js';
|
|
13
17
|
import { createPreflightResult } from './module.js';
|
|
@@ -95,6 +99,35 @@ export function deepMergeChunk(base, overlay, depth = 0) {
|
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* JSON type name for a value, matching apcore-rust `json_type_name` EXACTLY
|
|
104
|
+
* (D-58 / D10-001 cross-SDK parity): null→"null", boolean→"bool",
|
|
105
|
+
* number→"number", string→"string", array→"array", object→"object".
|
|
106
|
+
* Used to populate the STREAM_CHUNK_NOT_OBJECT error's `actual_type`.
|
|
107
|
+
*/
|
|
108
|
+
function jsonTypeName(value) {
|
|
109
|
+
if (value === null)
|
|
110
|
+
return 'null';
|
|
111
|
+
if (Array.isArray(value))
|
|
112
|
+
return 'array';
|
|
113
|
+
switch (typeof value) {
|
|
114
|
+
case 'boolean':
|
|
115
|
+
return 'bool';
|
|
116
|
+
case 'number':
|
|
117
|
+
return 'number';
|
|
118
|
+
case 'string':
|
|
119
|
+
return 'string';
|
|
120
|
+
default:
|
|
121
|
+
return 'object';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* A valid stream chunk is a plain JSON object (not null, not an array, not a
|
|
126
|
+
* scalar). Mirrors apcore-rust `Value::is_object()`.
|
|
127
|
+
*/
|
|
128
|
+
function isPlainObjectChunk(value) {
|
|
129
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
130
|
+
}
|
|
98
131
|
export class Executor {
|
|
99
132
|
_registry;
|
|
100
133
|
_middlewareManager;
|
|
@@ -102,6 +135,7 @@ export class Executor {
|
|
|
102
135
|
_config;
|
|
103
136
|
_approvalHandler;
|
|
104
137
|
_toggleState;
|
|
138
|
+
_eventEmitter;
|
|
105
139
|
_strategy;
|
|
106
140
|
_pipelineEngine;
|
|
107
141
|
/** Global strategy registry for name-based resolution. */
|
|
@@ -113,6 +147,7 @@ export class Executor {
|
|
|
113
147
|
this._config = options.config ?? null;
|
|
114
148
|
this._approvalHandler = options.approvalHandler ?? null;
|
|
115
149
|
this._toggleState = options.toggleState ?? null;
|
|
150
|
+
this._eventEmitter = options.eventEmitter ?? null;
|
|
116
151
|
if (options.middlewares) {
|
|
117
152
|
for (const mw of options.middlewares) {
|
|
118
153
|
this._middlewareManager.add(mw);
|
|
@@ -241,7 +276,12 @@ export class Executor {
|
|
|
241
276
|
}
|
|
242
277
|
async call(moduleId, inputs, context, versionHint) {
|
|
243
278
|
this._validateModuleId(moduleId);
|
|
244
|
-
|
|
279
|
+
// Issue #66: auto-bind executor to context on every entry. _withExecutor
|
|
280
|
+
// is idempotent for the same instance and raises ContextBindingError on
|
|
281
|
+
// cross-executor rebind, so the rule "Executor binds itself on first call"
|
|
282
|
+
// is enforced regardless of how the caller built the Context.
|
|
283
|
+
let ctx = context ?? Context.create();
|
|
284
|
+
ctx = ctx._withExecutor(this);
|
|
245
285
|
const pipeCtx = {
|
|
246
286
|
moduleId,
|
|
247
287
|
inputs: inputs ?? {},
|
|
@@ -270,6 +310,11 @@ export class Executor {
|
|
|
270
310
|
// PipelineStepError is the engine-level contract (§1.1). Unwrap the cause
|
|
271
311
|
// so the executor's public API surfaces the original typed error.
|
|
272
312
|
const unwrapped = exc instanceof PipelineStepError ? (exc.cause instanceof Error ? exc.cause : exc) : exc;
|
|
313
|
+
// D-20: cancellation MUST bypass on_error recovery even when the engine
|
|
314
|
+
// wrapped it in a PipelineStepError. Re-check the unwrapped cause and
|
|
315
|
+
// rethrow before any middleware onError handling runs.
|
|
316
|
+
if (unwrapped instanceof ExecutionCancelledError)
|
|
317
|
+
throw unwrapped;
|
|
273
318
|
// MiddlewareChainError wraps the original; unwrap it so callers see the
|
|
274
319
|
// real error class/code instead of a generic MODULE_EXECUTE_ERROR.
|
|
275
320
|
const ctxObj = pipeCtx.context;
|
|
@@ -316,9 +361,11 @@ export class Executor {
|
|
|
316
361
|
* and a full execution trace. Requires a strategy to be set (either on the
|
|
317
362
|
* executor or passed via options).
|
|
318
363
|
*/
|
|
319
|
-
async callWithTrace(moduleId, inputs, context, options) {
|
|
364
|
+
async callWithTrace(moduleId, inputs, context, options, versionHint) {
|
|
320
365
|
const strategy = options?.strategy ?? this._strategy;
|
|
321
|
-
|
|
366
|
+
// Issue #66: auto-bind executor (see call() for rationale).
|
|
367
|
+
let ctx = context ?? Context.create();
|
|
368
|
+
ctx = ctx._withExecutor(this);
|
|
322
369
|
const pipelineCtx = {
|
|
323
370
|
moduleId,
|
|
324
371
|
inputs: inputs ?? {},
|
|
@@ -331,18 +378,44 @@ export class Executor {
|
|
|
331
378
|
outputStream: null,
|
|
332
379
|
strategy,
|
|
333
380
|
trace: null,
|
|
381
|
+
// D-19: callWithTrace shares call() semantics modulo return shape, so the
|
|
382
|
+
// version hint must reach the pipeline context (e.g. registry version
|
|
383
|
+
// resolution) identically to call().
|
|
384
|
+
versionHint: versionHint ?? null,
|
|
334
385
|
};
|
|
335
386
|
try {
|
|
336
387
|
const [output, trace] = await this._pipelineEngine.run(strategy, pipelineCtx);
|
|
337
388
|
return [(output ?? {}), trace];
|
|
338
389
|
}
|
|
339
390
|
catch (exc) {
|
|
340
|
-
//
|
|
341
|
-
//
|
|
342
|
-
|
|
343
|
-
|
|
391
|
+
// Spec D-19/D-20/D-22: `callWithTrace` MUST share `call()`'s error
|
|
392
|
+
// semantics — same on_error chain, same cancellation short-circuit,
|
|
393
|
+
// same MiddlewareChainError unwrap. The trace is the observable record
|
|
394
|
+
// of execution, including any middleware recovery, not a sanitized
|
|
395
|
+
// projection. (Closes A-D-EXEC-004; mirrors Python
|
|
396
|
+
// `call_async_with_trace`.)
|
|
397
|
+
if (exc instanceof ExecutionCancelledError)
|
|
398
|
+
throw exc;
|
|
399
|
+
const unwrapped = exc instanceof PipelineStepError ? (exc.cause instanceof Error ? exc.cause : exc) : exc;
|
|
400
|
+
// D-20: step-wrapped cancellation bypasses on_error here too.
|
|
401
|
+
if (unwrapped instanceof ExecutionCancelledError)
|
|
402
|
+
throw unwrapped;
|
|
403
|
+
const ctxObj = pipelineCtx.context;
|
|
404
|
+
const underlying = unwrapped instanceof MiddlewareChainError ? unwrapped.original : unwrapped;
|
|
405
|
+
const wrapped = propagateError(underlying, moduleId, ctxObj);
|
|
406
|
+
const executedMw = pipelineCtx.executedMiddlewares;
|
|
407
|
+
if (executedMw && executedMw.length > 0) {
|
|
408
|
+
const recovery = await this._middlewareManager.executeOnError(moduleId, pipelineCtx.inputs, wrapped, ctxObj, executedMw);
|
|
409
|
+
if (recovery !== null && !(recovery instanceof RetrySignal)) {
|
|
410
|
+
// RetrySignal is intentionally not honoured in the trace variant
|
|
411
|
+
// (D-19 leaves retry-loop semantics to `call()`); a non-null
|
|
412
|
+
// recovery dict counts as a successful middleware repair and is
|
|
413
|
+
// returned alongside the trace already captured in pipelineCtx.
|
|
414
|
+
const trace = (pipelineCtx.trace ?? null);
|
|
415
|
+
return [recovery, trace];
|
|
416
|
+
}
|
|
344
417
|
}
|
|
345
|
-
throw
|
|
418
|
+
throw wrapped;
|
|
346
419
|
}
|
|
347
420
|
}
|
|
348
421
|
/**
|
|
@@ -368,7 +441,9 @@ export class Executor {
|
|
|
368
441
|
*/
|
|
369
442
|
async *stream(moduleId, inputs, context, versionHint) {
|
|
370
443
|
this._validateModuleId(moduleId);
|
|
371
|
-
|
|
444
|
+
// Issue #66: auto-bind executor (see call() for rationale).
|
|
445
|
+
let ctx = context ?? Context.create();
|
|
446
|
+
ctx = ctx._withExecutor(this);
|
|
372
447
|
const pipeCtx = {
|
|
373
448
|
moduleId,
|
|
374
449
|
inputs: inputs ?? {},
|
|
@@ -393,6 +468,10 @@ export class Executor {
|
|
|
393
468
|
const ctxObj = pipeCtx.context;
|
|
394
469
|
// Unwrap PipelineStepError to expose the original typed cause (§1.1).
|
|
395
470
|
const unwrapped = exc instanceof PipelineStepError ? (exc.cause instanceof Error ? exc.cause : exc) : exc;
|
|
471
|
+
// D-20: a step-wrapped cancellation MUST bypass on_error recovery in
|
|
472
|
+
// stream mode too. Rethrow the unwrapped cancellation before recovery.
|
|
473
|
+
if (unwrapped instanceof ExecutionCancelledError)
|
|
474
|
+
throw unwrapped;
|
|
396
475
|
const wrapped = propagateError(unwrapped, moduleId, ctxObj);
|
|
397
476
|
if (pipeCtx.executedMiddlewares && pipeCtx.executedMiddlewares.length > 0) {
|
|
398
477
|
const recovery = await this._middlewareManager.executeOnError(moduleId, pipeCtx.inputs, wrapped, ctxObj, pipeCtx.executedMiddlewares);
|
|
@@ -421,6 +500,7 @@ export class Executor {
|
|
|
421
500
|
// subsequent `Date.now() / 1000` divisor pretended the value was epoch
|
|
422
501
|
// seconds. (sync finding A-D-202.)
|
|
423
502
|
const globalDeadline = pipeCtx.context?.data?.[CTX_GLOBAL_DEADLINE] ?? null;
|
|
503
|
+
let chunkIndex = 0;
|
|
424
504
|
try {
|
|
425
505
|
for await (const chunk of outputStream) {
|
|
426
506
|
// Enforce global_deadline between chunks — matches apcore-python
|
|
@@ -430,8 +510,26 @@ export class Executor {
|
|
|
430
510
|
if (globalDeadline !== null && Date.now() > globalDeadline) {
|
|
431
511
|
throw new ModuleTimeoutError(moduleId, 0);
|
|
432
512
|
}
|
|
513
|
+
// Enforce stream-chunk shape BEFORE merge and BEFORE yield (D10-001 /
|
|
514
|
+
// apcore-rust deep_merge_chunks_checked, D-58). A non-object chunk is
|
|
515
|
+
// rejected so it is never delivered to the consumer; deep_merge can
|
|
516
|
+
// only accumulate objects. The throw routes through the catch below
|
|
517
|
+
// (propagateError / onError) like other stream errors.
|
|
518
|
+
if (!isPlainObjectChunk(chunk)) {
|
|
519
|
+
const actualType = jsonTypeName(chunk);
|
|
520
|
+
throw new InvalidInputError(`Streaming chunk at index ${chunkIndex} is not a JSON object ` +
|
|
521
|
+
`(got ${actualType}); chunks must be objects so deep_merge can ` +
|
|
522
|
+
`accumulate them.`, {
|
|
523
|
+
details: {
|
|
524
|
+
code: 'STREAM_CHUNK_NOT_OBJECT',
|
|
525
|
+
chunk_index: chunkIndex,
|
|
526
|
+
actual_type: actualType,
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
}
|
|
433
530
|
deepMergeChunk(accumulated, chunk);
|
|
434
531
|
yield chunk;
|
|
532
|
+
chunkIndex += 1;
|
|
435
533
|
}
|
|
436
534
|
}
|
|
437
535
|
catch (exc) {
|
|
@@ -469,13 +567,22 @@ export class Executor {
|
|
|
469
567
|
throw exc;
|
|
470
568
|
// Chunks are already delivered to the caller and cannot be recalled.
|
|
471
569
|
// Swallow the phase-3 error and log a warning — matches apcore-python
|
|
472
|
-
// executor.py
|
|
473
|
-
// and does NOT re-raise (sync finding A-D-012).
|
|
474
|
-
// TODO: emit ApCoreEvent via injected EventEmitter when Executor gains
|
|
475
|
-
// an optional eventEmitter constructor field (pending architectural wiring).
|
|
570
|
+
// executor.py which emits an ApCoreEvent("apcore.stream.post_validation_failed")
|
|
571
|
+
// and does NOT re-raise (sync finding A-D-012 / A-D-006).
|
|
476
572
|
const ctxObj = pipeCtx.context;
|
|
477
573
|
const unwrappedPost = exc instanceof PipelineStepError ? (exc.cause instanceof Error ? exc.cause : exc) : exc;
|
|
478
574
|
const wrapped = propagateError(unwrappedPost, moduleId, ctxObj);
|
|
575
|
+
// A-D-006: when an EventEmitter is wired, emit the post-validation-failed
|
|
576
|
+
// event so observers/trace exporters surface the failure (mirrors
|
|
577
|
+
// apcore-python executor.py:1096).
|
|
578
|
+
if (this._eventEmitter !== null) {
|
|
579
|
+
const cause = unwrappedPost instanceof Error ? unwrappedPost : wrapped;
|
|
580
|
+
this._eventEmitter.emit(createEvent('apcore.stream.post_validation_failed', moduleId, 'error', {
|
|
581
|
+
error_type: cause.constructor?.name ?? 'Error',
|
|
582
|
+
message: cause.message,
|
|
583
|
+
trace_id: ctxObj?.traceId ?? null,
|
|
584
|
+
}));
|
|
585
|
+
}
|
|
479
586
|
// Sync finding A-D-011: phase-3 errors must NOT invoke middleware
|
|
480
587
|
// `on_error` once chunks have already been yielded. The middleware
|
|
481
588
|
// recovery contract is "produce a recovery output before any output is
|
|
@@ -507,11 +614,31 @@ export class Executor {
|
|
|
507
614
|
return createPreflightResult(checks);
|
|
508
615
|
}
|
|
509
616
|
checks.push({ check: 'module_id', passed: true });
|
|
510
|
-
// Run pipeline in dry_run mode — pure=false steps are skipped
|
|
617
|
+
// Run pipeline in dry_run mode — pure=false steps are skipped.
|
|
618
|
+
// Issue #66: auto-bind executor on every entry (see call() for rationale).
|
|
619
|
+
// A-D-014: validate() MUST be non-throwing. A Context already bound to a
|
|
620
|
+
// DIFFERENT executor raises ContextBindingError on bind; surface that as a
|
|
621
|
+
// failed `executor_binding` check rather than letting it escape (mirrors
|
|
622
|
+
// apcore-python executor.py and apcore-rust executor.rs).
|
|
623
|
+
let validateCtx = context ?? Context.create();
|
|
624
|
+
try {
|
|
625
|
+
validateCtx = validateCtx._withExecutor(this);
|
|
626
|
+
}
|
|
627
|
+
catch (e) {
|
|
628
|
+
if (e instanceof ContextBindingError) {
|
|
629
|
+
checks.push({
|
|
630
|
+
check: 'executor_binding',
|
|
631
|
+
passed: false,
|
|
632
|
+
error: { code: e.code, message: e.message },
|
|
633
|
+
});
|
|
634
|
+
return createPreflightResult(checks);
|
|
635
|
+
}
|
|
636
|
+
throw e;
|
|
637
|
+
}
|
|
511
638
|
const pipeCtx = {
|
|
512
639
|
moduleId,
|
|
513
640
|
inputs: effectiveInputs,
|
|
514
|
-
context:
|
|
641
|
+
context: validateCtx,
|
|
515
642
|
module: null,
|
|
516
643
|
validatedInputs: null,
|
|
517
644
|
output: null,
|