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.
Files changed (114) hide show
  1. package/README.md +33 -3
  2. package/dist/acl-handlers.d.ts.map +1 -1
  3. package/dist/acl-handlers.js +5 -0
  4. package/dist/acl-handlers.js.map +1 -1
  5. package/dist/async-task.d.ts +49 -14
  6. package/dist/async-task.d.ts.map +1 -1
  7. package/dist/async-task.js +134 -39
  8. package/dist/async-task.js.map +1 -1
  9. package/dist/bindings.d.ts +1 -1
  10. package/dist/bindings.d.ts.map +1 -1
  11. package/dist/bindings.js +8 -5
  12. package/dist/bindings.js.map +1 -1
  13. package/dist/browser/index.d.ts +2 -2
  14. package/dist/browser/index.d.ts.map +1 -1
  15. package/dist/browser/index.js +2 -2
  16. package/dist/browser/index.js.map +1 -1
  17. package/dist/builtin-steps.d.ts +14 -12
  18. package/dist/builtin-steps.d.ts.map +1 -1
  19. package/dist/builtin-steps.js +81 -28
  20. package/dist/builtin-steps.js.map +1 -1
  21. package/dist/cancel.d.ts +23 -2
  22. package/dist/cancel.d.ts.map +1 -1
  23. package/dist/cancel.js +31 -6
  24. package/dist/cancel.js.map +1 -1
  25. package/dist/client.d.ts +3 -0
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +7 -3
  28. package/dist/client.js.map +1 -1
  29. package/dist/config.d.ts +27 -0
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +33 -1
  32. package/dist/config.js.map +1 -1
  33. package/dist/context.d.ts +36 -3
  34. package/dist/context.d.ts.map +1 -1
  35. package/dist/context.js +94 -11
  36. package/dist/context.js.map +1 -1
  37. package/dist/errors.d.ts +64 -1
  38. package/dist/errors.d.ts.map +1 -1
  39. package/dist/errors.js +101 -7
  40. package/dist/errors.js.map +1 -1
  41. package/dist/events/emitter.d.ts +46 -12
  42. package/dist/events/emitter.d.ts.map +1 -1
  43. package/dist/events/emitter.js +146 -56
  44. package/dist/events/emitter.js.map +1 -1
  45. package/dist/events/index.d.ts +2 -1
  46. package/dist/events/index.d.ts.map +1 -1
  47. package/dist/events/index.js +1 -1
  48. package/dist/events/index.js.map +1 -1
  49. package/dist/events/retry.d.ts +35 -0
  50. package/dist/events/retry.d.ts.map +1 -0
  51. package/dist/events/retry.js +52 -0
  52. package/dist/events/retry.js.map +1 -0
  53. package/dist/events/subscribers.d.ts +52 -9
  54. package/dist/events/subscribers.d.ts.map +1 -1
  55. package/dist/events/subscribers.js +96 -63
  56. package/dist/events/subscribers.js.map +1 -1
  57. package/dist/executor.d.ts +4 -1
  58. package/dist/executor.d.ts.map +1 -1
  59. package/dist/executor.js +143 -16
  60. package/dist/executor.js.map +1 -1
  61. package/dist/generated/version.d.ts +1 -1
  62. package/dist/generated/version.js +1 -1
  63. package/dist/index.d.ts +7 -5
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +6 -4
  66. package/dist/index.js.map +1 -1
  67. package/dist/middleware/circuit-breaker.d.ts +2 -2
  68. package/dist/middleware/circuit-breaker.d.ts.map +1 -1
  69. package/dist/middleware/circuit-breaker.js +19 -19
  70. package/dist/middleware/circuit-breaker.js.map +1 -1
  71. package/dist/middleware/index.d.ts +1 -1
  72. package/dist/middleware/index.d.ts.map +1 -1
  73. package/dist/middleware/index.js +1 -1
  74. package/dist/middleware/index.js.map +1 -1
  75. package/dist/middleware/manager.d.ts +6 -2
  76. package/dist/middleware/manager.d.ts.map +1 -1
  77. package/dist/middleware/manager.js +36 -1
  78. package/dist/middleware/manager.js.map +1 -1
  79. package/dist/middleware/platform-notify.d.ts +2 -3
  80. package/dist/middleware/platform-notify.d.ts.map +1 -1
  81. package/dist/middleware/platform-notify.js +5 -6
  82. package/dist/middleware/platform-notify.js.map +1 -1
  83. package/dist/pipeline.d.ts +1 -1
  84. package/dist/pipeline.js +11 -11
  85. package/dist/pipeline.js.map +1 -1
  86. package/dist/registry/registry.d.ts +46 -2
  87. package/dist/registry/registry.d.ts.map +1 -1
  88. package/dist/registry/registry.js +271 -31
  89. package/dist/registry/registry.js.map +1 -1
  90. package/dist/schema/ref-resolver.d.ts.map +1 -1
  91. package/dist/schema/ref-resolver.js +2 -2
  92. package/dist/schema/ref-resolver.js.map +1 -1
  93. package/dist/schema/types.d.ts.map +1 -1
  94. package/dist/schema/types.js +1 -1
  95. package/dist/schema/types.js.map +1 -1
  96. package/dist/schema/validator.d.ts.map +1 -1
  97. package/dist/schema/validator.js +11 -20
  98. package/dist/schema/validator.js.map +1 -1
  99. package/dist/streaming.d.ts +21 -0
  100. package/dist/streaming.d.ts.map +1 -0
  101. package/dist/streaming.js +32 -0
  102. package/dist/streaming.js.map +1 -0
  103. package/dist/sys-modules/registration.d.ts.map +1 -1
  104. package/dist/sys-modules/registration.js +18 -8
  105. package/dist/sys-modules/registration.js.map +1 -1
  106. package/package.json +6 -3
  107. package/dist/registry/index.d.ts +0 -15
  108. package/dist/registry/index.d.ts.map +0 -1
  109. package/dist/registry/index.js +0 -11
  110. package/dist/registry/index.js.map +0 -1
  111. package/dist/schema/index.d.ts +0 -11
  112. package/dist/schema/index.d.ts.map +0 -1
  113. package/dist/schema/index.js +0 -9
  114. package/dist/schema/index.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  /**
2
- * Global event bus with fan-out delivery and subscriber error isolation.
2
+ * Global event bus with fan-out delivery, per-subscriber retry, and DLQ.
3
3
  */
