@sensigo/realm 0.1.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 (222) hide show
  1. package/README.md +150 -0
  2. package/dist/adapters/adapter-utils.d.ts +14 -0
  3. package/dist/adapters/adapter-utils.d.ts.map +1 -0
  4. package/dist/adapters/adapter-utils.js +18 -0
  5. package/dist/adapters/adapter-utils.js.map +1 -0
  6. package/dist/adapters/airtable-adapter.d.ts +51 -0
  7. package/dist/adapters/airtable-adapter.d.ts.map +1 -0
  8. package/dist/adapters/airtable-adapter.js +425 -0
  9. package/dist/adapters/airtable-adapter.js.map +1 -0
  10. package/dist/adapters/file-adapter.d.ts +14 -0
  11. package/dist/adapters/file-adapter.d.ts.map +1 -0
  12. package/dist/adapters/file-adapter.js +89 -0
  13. package/dist/adapters/file-adapter.js.map +1 -0
  14. package/dist/adapters/github-adapter.d.ts +40 -0
  15. package/dist/adapters/github-adapter.d.ts.map +1 -0
  16. package/dist/adapters/github-adapter.js +286 -0
  17. package/dist/adapters/github-adapter.js.map +1 -0
  18. package/dist/adapters/gorgias-adapter.d.ts +40 -0
  19. package/dist/adapters/gorgias-adapter.d.ts.map +1 -0
  20. package/dist/adapters/gorgias-adapter.js +300 -0
  21. package/dist/adapters/gorgias-adapter.js.map +1 -0
  22. package/dist/adapters/http-adapter.d.ts +28 -0
  23. package/dist/adapters/http-adapter.d.ts.map +1 -0
  24. package/dist/adapters/http-adapter.js +97 -0
  25. package/dist/adapters/http-adapter.js.map +1 -0
  26. package/dist/adapters/mock-adapter.d.ts +16 -0
  27. package/dist/adapters/mock-adapter.d.ts.map +1 -0
  28. package/dist/adapters/mock-adapter.js +61 -0
  29. package/dist/adapters/mock-adapter.js.map +1 -0
  30. package/dist/adapters/notion-adapter.d.ts +54 -0
  31. package/dist/adapters/notion-adapter.d.ts.map +1 -0
  32. package/dist/adapters/notion-adapter.js +751 -0
  33. package/dist/adapters/notion-adapter.js.map +1 -0
  34. package/dist/adapters/parcelpanel-adapter.d.ts +60 -0
  35. package/dist/adapters/parcelpanel-adapter.d.ts.map +1 -0
  36. package/dist/adapters/parcelpanel-adapter.js +251 -0
  37. package/dist/adapters/parcelpanel-adapter.js.map +1 -0
  38. package/dist/adapters/rate-limiter.d.ts +26 -0
  39. package/dist/adapters/rate-limiter.d.ts.map +1 -0
  40. package/dist/adapters/rate-limiter.js +3 -0
  41. package/dist/adapters/rate-limiter.js.map +1 -0
  42. package/dist/adapters/shopify-adapter.d.ts +92 -0
  43. package/dist/adapters/shopify-adapter.d.ts.map +1 -0
  44. package/dist/adapters/shopify-adapter.js +415 -0
  45. package/dist/adapters/shopify-adapter.js.map +1 -0
  46. package/dist/adapters/slack-adapter.d.ts +18 -0
  47. package/dist/adapters/slack-adapter.d.ts.map +1 -0
  48. package/dist/adapters/slack-adapter.js +81 -0
  49. package/dist/adapters/slack-adapter.js.map +1 -0
  50. package/dist/adapters/token-bucket.d.ts +27 -0
  51. package/dist/adapters/token-bucket.d.ts.map +1 -0
  52. package/dist/adapters/token-bucket.js +109 -0
  53. package/dist/adapters/token-bucket.js.map +1 -0
  54. package/dist/config/secrets.d.ts +15 -0
  55. package/dist/config/secrets.d.ts.map +1 -0
  56. package/dist/config/secrets.js +33 -0
  57. package/dist/config/secrets.js.map +1 -0
  58. package/dist/engine/eligibility.d.ts +50 -0
  59. package/dist/engine/eligibility.d.ts.map +1 -0
  60. package/dist/engine/eligibility.js +267 -0
  61. package/dist/engine/eligibility.js.map +1 -0
  62. package/dist/engine/error-resolution.d.ts +20 -0
  63. package/dist/engine/error-resolution.d.ts.map +1 -0
  64. package/dist/engine/error-resolution.js +32 -0
  65. package/dist/engine/error-resolution.js.map +1 -0
  66. package/dist/engine/execution-loop.d.ts +101 -0
  67. package/dist/engine/execution-loop.d.ts.map +1 -0
  68. package/dist/engine/execution-loop.js +1156 -0
  69. package/dist/engine/execution-loop.js.map +1 -0
  70. package/dist/engine/lifecycle.d.ts +14 -0
  71. package/dist/engine/lifecycle.d.ts.map +1 -0
  72. package/dist/engine/lifecycle.js +17 -0
  73. package/dist/engine/lifecycle.js.map +1 -0
  74. package/dist/engine/precondition.d.ts +30 -0
  75. package/dist/engine/precondition.d.ts.map +1 -0
  76. package/dist/engine/precondition.js +125 -0
  77. package/dist/engine/precondition.js.map +1 -0
  78. package/dist/engine/prompt-template.d.ts +25 -0
  79. package/dist/engine/prompt-template.d.ts.map +1 -0
  80. package/dist/engine/prompt-template.js +66 -0
  81. package/dist/engine/prompt-template.js.map +1 -0
  82. package/dist/engine/render-template.d.ts +52 -0
  83. package/dist/engine/render-template.d.ts.map +1 -0
  84. package/dist/engine/render-template.js +548 -0
  85. package/dist/engine/render-template.js.map +1 -0
  86. package/dist/engine/state-guard.d.ts +15 -0
  87. package/dist/engine/state-guard.d.ts.map +1 -0
  88. package/dist/engine/state-guard.js +40 -0
  89. package/dist/engine/state-guard.js.map +1 -0
  90. package/dist/engine/trace-normalizer.d.ts +36 -0
  91. package/dist/engine/trace-normalizer.d.ts.map +1 -0
  92. package/dist/engine/trace-normalizer.js +146 -0
  93. package/dist/engine/trace-normalizer.js.map +1 -0
  94. package/dist/engine/trace-policy.d.ts +53 -0
  95. package/dist/engine/trace-policy.d.ts.map +1 -0
  96. package/dist/engine/trace-policy.js +35 -0
  97. package/dist/engine/trace-policy.js.map +1 -0
  98. package/dist/engine/workflow-context-loader.d.ts +9 -0
  99. package/dist/engine/workflow-context-loader.d.ts.map +1 -0
  100. package/dist/engine/workflow-context-loader.js +41 -0
  101. package/dist/engine/workflow-context-loader.js.map +1 -0
  102. package/dist/evidence/snapshot.d.ts +38 -0
  103. package/dist/evidence/snapshot.d.ts.map +1 -0
  104. package/dist/evidence/snapshot.js +53 -0
  105. package/dist/evidence/snapshot.js.map +1 -0
  106. package/dist/extensions/default-registry.d.ts +19 -0
  107. package/dist/extensions/default-registry.d.ts.map +1 -0
  108. package/dist/extensions/default-registry.js +31 -0
  109. package/dist/extensions/default-registry.js.map +1 -0
  110. package/dist/extensions/processor.d.ts +13 -0
  111. package/dist/extensions/processor.d.ts.map +1 -0
  112. package/dist/extensions/processor.js +3 -0
  113. package/dist/extensions/processor.js.map +1 -0
  114. package/dist/extensions/registry.d.ts +25 -0
  115. package/dist/extensions/registry.d.ts.map +1 -0
  116. package/dist/extensions/registry.js +43 -0
  117. package/dist/extensions/registry.js.map +1 -0
  118. package/dist/extensions/service-adapter.d.ts +35 -0
  119. package/dist/extensions/service-adapter.d.ts.map +1 -0
  120. package/dist/extensions/service-adapter.js +3 -0
  121. package/dist/extensions/service-adapter.js.map +1 -0
  122. package/dist/extensions/step-handler.d.ts +28 -0
  123. package/dist/extensions/step-handler.d.ts.map +1 -0
  124. package/dist/extensions/step-handler.js +3 -0
  125. package/dist/extensions/step-handler.js.map +1 -0
  126. package/dist/handlers/primitives/compare-strings.d.ts +13 -0
  127. package/dist/handlers/primitives/compare-strings.d.ts.map +1 -0
  128. package/dist/handlers/primitives/compare-strings.js +28 -0
  129. package/dist/handlers/primitives/compare-strings.js.map +1 -0
  130. package/dist/handlers/primitives/count-results.d.ts +21 -0
  131. package/dist/handlers/primitives/count-results.d.ts.map +1 -0
  132. package/dist/handlers/primitives/count-results.js +23 -0
  133. package/dist/handlers/primitives/count-results.js.map +1 -0
  134. package/dist/handlers/primitives/partition-by-substring.d.ts +18 -0
  135. package/dist/handlers/primitives/partition-by-substring.d.ts.map +1 -0
  136. package/dist/handlers/primitives/partition-by-substring.js +28 -0
  137. package/dist/handlers/primitives/partition-by-substring.js.map +1 -0
  138. package/dist/handlers/primitives/resolve-resource.d.ts +13 -0
  139. package/dist/handlers/primitives/resolve-resource.d.ts.map +1 -0
  140. package/dist/handlers/primitives/resolve-resource.js +21 -0
  141. package/dist/handlers/primitives/resolve-resource.js.map +1 -0
  142. package/dist/handlers/primitives/walk-field.d.ts +11 -0
  143. package/dist/handlers/primitives/walk-field.d.ts.map +1 -0
  144. package/dist/handlers/primitives/walk-field.js +31 -0
  145. package/dist/handlers/primitives/walk-field.js.map +1 -0
  146. package/dist/handlers/validate-field-match.d.ts +11 -0
  147. package/dist/handlers/validate-field-match.d.ts.map +1 -0
  148. package/dist/handlers/validate-field-match.js +39 -0
  149. package/dist/handlers/validate-field-match.js.map +1 -0
  150. package/dist/handlers/validate-verbatim-quotes.d.ts +11 -0
  151. package/dist/handlers/validate-verbatim-quotes.d.ts.map +1 -0
  152. package/dist/handlers/validate-verbatim-quotes.js +37 -0
  153. package/dist/handlers/validate-verbatim-quotes.js.map +1 -0
  154. package/dist/index.d.ts +57 -0
  155. package/dist/index.d.ts.map +1 -0
  156. package/dist/index.js +45 -0
  157. package/dist/index.js.map +1 -0
  158. package/dist/pipeline/processing-pipeline.d.ts +24 -0
  159. package/dist/pipeline/processing-pipeline.d.ts.map +1 -0
  160. package/dist/pipeline/processing-pipeline.js +53 -0
  161. package/dist/pipeline/processing-pipeline.js.map +1 -0
  162. package/dist/processors/compute-hash.d.ts +4 -0
  163. package/dist/processors/compute-hash.d.ts.map +1 -0
  164. package/dist/processors/compute-hash.js +14 -0
  165. package/dist/processors/compute-hash.js.map +1 -0
  166. package/dist/processors/normalize-text.d.ts +8 -0
  167. package/dist/processors/normalize-text.d.ts.map +1 -0
  168. package/dist/processors/normalize-text.js +47 -0
  169. package/dist/processors/normalize-text.js.map +1 -0
  170. package/dist/store/json-file-store.d.ts +24 -0
  171. package/dist/store/json-file-store.d.ts.map +1 -0
  172. package/dist/store/json-file-store.js +210 -0
  173. package/dist/store/json-file-store.js.map +1 -0
  174. package/dist/store/store-interface.d.ts +33 -0
  175. package/dist/store/store-interface.d.ts.map +1 -0
  176. package/dist/store/store-interface.js +2 -0
  177. package/dist/store/store-interface.js.map +1 -0
  178. package/dist/store/trace-buffer-store.d.ts +55 -0
  179. package/dist/store/trace-buffer-store.d.ts.map +1 -0
  180. package/dist/store/trace-buffer-store.js +113 -0
  181. package/dist/store/trace-buffer-store.js.map +1 -0
  182. package/dist/types/mcp-types.d.ts +17 -0
  183. package/dist/types/mcp-types.d.ts.map +1 -0
  184. package/dist/types/mcp-types.js +5 -0
  185. package/dist/types/mcp-types.js.map +1 -0
  186. package/dist/types/response-envelope.d.ts +96 -0
  187. package/dist/types/response-envelope.d.ts.map +1 -0
  188. package/dist/types/response-envelope.js +2 -0
  189. package/dist/types/response-envelope.js.map +1 -0
  190. package/dist/types/run-record.d.ts +169 -0
  191. package/dist/types/run-record.d.ts.map +1 -0
  192. package/dist/types/run-record.js +2 -0
  193. package/dist/types/run-record.js.map +1 -0
  194. package/dist/types/workflow-definition.d.ts +292 -0
  195. package/dist/types/workflow-definition.d.ts.map +1 -0
  196. package/dist/types/workflow-definition.js +2 -0
  197. package/dist/types/workflow-definition.js.map +1 -0
  198. package/dist/types/workflow-error.d.ts +26 -0
  199. package/dist/types/workflow-error.d.ts.map +1 -0
  200. package/dist/types/workflow-error.js +28 -0
  201. package/dist/types/workflow-error.js.map +1 -0
  202. package/dist/utils/schema-skeleton.d.ts +11 -0
  203. package/dist/utils/schema-skeleton.d.ts.map +1 -0
  204. package/dist/utils/schema-skeleton.js +40 -0
  205. package/dist/utils/schema-skeleton.js.map +1 -0
  206. package/dist/validation/input-schema.d.ts +26 -0
  207. package/dist/validation/input-schema.d.ts.map +1 -0
  208. package/dist/validation/input-schema.js +67 -0
  209. package/dist/validation/input-schema.js.map +1 -0
  210. package/dist/workflow/registrar.d.ts +20 -0
  211. package/dist/workflow/registrar.d.ts.map +1 -0
  212. package/dist/workflow/registrar.js +61 -0
  213. package/dist/workflow/registrar.js.map +1 -0
  214. package/dist/workflow/template-resolver.d.ts +25 -0
  215. package/dist/workflow/template-resolver.d.ts.map +1 -0
  216. package/dist/workflow/template-resolver.js +112 -0
  217. package/dist/workflow/template-resolver.js.map +1 -0
  218. package/dist/workflow/yaml-loader.d.ts +15 -0
  219. package/dist/workflow/yaml-loader.d.ts.map +1 -0
  220. package/dist/workflow/yaml-loader.js +408 -0
  221. package/dist/workflow/yaml-loader.js.map +1 -0
  222. package/package.json +61 -0