4
+ import { resolveRetry, computeDelayMs, fnmatch } from './retry.js';
4
5
  export function createEvent(eventType, moduleId, severity, data) {
5
6
  return {
6
7
  eventType,
@@ -10,35 +11,26 @@ export function createEvent(eventType, moduleId, severity, data) {
10
11
  data,
11
12
  };
12
13
  }
13
- /**
14
- * Emit a canonical event AND a legacy alias for the same event during the
15
- * deprecation window. The legacy event payload is augmented with
16
- * `deprecated: true` and `canonical_event: <canonicalType>` so subscribers
17
- * still listening to the legacy name can migrate.
18
- *
19
- * The two emissions share an identical timestamp so they appear atomic to
20
- * downstream consumers ordering by `timestamp`.
21
- */
22
- export function emitWithLegacy(emitter, canonicalType, legacyType, moduleId, severity, data) {
23
- const timestamp = new Date().toISOString();
24
- emitter.emit({ eventType: canonicalType, moduleId, timestamp, severity, data });
25
- emitter.emit({
26
- eventType: legacyType,
27
- moduleId,
28
- timestamp,
29
- severity,
30
- data: { ...data, deprecated: true, canonical_event: canonicalType },
31
- });
14
+ function sleep(ms) {
15
+ return new Promise((resolve) => setTimeout(resolve, ms));
32
16
  }
33
17
  const DEFAULT_MAX_PENDING = 1000;
34
18
  /**
35
- * Global event bus with non-blocking fan-out delivery.
36
- * Errors in one subscriber do not affect others.
19
+ * Global event bus with fan-out delivery, per-subscriber retry, and DLQ.
20
+ *
21
+ * Key behaviors:
22
+ * - All subscribers get exponential-backoff retries up to `maxAttempts`. A subscriber
23
+ * that omits `retry` receives the spec default policy (max_attempts=3); one that sets
24
+ * `maxAttempts: 1` disables retry (single attempt).
25
+ * - After retry exhaustion: DLQ event + optional `onFailure` callback.
26
+ * - `eventPattern` (glob) filters which events a subscriber receives.
27
+ * - `flush()` drains all in-flight async deliveries.
37
28
  */
38
29
  export class EventEmitter {
39
30
  _subscribers = [];
40
31
  _pending = [];
41
32
  _maxPending;
33
+ _shutdown = false;
42
34
  constructor(maxPending = DEFAULT_MAX_PENDING) {
43
35
  this._maxPending = maxPending;
44
36
  }
@@ -51,34 +43,119 @@ export class EventEmitter {
51
43
  this._subscribers.splice(idx, 1);
52
44
  }
53
45
  }
46
+ /**
47
+ * Stop accepting new emits. After shutdown, {@link emit} is a no-op (A-D-028,
48
+ * cross-SDK canonical with Python/Rust which drop post-shutdown emits). Drains
49
+ * any in-flight deliveries via {@link flush}.
50
+ */
51
+ async shutdown(timeoutMs = 5000) {
52
+ if (this._shutdown)
53
+ return;
54
+ this._shutdown = true;
55
+ await this.flush(timeoutMs);
56
+ }
54
57
  emit(event) {
55
- const snapshot = [...this._subscribers];
58
+ // A-D-028: silently drop emits after shutdown.
59
+ if (this._shutdown)
60
+ return;
61
+ const snapshot = this._getMatchingSubscribers(event.eventType);
56
62
  for (const subscriber of snapshot) {
63
+ // Every subscriber — built-in and user-registered, with or without an explicit
64
+ // `retry` block — goes through the unified retry/backoff/DLQ delivery path.
65
+ // A subscriber that omits `retry` receives the spec default policy
66
+ // (max_attempts=3); one that explicitly sets maxAttempts:1 disables retry.
67
+ // (event-system.md §Per-Subscriber Retry Policy; sync finding A-D-005)
68
+ const deliveryPromise = this._deliver(subscriber, event);
69
+ if (this._pending.length >= this._maxPending) {
70
+ console.warn(`[apcore:events] _pending cap (${this._maxPending}) reached — dropping async delivery for event ${event.eventType}`);
71
+ this._dispatchDroppedEvent(subscriber, event);
72
+ }
73
+ else {
74
+ const tracked = deliveryPromise.catch(() => {
75
+ // errors handled inside _deliver
76
+ });
77
+ this._pending.push(tracked);
78
+ tracked.then(() => {
79
+ const idx = this._pending.indexOf(tracked);
80
+ if (idx !== -1)
81
+ this._pending.splice(idx, 1);
82
+ });
83
+ }
84
+ }
85
+ }
86
+ _getMatchingSubscribers(eventType, isDlq = false) {
87
+ return this._subscribers.filter((sub) => {
88
+ // A-D-026: DLQ events (apcore.event.delivery_failed) are delivered ONLY
89
+ // to subscribers with an explicit, non-wildcard pattern. Catch-all
90
+ // subscribers (no pattern, or pattern '*') never receive DLQ events —
91
+ // this prevents cascading failures where a catch-all subscriber would
92
+ // recursively fail on the DLQ event about its own delivery failure.
93
+ const pattern = sub.eventPattern ?? '*';
94
+ if (isDlq && pattern === '*')
95
+ return false;
96
+ return fnmatch(eventType, pattern);
97
+ });
98
+ }
99
+ async _deliver(subscriber, event) {
100
+ const retry = resolveRetry(subscriber.retry);
101
+ let lastError = new Error('Unknown error');
102
+ for (let attempt = 0; attempt < retry.maxAttempts; attempt++) {
103
+ try {
104
+ await subscriber.onEvent(event);
105
+ return;
106
+ }
107
+ catch (e) {
108
+ lastError = e instanceof Error ? e : new Error(String(e));
109
+ if (attempt + 1 < retry.maxAttempts) {
110
+ await sleep(computeDelayMs(retry, attempt));
111
+ }
112
+ }
113
+ }
114
+ // All attempts exhausted — emit DLQ event and invoke onFailure callback
115
+ await this._emitDLQ(subscriber, event, lastError, retry.maxAttempts);
116
+ if (subscriber.onFailure) {
117
+ try {
118
+ await subscriber.onFailure(event, lastError, retry.maxAttempts);
119
+ }
120
+ catch (cbError) {
121
+ console.error('[apcore:events] onFailure callback raised:', cbError);
122
+ }
123
+ }
124
+ }
125
+ async _emitDLQ(subscriber, originalEvent, error, attemptCount) {
126
+ // A-D-029: prefer the declared `subscriberType` field; fall back to the
127
+ // constructor-name derivation only when it is absent.
128
+ const subscriberType = typeof subscriber.subscriberType === 'string'
129
+ ? subscriber.subscriberType
130
+ : (subscriber.constructor?.name ?? 'unknown')
131
+ .replace('Subscriber', '')
132
+ .toLowerCase();
133
+ const subscriberId = subscriber.subscriberId ?? this._identifySubscriber(subscriber);
134
+ const dlqEvent = createEvent('apcore.event.delivery_failed', null, 'error', {
135
+ subscriber_type: subscriberType,
136
+ subscriber_id: subscriberId,
137
+ original_event: {
138
+ name: originalEvent.eventType,
139
+ module_id: originalEvent.moduleId,
140
+ timestamp: originalEvent.timestamp,
141
+ payload: originalEvent.data,
142
+ },
143
+ error: { type: error.constructor?.name ?? 'Error', message: error.message },
144
+ attempt_count: attemptCount,
145
+ timestamp: new Date().toISOString(),
146
+ });
147
+ // Deliver DLQ event with NO retry — single attempt only; DLQ subscriber errors are logged.
148
+ // isDlq=true excludes catch-all ('*'/no-pattern) subscribers (A-D-026).
149
+ const dlqSubscribers = this._getMatchingSubscribers(dlqEvent.eventType, true);
150
+ for (const dlqSub of dlqSubscribers) {
57
151
  try {
58
- const result = subscriber.onEvent(event);
59
- if (result instanceof Promise) {
60
- if (this._pending.length >= this._maxPending) {
61
- // Overflow: instead of silently dropping, emit a structured event
62
- // so observers can track delivery loss. (sync finding A-D-504)
63
- console.warn(`[apcore:events] _pending cap (${this._maxPending}) reached — dropping async delivery for event ${event.eventType}`);
64
- this._dispatchDroppedEvent(subscriber, event);
65
- }
66
- else {
67
- const tracked = result.catch((err) => {
68
- console.warn(`[apcore:events] Subscriber failed handling event ${event.eventType}:`, err);
69
- });
70
- this._pending.push(tracked);
71
- // Auto-cleanup when resolved to prevent unbounded growth
72
- tracked.then(() => {
73
- const idx = this._pending.indexOf(tracked);
74
- if (idx !== -1)
75
- this._pending.splice(idx, 1);
76
- });
77
- }
152
+ const r = dlqSub.onEvent(dlqEvent);
153
+ if (r instanceof Promise) {
154
+ await r;
78
155
  }
79
156
  }
80
- catch (err) {
81
- console.warn(`[apcore:events] Subscriber failed handling event ${event.eventType}:`, err);
157
+ catch (dlqErr) {
158
+ console.error('[apcore:events] DLQ subscriber raised:', dlqErr);
82
159
  }
83
160
  }
84
161
  }
@@ -95,7 +172,7 @@ export class EventEmitter {
95
172
  });
96
173
  for (const sub of this._subscribers) {
97
174
  if (sub === droppedFor)
98
- continue; // avoid recursive drop on the same sink
175
+ continue;
99
176
  try {
100
177
  const r = sub.onEvent(droppedEvent);
101
178
  // Intentionally do not track this Promise in _pending — at-cap by design.
@@ -103,20 +180,21 @@ export class EventEmitter {
103
180
  // rejections don't escape.
104
181
  if (r instanceof Promise) {
105
182
  r.catch((err) => {
106
- console.warn(`[apcore:events] Subscriber failed handling delivery_dropped:`, err);
183
+ console.warn('[apcore:events] Subscriber failed handling delivery_dropped:', err);
107
184
  });
108
185
  }
109
186
  }
110
187
  catch (err) {
111
- console.warn(`[apcore:events] Subscriber failed handling delivery_dropped:`, err);
188
+ console.warn('[apcore:events] Subscriber failed handling delivery_dropped:', err);
112
189
  }
113
190
  }
114
191
  }
115
192
  _identifySubscriber(sub) {
193
+ if (sub.subscriberId)
194
+ return sub.subscriberId;
116
195
  const ctorName = sub.constructor?.name;
117
196
  if (ctorName && ctorName !== 'Object')
118
197
  return ctorName;
119
- // Fall back to a stable hash-ish string based on identity.
120
198
  return `subscriber@${this._subscribers.indexOf(sub)}`;
121
199
  }
122
200
  /**
@@ -128,13 +206,25 @@ export class EventEmitter {
128
206
  * (sync finding A-D-503)
129
207
  */
130
208
  async flush(timeoutMs = 5000) {
131
- const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : Infinity;
132
- while (this._pending.length > 0) {
133
- if (Date.now() >= deadline)
134
- return;
135
- const pending = [...this._pending];
136
- this._pending = [];
137
- await Promise.allSettled(pending);
209
+ // A-D-027: per-pending semantics (Python canonical) each pending delivery
210
+ // gets up to `timeoutMs` to settle, rather than sharing one total deadline.
211
+ // A delivery that exceeds its budget is abandoned (the next call to flush
212
+ // can re-await any that are still tracked).
213
+ const pending = [...this._pending];
214
+ this._pending = [];
215
+ for (const p of pending) {
216
+ if (timeoutMs > 0) {
217
+ let timer;
218
+ const timeout = new Promise((resolve) => {
219
+ timer = setTimeout(resolve, timeoutMs);
220
+ });
221
+ await Promise.race([p.catch(() => { }), timeout]);
222
+ if (timer !== undefined)
223
+ clearTimeout(timer);
224
+ }
225
+ else {
226
+ await p.catch(() => { });
227
+ }
138
228
  }
139
229
  }
140
230
  }
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/events/emitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/events/emitter.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
- export { EventEmitter, createEvent, emitWithLegacy } from './emitter.js';
1
+ export { EventEmitter, createEvent } from './emitter.js';
2
2
  export type { ApCoreEvent, EventSubscriber } from './emitter.js';
3
3
  export { WebhookSubscriber, A2ASubscriber, FileSubscriber, StdoutSubscriber, FilterSubscriber } from './subscribers.js';
4
4
  export { CircuitBreakerWrapper, CircuitState } from './circuit-breaker.js';
5
5
  export type { CircuitBreakerConfig } from './circuit-breaker.js';
6
+ export type { RetryConfig } from './retry.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- export { EventEmitter, createEvent, emitWithLegacy } from './emitter.js';
1
+ export { EventEmitter, createEvent } from './emitter.js';
2
2
  export { WebhookSubscriber, A2ASubscriber, FileSubscriber, StdoutSubscriber, FilterSubscriber } from './subscribers.js';
3
3
  export { CircuitBreakerWrapper, CircuitState } from './circuit-breaker.js';
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxH,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Retry configuration types and helpers for event delivery.
3
+ */
4
+ export interface RetryConfig {
5
+ maxAttempts?: number;
6
+ initialBackoffMs?: number;
7
+ maxBackoffMs?: number;
8
+ backoffMultiplier?: number;
9
+ }
10
+ export interface ResolvedRetryConfig {
11
+ maxAttempts: number;
12
+ initialBackoffMs: number;
13
+ maxBackoffMs: number;
14
+ backoffMultiplier: number;
15
+ }
16
+ /**
17
+ * Spec default retry policy (event-system.md §Per-Subscriber Retry Policy).
18
+ * Applied when a subscriber omits the `retry` block entirely, and as the base
19
+ * for merging when individual fields are omitted. `max_attempts` default is 3 —
20
+ * uniform across Python/TypeScript/Rust SDKs.
21
+ */
22
+ export declare const DEFAULT_RETRY: ResolvedRetryConfig;
23
+ /**
24
+ * Merge caller-supplied retry config with the spec defaults.
25
+ * A subscriber that does NOT supply `retry` receives the full DEFAULT_RETRY
26
+ * policy (max_attempts=3), per event-system.md §Per-Subscriber Retry Policy —
27
+ * built-in and user-registered subscribers share the same default. A subscriber
28
+ * that explicitly sets `maxAttempts: 1` disables retry (single attempt).
29
+ */
30
+ export declare function resolveRetry(config?: RetryConfig): ResolvedRetryConfig;
31
+ /** Glob pattern matching supporting * (any chars) and ? (single char). Cached per pattern. */
32
+ export declare function fnmatch(text: string, pattern: string): boolean;
33
+ /** Exponential-backoff delay for attempt `attempt` (0-based, clamped to ≥ 0). */
34
+ export declare function computeDelayMs(cfg: ResolvedRetryConfig, attempt: number): number;
35
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/events/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,mBAK3B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAKtE;AAID,8FAA8F;AAC9F,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAc9D;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKhF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Retry configuration types and helpers for event delivery.
3
+ */
4
+ /**
5
+ * Spec default retry policy (event-system.md §Per-Subscriber Retry Policy).
6
+ * Applied when a subscriber omits the `retry` block entirely, and as the base
7
+ * for merging when individual fields are omitted. `max_attempts` default is 3 —
8
+ * uniform across Python/TypeScript/Rust SDKs.
9
+ */
10
+ export const DEFAULT_RETRY = {
11
+ maxAttempts: 3,
12
+ initialBackoffMs: 100,
13
+ maxBackoffMs: 30_000,
14
+ backoffMultiplier: 2.0,
15
+ };
16
+ /**
17
+ * Merge caller-supplied retry config with the spec defaults.
18
+ * A subscriber that does NOT supply `retry` receives the full DEFAULT_RETRY
19
+ * policy (max_attempts=3), per event-system.md §Per-Subscriber Retry Policy —
20
+ * built-in and user-registered subscribers share the same default. A subscriber
21
+ * that explicitly sets `maxAttempts: 1` disables retry (single attempt).
22
+ */
23
+ export function resolveRetry(config) {
24
+ if (config === undefined) {
25
+ return { ...DEFAULT_RETRY };
26
+ }
27
+ return { ...DEFAULT_RETRY, ...config };
28
+ }
29
+ const _patternCache = new Map();
30
+ /** Glob pattern matching supporting * (any chars) and ? (single char). Cached per pattern. */
31
+ export function fnmatch(text, pattern) {
32
+ let regex = _patternCache.get(pattern);
33
+ if (regex === undefined) {
34
+ const regexStr = Array.from(pattern)
35
+ .map((c) => {
36
+ if (c === '*')
37
+ return '.*';
38
+ if (c === '?')
39
+ return '.';
40
+ return c.replace(/[$()*+.?[\]^{|}-]/g, '\\$&');
41
+ })
42
+ .join('');
43
+ regex = new RegExp(`^${regexStr}$`);
44
+ _patternCache.set(pattern, regex);
45
+ }
46
+ return regex.test(text);
47
+ }
48
+ /** Exponential-backoff delay for attempt `attempt` (0-based, clamped to ≥ 0). */
49
+ export function computeDelayMs(cfg, attempt) {
50
+ return Math.min(cfg.maxBackoffMs, Math.floor(cfg.initialBackoffMs * Math.pow(cfg.backoffMultiplier, Math.max(0, attempt))));
51
+ }
52
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/events/retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAwB;IAChD,WAAW,EAAE,CAAC;IACd,gBAAgB,EAAE,GAAG;IACrB,YAAY,EAAE,MAAM;IACpB,iBAAiB,EAAE,GAAG;CACvB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB;IAC/C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,GAAG,aAAa,EAAE,GAAG,MAAM,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEhD,8FAA8F;AAC9F,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe;IACnD,IAAI,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;aACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG;gBAAE,OAAO,GAAG,CAAC;YAC1B,OAAO,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CAAC;QACZ,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC;QACpC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,GAAwB,EAAE,OAAe;IACtE,OAAO,IAAI,CAAC,GAAG,CACb,GAAG,CAAC,YAAY,EAChB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CACzF,CAAC;AACJ,CAAC"}
@@ -2,47 +2,81 @@
2
2
  * Event subscribers for webhook, A2A, file, stdout, and filter delivery.
3
3
  */
4
4
  import type { ApCoreEvent, EventSubscriber } from './emitter.js';
5
+ import type { RetryConfig } from './retry.js';
5
6
  /**
6
7
  * Delivers events via HTTP POST to a webhook URL.
7
8
  *
8
- * Retries on 5xx and connection errors up to `retryCount` times.
9
- * Does not retry on 4xx responses. Enforces `timeoutMs`.
9
+ * Retries on 5xx and connection errors. As of v0.22.0 finding A-D-EVT-001,
10
+ * the retry policy is unified across event subscribers: the subscriber MUST
11
+ * NOT loop internally. Instead, it rethrows on 5xx / network errors and the
12
+ * outer `EventEmitter._deliver` applies the spec retry policy declared via
13
+ * the `retry` field (defaults to `DEFAULT_RETRY` — 3 attempts, 100 ms initial
14
+ * backoff, 2× multiplier, 30 s cap). 4xx responses are treated as
15
+ * non-retryable: a warning is logged and the call returns normally.
10
16
  */
11
17
  export declare class WebhookSubscriber implements EventSubscriber {
18
+ /** Declared subscriber kind for DLQ payloads (A-D-029). */
19
+ readonly subscriberType = "webhook";
20
+ readonly subscriberId: string;
21
+ readonly retry: RetryConfig;
12
22
  private readonly _url;
13
23
  private readonly _headers;
14
- private readonly _retryCount;
15
24
  private readonly _timeoutMs;
16
- constructor(url: string, headers?: Record<string, string>, retryCount?: number, timeoutMs?: number);
25
+ constructor(url: string, headers?: Record<string, string>, timeoutMsOrOpts?: number | {
26
+ timeoutMs?: number;
27
+ retry?: RetryConfig;
28
+ id?: string;
29
+ }, id?: string);
17
30
  onEvent(event: ApCoreEvent): Promise<void>;
18
31
  }
19
32
  /**
20
33
  * Delivers events via the A2A protocol to the platform.
21
34
  *
22
35
  * Sends a POST with `skillId="apevo.event_receiver"` and the
23
- * serialized event in the payload. Failures are logged, not raised.
36
+ * serialized event in the payload. As of v0.22.0 finding A-D-EVT-001 the
37
+ * subscriber no longer silently swallows errors: it rethrows on any
38
+ * status >=400 or network error so the unified `EventEmitter._deliver`
39
+ * retry policy applies (defaults to `DEFAULT_RETRY` — 3 attempts, 100 ms
40
+ * initial backoff, 2× multiplier, 30 s cap). After exhaustion the
41
+ * EventEmitter routes the failure through the DLQ + `onFailure` path.
24
42
  */
25
43
  export declare class A2ASubscriber implements EventSubscriber {
44
+ /** Declared subscriber kind for DLQ payloads (A-D-029). */
45
+ readonly subscriberType = "a2a";
46
+ readonly subscriberId: string;
47
+ readonly retry: RetryConfig;
26
48
  private readonly _platformUrl;
27
49
  private readonly _auth;
28
50
  private readonly _timeoutMs;
29
- constructor(platformUrl: string, auth?: string | Record<string, string | unknown>, timeoutMs?: number);
51
+ private readonly _skillId;
52
+ constructor(platformUrl: string, auth?: string | Record<string, string | unknown>, timeoutMsOrOpts?: number | {
53
+ timeoutMs?: number;
54
+ retry?: RetryConfig;
55
+ id?: string;
56
+ skillId?: string;
57
+ }, id?: string, skillId?: string);
30
58
  onEvent(event: ApCoreEvent): Promise<void>;
31
59
  }
32
60
  /** Writes events to a local file (built-in type: 'file'). */
33
61
  export declare class FileSubscriber implements EventSubscriber {
62
+ /** Declared subscriber kind for DLQ payloads (A-D-029). */
63
+ readonly subscriberType = "file";
64
+ readonly subscriberId: string;
34
65
  private readonly _path;
35
66
  private readonly _append;
36
67
  private readonly _format;
37
68
  private readonly _rotateBytes;
38
- constructor(path: string, append?: boolean, format?: string, rotateBytes?: number);
69
+ constructor(path: string, append?: boolean, format?: string, rotateBytes?: number, id?: string);
39
70
  onEvent(event: ApCoreEvent): Promise<void>;
40
71
  }
41
72
  /** Writes events to stdout (built-in type: 'stdout'). */
42
73
  export declare class StdoutSubscriber implements EventSubscriber {
74
+ /** Declared subscriber kind for DLQ payloads (A-D-029). */
75
+ readonly subscriberType = "stdout";
76
+ readonly subscriberId: string;
43
77
  private readonly _format;
44
78
  private readonly _levelFilter;
45
- constructor(format?: string, levelFilter?: string);
79
+ constructor(format?: string, levelFilter?: string, id?: string);
46
80
  onEvent(event: ApCoreEvent): Promise<void>;
47
81
  }
48
82
  /**
@@ -54,10 +88,19 @@ export declare class StdoutSubscriber implements EventSubscriber {
54
88
  * 3. If neither is set, forward all events.
55
89
  */
56
90
  export declare class FilterSubscriber implements EventSubscriber {
91
+ /** Declared subscriber kind for DLQ payloads (A-D-029). */
92
+ readonly subscriberType = "filter";
93
+ /** Stable identity for DLQ payloads and dedup (A-D-022). */
94
+ readonly subscriberId: string;
95
+ /** Retry policy applied by EventEmitter._deliver (A-D-022). */
96
+ readonly retry: RetryConfig;
57
97
  private readonly _delegate;
58
98
  private readonly _includeEvents;
59
99
  private readonly _excludeEvents;
60
- constructor(delegate: EventSubscriber, includeEvents?: string[], excludeEvents?: string[]);
100
+ constructor(delegate: EventSubscriber, includeEvents?: string[], excludeEvents?: string[], opts?: {
101
+ id?: string;
102
+ retry?: RetryConfig;
103
+ });
61
104
  onEvent(event: ApCoreEvent): Promise<void>;
62
105
  private _matches;
63
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../src/events/subscribers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAsBjE;;;;;GAKG;AACH,qBAAa,iBAAkB,YAAW,eAAe;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGlC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAa;IAQpB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CA+DjD;AAED;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAGlC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EAChD,SAAS,GAAE,MAAa;IAOpB,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAwDjD;AAED,6DAA6D;AAC7D,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;gBAEjC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,OAAc,EAAE,MAAM,GAAE,MAAe,EAAE,WAAW,CAAC,EAAE,MAAM;IAOzF,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAiCjD;AAED,yDAAyD;AACzD,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;gBAEjC,MAAM,GAAE,MAAe,EAAE,WAAW,CAAC,EAAE,MAAM;IAUnD,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAoBjD;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkB;gBAErC,QAAQ,EAAE,eAAe,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE;IAMnF,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,OAAO,CAAC,QAAQ;CASjB"}
1
+ {"version":3,"file":"subscribers.d.ts","sourceRoot":"","sources":["../../src/events/subscribers.ts"],"names":[],"mappings":"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"}