@@ -0,0 +1,36 @@
1
+ import type { AgentTraceEntry, TraceEntry, TraceNormalizationSummary } from '../types/run-record.js';
2
+ export interface NormalizeTraceResult {
3
+ entries: TraceEntry[];
4
+ digest: string | undefined;
5
+ summary: TraceNormalizationSummary;
6
+ }
7
+ /**
8
+ * Canonicalizes agent-submitted trace entries in a single pass.
9
+ *
10
+ * Rules applied in order:
11
+ * 1. Normalize event: trim whitespace; replace empty with "unknown_event"; cap to 100 chars.
12
+ * 2. Drop entries whose normalized event starts with "trace." (reserved engine namespace).
13
+ * 3. Normalize data: keep first 20 keys; cap string values to 500 chars; drop non-primitive values.
14
+ * 4. Apply hard limits (first-trigger wins): max 100 entries, max 50 KB UTF-8 bytes.
15
+ * 5. Assign seq numbers (1-based, monotonically increasing) after filtering.
16
+ * 6. Append a sentinel entry if truncation occurred.
17
+ *
18
+ * Normalization precedes the reserved-prefix check so that whitespace-padded variants
19
+ * like " trace.internal" are caught and dropped correctly.
20
+ * Byte limit uses incremental UTF-8 byte accounting: the serialized array size is
21
+ * maintained as a running counter rather than re-serializing the full array each
22
+ * iteration. The counter starts at 2 (empty JSON array `[]`) and grows by
23
+ * Buffer.byteLength(JSON.stringify(candidate)) + comma overhead per accepted entry.
24
+ * This is exact because JSON array serialization is the concatenation of independently
25
+ * serialized element strings separated by commas and wrapped in brackets.
26
+ *
27
+ * Invariant note: this exactness relies on current JSON serialization behavior and
28
+ * object construction order in this module. If serialization strategy changes,
29
+ * parity tests in trace-normalizer.test.ts are expected to fail and should trigger
30
+ * a review of the incremental byte-budget logic.
31
+ *
32
+ * Sentinel entries are exempt from the reserved-prefix drop rule.
33
+ * The sentinel data contains submitted, stored_before_sentinel, discarded, and reason fields.
34
+ */
35
+ export declare function normalizeTrace(input: AgentTraceEntry[]): NormalizeTraceResult;
36
+ //# sourceMappingURL=trace-normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-normalizer.d.ts","sourceRoot":"","sources":["../../src/engine/trace-normalizer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,yBAAyB,EAC1B,MAAM,wBAAwB,CAAC;AAuChC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,yBAAyB,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,oBAAoB,CA+F7E"}
@@ -0,0 +1,146 @@
1
+ // trace-normalizer.ts — Deterministic single-pass canonicalization for agent-submitted trace entries.
2
+ import { createHash } from 'node:crypto';
3
+ const MAX_ENTRIES = 100;
4
+ const MAX_BYTES = 50 * 1024; // 50 KB
5
+ const MAX_EVENT_LENGTH = 100;
6
+ const MAX_DATA_KEYS = 20;
7
+ const MAX_STRING_VALUE = 500;
8
+ const RESERVED_PREFIX = 'trace.';
9
+ const SENTINEL_EVENT = 'trace.truncated';
10
+ function normalizeEvent(raw) {
11
+ const trimmed = raw.trim();
12
+ return trimmed.length === 0 ? 'unknown_event' : trimmed.slice(0, MAX_EVENT_LENGTH);
13
+ }
14
+ function normalizeData(raw) {
15
+ if (raw === undefined)
16
+ return undefined;
17
+ const keys = Object.keys(raw).slice(0, MAX_DATA_KEYS);
18
+ const result = {};
19
+ for (const key of keys) {
20
+ const v = raw[key];
21
+ if (v === null) {
22
+ result[key] = null;
23
+ }
24
+ else if (typeof v === 'boolean') {
25
+ result[key] = v;
26
+ }
27
+ else if (typeof v === 'number') {
28
+ result[key] = v;
29
+ }
30
+ else if (typeof v === 'string') {
31
+ result[key] = v.slice(0, MAX_STRING_VALUE);
32
+ }
33
+ // Other types (object, array, undefined) are dropped silently.
34
+ }
35
+ return Object.keys(result).length > 0 ? result : undefined;
36
+ }
37
+ /**
38
+ * Canonicalizes agent-submitted trace entries in a single pass.
39
+ *
40
+ * Rules applied in order:
41
+ * 1. Normalize event: trim whitespace; replace empty with "unknown_event"; cap to 100 chars.
42
+ * 2. Drop entries whose normalized event starts with "trace." (reserved engine namespace).
43
+ * 3. Normalize data: keep first 20 keys; cap string values to 500 chars; drop non-primitive values.
44
+ * 4. Apply hard limits (first-trigger wins): max 100 entries, max 50 KB UTF-8 bytes.
45
+ * 5. Assign seq numbers (1-based, monotonically increasing) after filtering.
46
+ * 6. Append a sentinel entry if truncation occurred.
47
+ *
48
+ * Normalization precedes the reserved-prefix check so that whitespace-padded variants
49
+ * like " trace.internal" are caught and dropped correctly.
50
+ * Byte limit uses incremental UTF-8 byte accounting: the serialized array size is
51
+ * maintained as a running counter rather than re-serializing the full array each
52
+ * iteration. The counter starts at 2 (empty JSON array `[]`) and grows by
53
+ * Buffer.byteLength(JSON.stringify(candidate)) + comma overhead per accepted entry.
54
+ * This is exact because JSON array serialization is the concatenation of independently
55
+ * serialized element strings separated by commas and wrapped in brackets.
56
+ *
57
+ * Invariant note: this exactness relies on current JSON serialization behavior and
58
+ * object construction order in this module. If serialization strategy changes,
59
+ * parity tests in trace-normalizer.test.ts are expected to fail and should trigger
60
+ * a review of the incremental byte-budget logic.
61
+ *
62
+ * Sentinel entries are exempt from the reserved-prefix drop rule.
63
+ * The sentinel data contains submitted, stored_before_sentinel, discarded, and reason fields.
64
+ */
65
+ export function normalizeTrace(input) {
66
+ const submittedEntries = input.length;
67
+ let discardedReserved = 0;
68
+ let discardedOverflow = 0;
69
+ let truncated = false;
70
+ let truncationReason;
71
+ const stored = [];
72
+ // Incremental UTF-8 byte accounting for the serialized array form.
73
+ // Starts at 2 for the empty array (`[]`); grows by candidateBytes + commaBytes on each accept.
74
+ let currentArrayBytes = 2;
75
+ for (const entry of input) {
76
+ // Normalize event first so whitespace-padded reserved-prefix events are caught below.
77
+ const event = normalizeEvent(entry.event);
78
+ // Drop entries whose normalized event starts with the reserved engine prefix.
79
+ if (event.startsWith(RESERVED_PREFIX)) {
80
+ discardedReserved++;
81
+ continue;
82
+ }
83
+ // First-trigger: once truncated, all remaining valid entries count as overflow.
84
+ if (truncated) {
85
+ discardedOverflow++;
86
+ continue;
87
+ }
88
+ const data = normalizeData(entry.data);
89
+ const candidate = {
90
+ seq: stored.length + 1,
91
+ event,
92
+ ...(entry.timestamp !== undefined ? { timestamp: entry.timestamp } : {}),
93
+ ...(data !== undefined ? { data } : {}),
94
+ };
95
+ // Count limit check (evaluated before byte limit — first-trigger wins).
96
+ if (stored.length >= MAX_ENTRIES) {
97
+ truncated = true;
98
+ truncationReason = 'count_limit';
99
+ discardedOverflow++;
100
+ continue;
101
+ }
102
+ // Byte limit check: compute candidate bytes once and check the prospective array total.
103
+ // Incrementally tracking the array byte count is exact because JSON.stringify on an array
104
+ // equals '[' + elements.join(',') + ']' — element serializations are independent of context.
105
+ const candidateStr = JSON.stringify(candidate);
106
+ const candidateBytes = Buffer.byteLength(candidateStr, 'utf8');
107
+ const commaBytes = stored.length > 0 ? 1 : 0;
108
+ if (currentArrayBytes + commaBytes + candidateBytes > MAX_BYTES) {
109
+ truncated = true;
110
+ truncationReason = 'byte_limit';
111
+ discardedOverflow++;
112
+ continue;
113
+ }
114
+ currentArrayBytes += commaBytes + candidateBytes;
115
+ stored.push(candidate);
116
+ }
117
+ // Append engine sentinel if truncation occurred. Sentinel is exempt from reserved-prefix drop.
118
+ if (truncated) {
119
+ const sentinel = {
120
+ seq: stored.length + 1,
121
+ event: SENTINEL_EVENT,
122
+ data: {
123
+ submitted: submittedEntries,
124
+ stored_before_sentinel: stored.length,
125
+ discarded: discardedReserved + discardedOverflow,
126
+ reason: truncationReason,
127
+ },
128
+ };
129
+ stored.push(sentinel);
130
+ }
131
+ const discardedEntries = discardedReserved + discardedOverflow;
132
+ const summary = {
133
+ submitted_entries: submittedEntries,
134
+ stored_entries: stored.length,
135
+ discarded_entries: discardedEntries,
136
+ discarded_reserved_event_entries: discardedReserved,
137
+ discarded_overflow_entries: discardedOverflow,
138
+ truncated,
139
+ ...(truncationReason !== undefined ? { truncation_reason: truncationReason } : {}),
140
+ };
141
+ const digest = stored.length > 0
142
+ ? createHash('sha256').update(JSON.stringify(stored)).digest('hex')
143
+ : undefined;
144
+ return { entries: stored, digest, summary };
145
+ }
146
+ //# sourceMappingURL=trace-normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-normalizer.js","sourceRoot":"","sources":["../../src/engine/trace-normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Monotonic version identifier for the canonical trace policy.
3
+ * Increment when any limit, prefix rule, or truncation behavior changes.
4
+ */
5
+ export declare const TRACE_POLICY_VERSION: "v1";
6
+ export type TracePolicyVersion = typeof TRACE_POLICY_VERSION;
7
+ /** Canonical descriptor of the engine's trace normalization policy. */
8
+ export interface TracePolicyDescriptor {
9
+ /** Monotonic version string. Increment on any semantic change. */
10
+ version: TracePolicyVersion;
11
+ /**
12
+ * Maximum number of entries accepted into a normalized trace (before the sentinel entry).
13
+ * Matches the MAX_ENTRIES constant in trace-normalizer.ts.
14
+ */
15
+ maxStoredEntries: number;
16
+ /**
17
+ * Maximum UTF-8 byte size of the serialized stored-entries array (brackets + commas included).
18
+ * Matches the MAX_BYTES constant in trace-normalizer.ts.
19
+ */
20
+ maxSerializedBytes: number;
21
+ /**
22
+ * Normalized event prefix reserved for engine use.
23
+ * Entries whose normalized event starts with this prefix are dropped during normalization.
24
+ */
25
+ reservedEventPrefix: string;
26
+ /**
27
+ * Event name used for the sentinel entry appended when truncation occurs.
28
+ * Exempt from the reserved-prefix drop rule.
29
+ */
30
+ sentinelEvent: string;
31
+ /**
32
+ * Describes how truncation is triggered.
33
+ * 'first_trigger': the first limit hit (count or bytes) ends acceptance of further entries.
34
+ */
35
+ truncationBehavior: 'first_trigger';
36
+ }
37
+ /**
38
+ * Canonical trace policy. These values are the single authoritative source for
39
+ * trace normalization limits. Kept in sync with trace-normalizer.ts constants.
40
+ *
41
+ * When updating any limit in trace-normalizer.ts:
42
+ * 1. Update the matching field here.
43
+ * 2. Bump TRACE_POLICY_VERSION.
44
+ * 3. Update cloud adapters to recognize the new version.
45
+ */
46
+ export declare const TRACE_POLICY: TracePolicyDescriptor;
47
+ /**
48
+ * SHA-256 hash of the canonical policy descriptor (deterministically key-sorted JSON).
49
+ * Use as `engine_policy_hash` in cloud audit records.
50
+ * Recomputed on each process start; stable for a given TRACE_POLICY value.
51
+ */
52
+ export declare const TRACE_POLICY_HASH: string;
53
+ //# sourceMappingURL=trace-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-policy.d.ts","sourceRoot":"","sources":["../../src/engine/trace-policy.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAG,IAAa,CAAC;AAElD,MAAM,MAAM,kBAAkB,GAAG,OAAO,oBAAoB,CAAC;AAE7D,uEAAuE;AACvE,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,kBAAkB,EAAE,eAAe,CAAC;CACrC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,EAAE,qBAO1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAMhB,CAAC"}
@@ -0,0 +1,35 @@
1
+ // trace-policy.ts — Versioned canonical trace policy descriptor.
2
+ // This module is the engine's authoritative contract for trace semantics.
3
+ // Cloud adapters MUST consume this descriptor rather than duplicating limits manually.
4
+ import { createHash } from 'node:crypto';
5
+ /**
6
+ * Monotonic version identifier for the canonical trace policy.
7
+ * Increment when any limit, prefix rule, or truncation behavior changes.
8
+ */
9
+ export const TRACE_POLICY_VERSION = 'v1';
10
+ /**
11
+ * Canonical trace policy. These values are the single authoritative source for
12
+ * trace normalization limits. Kept in sync with trace-normalizer.ts constants.
13
+ *
14
+ * When updating any limit in trace-normalizer.ts:
15
+ * 1. Update the matching field here.
16
+ * 2. Bump TRACE_POLICY_VERSION.
17
+ * 3. Update cloud adapters to recognize the new version.
18
+ */
19
+ export const TRACE_POLICY = {
20
+ version: TRACE_POLICY_VERSION,
21
+ maxStoredEntries: 100,
22
+ maxSerializedBytes: 50 * 1024, // 50 KB
23
+ reservedEventPrefix: 'trace.',
24
+ sentinelEvent: 'trace.truncated',
25
+ truncationBehavior: 'first_trigger',
26
+ };
27
+ /**
28
+ * SHA-256 hash of the canonical policy descriptor (deterministically key-sorted JSON).
29
+ * Use as `engine_policy_hash` in cloud audit records.
30
+ * Recomputed on each process start; stable for a given TRACE_POLICY value.
31
+ */
32
+ export const TRACE_POLICY_HASH = createHash('sha256')
33
+ .update(JSON.stringify(Object.fromEntries(Object.entries(TRACE_POLICY).sort(([a], [b]) => a.localeCompare(b)))))
34
+ .digest('hex');
35
+ //# sourceMappingURL=trace-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-policy.js","sourceRoot":"","sources":["../../src/engine/trace-policy.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,0EAA0E;AAC1E,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAa,CAAC;AAmClD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAA0B;IACjD,OAAO,EAAE,oBAAoB;IAC7B,gBAAgB,EAAE,GAAG;IACrB,kBAAkB,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ;IACvC,mBAAmB,EAAE,QAAQ;IAC7B,aAAa,EAAE,iBAAiB;IAChC,kBAAkB,EAAE,eAAe;CACpC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAW,UAAU,CAAC,QAAQ,CAAC;KAC1D,MAAM,CACL,IAAI,CAAC,SAAS,CACZ,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CACxF,CACF;KACA,MAAM,CAAC,KAAK,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { WorkflowDefinition } from '../types/workflow-definition.js';
2
+ import type { WorkflowContextSnapshot } from '../types/run-record.js';
3
+ /**
4
+ * Reads all workflow_context entries from the workflow definition.
5
+ * Returns a map of entry name → snapshot. If a file cannot be read,
6
+ * the snapshot records the error and uses empty string as content.
7
+ */
8
+ export declare function loadWorkflowContext(definition: WorkflowDefinition): Promise<Record<string, WorkflowContextSnapshot>>;
9
+ //# sourceMappingURL=workflow-context-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-context-loader.d.ts","sourceRoot":"","sources":["../../src/engine/workflow-context-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CA8BlD"}
@@ -0,0 +1,41 @@
1
+ // Loads workflow_context entries declared in the workflow definition.
2
+ // Called once at run start. On file read failure, records an error snapshot
3
+ // and continues — execution is never aborted by a context load failure.
4
+ import * as fs from 'node:fs/promises';
5
+ import * as crypto from 'node:crypto';
6
+ /**
7
+ * Reads all workflow_context entries from the workflow definition.
8
+ * Returns a map of entry name → snapshot. If a file cannot be read,
9
+ * the snapshot records the error and uses empty string as content.
10
+ */
11
+ export async function loadWorkflowContext(definition) {
12
+ const entries = definition.workflow_context;
13
+ if (!entries || Object.keys(entries).length === 0)
14
+ return {};
15
+ const snapshots = {};
16
+ const loadedAt = new Date().toISOString();
17
+ for (const [name, entry] of Object.entries(entries)) {
18
+ const absolutePath = entry.source.path;
19
+ try {
20
+ const content = await fs.readFile(absolutePath, 'utf-8');
21
+ const hash = crypto.createHash('sha256').update(content).digest('hex');
22
+ snapshots[name] = {
23
+ source_path: absolutePath,
24
+ content,
25
+ content_hash: hash,
26
+ loaded_at: loadedAt,
27
+ };
28
+ }
29
+ catch (err) {
30
+ snapshots[name] = {
31
+ source_path: absolutePath,
32
+ content: '',
33
+ content_hash: '',
34
+ loaded_at: loadedAt,
35
+ error: err instanceof Error ? err.message : String(err),
36
+ };
37
+ }
38
+ }
39
+ return snapshots;
40
+ }
41
+ //# sourceMappingURL=workflow-context-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-context-loader.js","sourceRoot":"","sources":["../../src/engine/workflow-context-loader.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,4EAA4E;AAC5E,wEAAwE;AACxE,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAItC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAA8B;IAE9B,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC;IAC5C,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE7D,MAAM,SAAS,GAA4C,EAAE,CAAC;IAC9D,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,SAAS,CAAC,IAAI,CAAC,GAAG;gBAChB,WAAW,EAAE,YAAY;gBACzB,OAAO;gBACP,YAAY,EAAE,IAAI;gBAClB,SAAS,EAAE,QAAQ;aACpB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,IAAI,CAAC,GAAG;gBAChB,WAAW,EAAE,YAAY;gBACzB,OAAO,EAAE,EAAE;gBACX,YAAY,EAAE,EAAE;gBAChB,SAAS,EAAE,QAAQ;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { EvidenceSnapshot, StepDiagnostics, AgentTraceEntry } from '../types/run-record.js';
2
+ import type { ToolCallRecord } from '../types/mcp-types.js';
3
+ import type { NormalizeTraceResult } from '../engine/trace-normalizer.js';
4
+ export interface CaptureEvidenceParams {
5
+ stepId: string;
6
+ startedAt: Date;
7
+ completedAt: Date;
8
+ input: Record<string, unknown>;
9
+ output: Record<string, unknown>;
10
+ error?: string;
11
+ diagnostics?: StepDiagnostics;
12
+ agentProfile?: string;
13
+ agentProfileHash?: string;
14
+ resolvedParams?: Record<string, unknown>;
15
+ /** MCP tool calls made during this step. Absent = callStep path; present = callStepWithTools path. */
16
+ toolCalls?: ToolCallRecord[];
17
+ /**
18
+ * Agent-submitted trace entries. When present (even empty array), the normalizer runs
19
+ * and trace_summary is always recorded. Entries surviving normalization are stored as trace.
20
+ * evidence_hash is unaffected — it covers output_summary only.
21
+ * Ignored when normalizedTrace is provided.
22
+ */
23
+ trace?: AgentTraceEntry[];
24
+ /**
25
+ * Pre-normalized trace result from the execution loop. When provided, used directly
26
+ * in place of calling normalizeTrace on raw trace entries. Allows the execution loop
27
+ * to run schema validation on canonical entries before evidence capture without
28
+ * re-normalizing. Takes precedence over the raw trace field.
29
+ */
30
+ normalizedTrace?: NormalizeTraceResult;
31
+ }
32
+ /** Builds an EvidenceSnapshot from step execution parameters, including a SHA-256 content hash.
33
+ *
34
+ * evidence_hash is computed from output_summary only and is unaffected by trace.
35
+ * trace_digest (when present) covers the canonical trace array separately.
36
+ */
37
+ export declare function captureEvidence(params: CaptureEvidenceParams): EvidenceSnapshot;
38
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/evidence/snapshot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,sGAAsG;IACtG,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,gBAAgB,CA0C/E"}
@@ -0,0 +1,53 @@
1
+ // Standalone evidence capture utility — builds an EvidenceSnapshot from step execution data.
2
+ import { createHash } from 'node:crypto';
3
+ import { normalizeTrace } from '../engine/trace-normalizer.js';
4
+ /** Builds an EvidenceSnapshot from step execution parameters, including a SHA-256 content hash.
5
+ *
6
+ * evidence_hash is computed from output_summary only and is unaffected by trace.
7
+ * trace_digest (when present) covers the canonical trace array separately.
8
+ */
9
+ export function captureEvidence(params) {
10
+ // evidence_hash: hash of output only — behavior unchanged.
11
+ const evidenceHash = createHash('sha256').update(JSON.stringify(params.output)).digest('hex');
12
+ // Trace normalization: prefer pre-normalized result when available (avoids double normalization
13
+ // when the execution loop already normalized for schema validation). Fall back to raw trace.
14
+ let traceEntry = {};
15
+ if (params.normalizedTrace !== undefined) {
16
+ const { entries, digest, summary } = params.normalizedTrace;
17
+ if (entries.length > 0 && digest !== undefined) {
18
+ traceEntry = { trace: entries, trace_digest: digest, trace_summary: summary };
19
+ }
20
+ else {
21
+ traceEntry = { trace_summary: summary };
22
+ }
23
+ }
24
+ else if (params.trace !== undefined) {
25
+ const { entries, digest, summary } = normalizeTrace(params.trace);
26
+ if (entries.length > 0 && digest !== undefined) {
27
+ traceEntry = { trace: entries, trace_digest: digest, trace_summary: summary };
28
+ }
29
+ else {
30
+ traceEntry = { trace_summary: summary };
31
+ }
32
+ }
33
+ return {
34
+ step_id: params.stepId,
35
+ started_at: params.startedAt.toISOString(),
36
+ completed_at: params.completedAt.toISOString(),
37
+ duration_ms: params.completedAt.getTime() - params.startedAt.getTime(),
38
+ input_summary: params.input,
39
+ output_summary: params.output,
40
+ status: params.error !== undefined ? 'error' : 'success',
41
+ ...(params.error !== undefined ? { error: params.error } : {}),
42
+ evidence_hash: evidenceHash,
43
+ ...(params.diagnostics !== undefined ? { diagnostics: params.diagnostics } : {}),
44
+ ...(params.agentProfile !== undefined ? { agent_profile: params.agentProfile } : {}),
45
+ ...(params.agentProfileHash !== undefined
46
+ ? { agent_profile_hash: params.agentProfileHash }
47
+ : {}),
48
+ ...(params.resolvedParams !== undefined ? { resolved_params: params.resolvedParams } : {}),
49
+ ...(params.toolCalls !== undefined ? { tool_calls: params.toolCalls } : {}),
50
+ ...traceEntry,
51
+ };
52
+ }
53
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/evidence/snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { ExtensionRegistry } from './registry.js';
2
+ /**
3
+ * Returns an ExtensionRegistry pre-populated with Realm's built-in adapters.
4
+ * `FileSystemAdapter` is registered under `'filesystem'`.
5
+ * `SlackAdapter` is registered under `'slack'` with `webhook_url` taken from the
6
+ * `SLACK_WEBHOOK_URL` environment variable. If the variable is absent the adapter
7
+ * is still registered but will fail at call time via `ADAPTER_REQUEST_FAILED`.
8
+ *
9
+ * The engine uses this automatically when no registry is provided — workflows that only
10
+ * use built-in adapters need no registry code at all.
11
+ *
12
+ * Use this as a starting point when you need to add your own handlers or adapters on top:
13
+ * ```ts
14
+ * const registry = createDefaultRegistry();
15
+ * registry.register('handler', 'my_handler', myHandler);
16
+ * ```
17
+ */
18
+ export declare function createDefaultRegistry(): ExtensionRegistry;
19
+ //# sourceMappingURL=default-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-registry.d.ts","sourceRoot":"","sources":["../../src/extensions/default-registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIlD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,IAAI,iBAAiB,CAWzD"}
@@ -0,0 +1,31 @@
1
+ // default-registry.ts — pre-populates ExtensionRegistry with Realm's built-in adapters.
2
+ // Used by the execution engine as the fallback when no registry is explicitly provided,
3
+ // ensuring built-in adapters are always available without any developer wiring.
4
+ import { ExtensionRegistry } from './registry.js';
5
+ import { FileSystemAdapter } from '../adapters/file-adapter.js';
6
+ import { SlackAdapter } from '../adapters/slack-adapter.js';
7
+ /**
8
+ * Returns an ExtensionRegistry pre-populated with Realm's built-in adapters.
9
+ * `FileSystemAdapter` is registered under `'filesystem'`.
10
+ * `SlackAdapter` is registered under `'slack'` with `webhook_url` taken from the
11
+ * `SLACK_WEBHOOK_URL` environment variable. If the variable is absent the adapter
12
+ * is still registered but will fail at call time via `ADAPTER_REQUEST_FAILED`.
13
+ *
14
+ * The engine uses this automatically when no registry is provided — workflows that only
15
+ * use built-in adapters need no registry code at all.
16
+ *
17
+ * Use this as a starting point when you need to add your own handlers or adapters on top:
18
+ * ```ts
19
+ * const registry = createDefaultRegistry();
20
+ * registry.register('handler', 'my_handler', myHandler);
21
+ * ```
22
+ */
23
+ export function createDefaultRegistry() {
24
+ const r = new ExtensionRegistry();
25
+ r.register('adapter', 'filesystem', new FileSystemAdapter('filesystem'));
26
+ r.register('adapter', 'slack', new SlackAdapter('slack', {
27
+ webhook_url: process.env['SLACK_WEBHOOK_URL'] ?? '',
28
+ }));
29
+ return r;
30
+ }
31
+ //# sourceMappingURL=default-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-registry.js","sourceRoot":"","sources":["../../src/extensions/default-registry.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,wFAAwF;AACxF,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,CAAC,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAClC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,IAAI,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC;IACzE,CAAC,CAAC,QAAQ,CACR,SAAS,EACT,OAAO,EACP,IAAI,YAAY,CAAC,OAAO,EAAE;QACxB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,EAAE;KACpD,CAAC,CACH,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface ProcessorInput {
2
+ text: string;
3
+ metadata: Record<string, unknown>;
4
+ }
5
+ export interface ProcessorOutput {
6
+ text: string;
7
+ metadata: Record<string, unknown>;
8
+ }
9
+ export interface Processor {
10
+ readonly id: string;
11
+ process(content: ProcessorInput, config: Record<string, unknown>): Promise<ProcessorOutput>;
12
+ }
13
+ //# sourceMappingURL=processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.d.ts","sourceRoot":"","sources":["../../src/extensions/processor.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7F"}
@@ -0,0 +1,3 @@
1
+ // Processor — stateless content transformation in a processing pipeline.
2
+ export {};
3
+ //# sourceMappingURL=processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.js","sourceRoot":"","sources":["../../src/extensions/processor.ts"],"names":[],"mappings":"AAAA,yEAAyE"}
@@ -0,0 +1,25 @@
1
+ import type { ServiceAdapter } from './service-adapter.js';
2
+ import type { Processor } from './processor.js';
3
+ import type { StepHandler } from './step-handler.js';
4
+ import type { RateLimitConfig } from '../types/workflow-definition.js';
5
+ import type { RateLimiter } from '../adapters/rate-limiter.js';
6
+ export declare class ExtensionRegistry {
7
+ private adapters;
8
+ private processors;
9
+ private handlers;
10
+ private rateLimiters;
11
+ register(type: 'adapter', name: string, impl: ServiceAdapter): void;
12
+ register(type: 'processor', name: string, impl: Processor): void;
13
+ register(type: 'handler', name: string, impl: StepHandler): void;
14
+ getAdapter(name: string): ServiceAdapter | undefined;
15
+ getProcessor(name: string): Processor | undefined;
16
+ getHandler(name: string): StepHandler | undefined;
17
+ /**
18
+ * Returns the RateLimiter for the given service, creating one if it does not
19
+ * yet exist. The limiter is keyed by service name and lives for the lifetime
20
+ * of the registry — callers should use a stable registry instance to get the
21
+ * benefit of shared rate limiting across concurrent steps.
22
+ */
23
+ getOrCreateRateLimiter(serviceName: string, config: RateLimitConfig): RateLimiter;
24
+ }
25
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/extensions/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG/D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,YAAY,CAAkC;IAEtD,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI;IACnE,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAChE,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI;IAehE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIpD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIjD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIjD;;;;;OAKG;IACH,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,WAAW;CAYlF"}
@@ -0,0 +1,43 @@
1
+ import { TokenBucketRateLimiter } from '../adapters/token-bucket.js';
2
+ export class ExtensionRegistry {
3
+ adapters = new Map();
4
+ processors = new Map();
5
+ handlers = new Map();
6
+ rateLimiters = new Map();
7
+ register(type, name, impl) {
8
+ if (type === 'adapter') {
9
+ this.adapters.set(name, impl);
10
+ }
11
+ else if (type === 'processor') {
12
+ this.processors.set(name, impl);
13
+ }
14
+ else {
15
+ this.handlers.set(name, impl);
16
+ }
17
+ }
18
+ getAdapter(name) {
19
+ return this.adapters.get(name);
20
+ }
21
+ getProcessor(name) {
22
+ return this.processors.get(name);
23
+ }
24
+ getHandler(name) {
25
+ return this.handlers.get(name);
26
+ }
27
+ /**
28
+ * Returns the RateLimiter for the given service, creating one if it does not
29
+ * yet exist. The limiter is keyed by service name and lives for the lifetime
30
+ * of the registry — callers should use a stable registry instance to get the
31
+ * benefit of shared rate limiting across concurrent steps.
32
+ */
33
+ getOrCreateRateLimiter(serviceName, config) {
34
+ if (!this.rateLimiters.has(serviceName)) {
35
+ this.rateLimiters.set(serviceName, new TokenBucketRateLimiter({
36
+ requests_per_second: config.requests_per_second,
37
+ burst: config.burst ?? config.requests_per_second,
38
+ }));
39
+ }
40
+ return this.rateLimiters.get(serviceName);
41
+ }
42
+ }
43
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/extensions/registry.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,OAAO,iBAAiB;IACpB,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC7C,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC1C,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IAKtD,QAAQ,CACN,IAAyC,EACzC,IAAY,EACZ,IAA8C;QAE9C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAsB,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,IAAiB,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAmB,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,YAAY,CAAC,IAAY;QACvB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,WAAmB,EAAE,MAAuB;QACjE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CACnB,WAAW,EACX,IAAI,sBAAsB,CAAC;gBACzB,mBAAmB,EAAE,MAAM,CAAC,mBAAoB;gBAChD,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,mBAAoB;aACnD,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAE,CAAC;IAC7C,CAAC;CACF"}