monora-ai 2.0.0 → 2.1.3

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 (202) hide show
  1. package/README.md +441 -150
  2. package/dist/aims_governance.d.ts +238 -0
  3. package/dist/aims_governance.d.ts.map +1 -0
  4. package/dist/aims_governance.js +922 -0
  5. package/dist/alerts.d.ts +16 -0
  6. package/dist/alerts.d.ts.map +1 -1
  7. package/dist/alerts.js +16 -0
  8. package/dist/api.d.ts +6 -0
  9. package/dist/api.d.ts.map +1 -1
  10. package/dist/api.js +6 -0
  11. package/dist/assessment.d.ts +269 -0
  12. package/dist/assessment.d.ts.map +1 -0
  13. package/dist/assessment.js +1232 -0
  14. package/dist/attestation.js +23 -1
  15. package/dist/attribution.d.ts +349 -0
  16. package/dist/attribution.d.ts.map +1 -0
  17. package/dist/attribution.js +987 -0
  18. package/dist/autodetect.d.ts +69 -1
  19. package/dist/autodetect.d.ts.map +1 -1
  20. package/dist/autodetect.js +644 -1
  21. package/dist/bias.d.ts +130 -0
  22. package/dist/bias.d.ts.map +1 -0
  23. package/dist/bias.js +223 -0
  24. package/dist/circuit_breaker.js +3 -3
  25. package/dist/cli/diagnostics.d.ts +5 -1
  26. package/dist/cli/diagnostics.d.ts.map +1 -1
  27. package/dist/cli/diagnostics.js +31 -8
  28. package/dist/cli/doctor.d.ts +25 -0
  29. package/dist/cli/doctor.d.ts.map +1 -0
  30. package/dist/cli/doctor.js +381 -0
  31. package/dist/cli/fix.d.ts +16 -0
  32. package/dist/cli/fix.d.ts.map +1 -0
  33. package/dist/cli/fix.js +284 -0
  34. package/dist/cli/init.d.ts +57 -0
  35. package/dist/cli/init.d.ts.map +1 -0
  36. package/dist/cli/init.js +205 -0
  37. package/dist/cli.js +1611 -126
  38. package/dist/complianceTargets.d.ts +111 -0
  39. package/dist/complianceTargets.d.ts.map +1 -0
  40. package/dist/complianceTargets.js +521 -0
  41. package/dist/config.d.ts +301 -17
  42. package/dist/config.d.ts.map +1 -1
  43. package/dist/config.js +428 -36
  44. package/dist/config_migrations.d.ts +41 -0
  45. package/dist/config_migrations.d.ts.map +1 -1
  46. package/dist/config_migrations.js +205 -0
  47. package/dist/config_schema.d.ts +2900 -731
  48. package/dist/config_schema.d.ts.map +1 -1
  49. package/dist/config_schema.js +257 -55
  50. package/dist/context.d.ts +34 -0
  51. package/dist/context.d.ts.map +1 -1
  52. package/dist/context.js +118 -7
  53. package/dist/control_backbone.d.ts +122 -0
  54. package/dist/control_backbone.d.ts.map +1 -0
  55. package/dist/control_backbone.js +698 -0
  56. package/dist/data-governance.d.ts +187 -0
  57. package/dist/data-governance.d.ts.map +1 -0
  58. package/dist/data-governance.js +424 -0
  59. package/dist/dataResidency.d.ts +44 -0
  60. package/dist/dataResidency.d.ts.map +1 -0
  61. package/dist/dataResidency.js +203 -0
  62. package/dist/dispatcher.d.ts +32 -0
  63. package/dist/dispatcher.d.ts.map +1 -1
  64. package/dist/dispatcher.js +91 -4
  65. package/dist/events.d.ts.map +1 -1
  66. package/dist/events.js +38 -0
  67. package/dist/evidence_store.d.ts +103 -0
  68. package/dist/evidence_store.d.ts.map +1 -0
  69. package/dist/evidence_store.js +459 -0
  70. package/dist/executiveSummary.d.ts +65 -8
  71. package/dist/executiveSummary.d.ts.map +1 -1
  72. package/dist/executiveSummary.js +289 -26
  73. package/dist/identity.d.ts +143 -0
  74. package/dist/identity.d.ts.map +1 -0
  75. package/dist/identity.js +231 -0
  76. package/dist/impact-assessment.d.ts +350 -0
  77. package/dist/impact-assessment.d.ts.map +1 -0
  78. package/dist/impact-assessment.js +580 -0
  79. package/dist/index.d.ts +25 -5
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +300 -4
  82. package/dist/instrumentation.d.ts +1 -1
  83. package/dist/instrumentation.d.ts.map +1 -1
  84. package/dist/instrumentation.js +243 -27
  85. package/dist/integrations/anthropic.d.ts +3 -0
  86. package/dist/integrations/anthropic.d.ts.map +1 -1
  87. package/dist/integrations/anthropic.js +284 -79
  88. package/dist/integrations/governance.d.ts +33 -0
  89. package/dist/integrations/governance.d.ts.map +1 -0
  90. package/dist/integrations/governance.js +208 -0
  91. package/dist/integrations/langchain.d.ts +7 -0
  92. package/dist/integrations/langchain.d.ts.map +1 -1
  93. package/dist/integrations/langchain.js +387 -143
  94. package/dist/integrations/openai.d.ts +9 -0
  95. package/dist/integrations/openai.d.ts.map +1 -1
  96. package/dist/integrations/openai.js +673 -73
  97. package/dist/iso42001_consolidation.d.ts +16 -0
  98. package/dist/iso42001_consolidation.d.ts.map +1 -0
  99. package/dist/iso42001_consolidation.js +413 -0
  100. package/dist/iso42001_workflows.d.ts +263 -0
  101. package/dist/iso42001_workflows.d.ts.map +1 -0
  102. package/dist/iso42001_workflows.js +781 -0
  103. package/dist/lifecycle.d.ts +299 -0
  104. package/dist/lifecycle.d.ts.map +1 -0
  105. package/dist/lifecycle.js +624 -0
  106. package/dist/lineage.d.ts +2 -2
  107. package/dist/lineage.d.ts.map +1 -1
  108. package/dist/lineage.js +12 -17
  109. package/dist/middleware/express.d.ts.map +1 -1
  110. package/dist/middleware/express.js +33 -3
  111. package/dist/middleware/nextjs.d.ts.map +1 -1
  112. package/dist/middleware/nextjs.js +42 -68
  113. package/dist/model.d.ts +143 -0
  114. package/dist/model.d.ts.map +1 -0
  115. package/dist/model.js +371 -0
  116. package/dist/onboarding.d.ts +42 -0
  117. package/dist/onboarding.d.ts.map +1 -0
  118. package/dist/onboarding.js +1022 -0
  119. package/dist/oversight.d.ts +264 -0
  120. package/dist/oversight.d.ts.map +1 -0
  121. package/dist/oversight.js +497 -0
  122. package/dist/pdf_report.d.ts.map +1 -1
  123. package/dist/pdf_report.js +42 -21
  124. package/dist/presets.d.ts +88 -0
  125. package/dist/presets.d.ts.map +1 -0
  126. package/dist/presets.js +520 -0
  127. package/dist/propagation.d.ts.map +1 -1
  128. package/dist/propagation.js +34 -2
  129. package/dist/quotas.d.ts +171 -0
  130. package/dist/quotas.d.ts.map +1 -0
  131. package/dist/quotas.js +259 -0
  132. package/dist/register.d.ts +13 -0
  133. package/dist/register.d.ts.map +1 -0
  134. package/dist/register.js +99 -0
  135. package/dist/registry.d.ts +1 -0
  136. package/dist/registry.d.ts.map +1 -1
  137. package/dist/registry.js +7 -0
  138. package/dist/registryData.json +43 -6
  139. package/dist/report.d.ts +2 -1
  140. package/dist/report.d.ts.map +1 -1
  141. package/dist/report.js +189 -2
  142. package/dist/reporting.d.ts +125 -0
  143. package/dist/reporting.d.ts.map +1 -1
  144. package/dist/reporting.js +196 -5
  145. package/dist/resources.d.ts +285 -0
  146. package/dist/resources.d.ts.map +1 -0
  147. package/dist/resources.js +643 -0
  148. package/dist/risk.d.ts +120 -0
  149. package/dist/risk.d.ts.map +1 -0
  150. package/dist/risk.js +220 -0
  151. package/dist/runtime.d.ts +74 -1
  152. package/dist/runtime.d.ts.map +1 -1
  153. package/dist/runtime.js +598 -22
  154. package/dist/schemaInference.d.ts +92 -0
  155. package/dist/schemaInference.d.ts.map +1 -0
  156. package/dist/schemaInference.js +466 -0
  157. package/dist/schema_validation.js +2 -2
  158. package/dist/schemas/config.schema.json +169 -6
  159. package/dist/schemas/event.schema.json +4 -0
  160. package/dist/security_report.js +4 -4
  161. package/dist/signing.d.ts +1 -1
  162. package/dist/signing.d.ts.map +1 -1
  163. package/dist/signing.js +4 -0
  164. package/dist/sinks/file.d.ts +19 -1
  165. package/dist/sinks/file.d.ts.map +1 -1
  166. package/dist/sinks/file.js +82 -13
  167. package/dist/sinks/https.d.ts +10 -0
  168. package/dist/sinks/https.d.ts.map +1 -1
  169. package/dist/sinks/https.js +76 -16
  170. package/dist/sinks/stdout.d.ts +1 -0
  171. package/dist/sinks/stdout.d.ts.map +1 -1
  172. package/dist/sinks/stdout.js +12 -1
  173. package/dist/spec.d.ts +159 -0
  174. package/dist/spec.d.ts.map +1 -0
  175. package/dist/spec.js +391 -0
  176. package/dist/stakeholders.d.ts +199 -0
  177. package/dist/stakeholders.d.ts.map +1 -0
  178. package/dist/stakeholders.js +398 -0
  179. package/dist/standards.d.ts.map +1 -1
  180. package/dist/standards.js +160 -2
  181. package/dist/standards_ingest.d.ts +2 -2
  182. package/dist/standards_ingest.d.ts.map +1 -1
  183. package/dist/standards_ingest.js +105 -23
  184. package/dist/streaming.d.ts.map +1 -1
  185. package/dist/streaming.js +7 -2
  186. package/dist/telemetry.d.ts +16 -2
  187. package/dist/telemetry.d.ts.map +1 -1
  188. package/dist/telemetry.js +79 -14
  189. package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
  190. package/dist/traced_emitter.d.ts +3 -0
  191. package/dist/traced_emitter.d.ts.map +1 -1
  192. package/dist/traced_emitter.js +142 -25
  193. package/dist/trust_package.d.ts +21 -1
  194. package/dist/trust_package.d.ts.map +1 -1
  195. package/dist/trust_package.js +101 -4
  196. package/dist/verify.d.ts.map +1 -1
  197. package/dist/verify.js +9 -2
  198. package/dist/wal.d.ts.map +1 -1
  199. package/dist/wal.js +2 -1
  200. package/package.json +14 -1
  201. package/scripts/postinstall.js +119 -97
  202. package/templates/controls/iso42001_control_catalog.json +1443 -0
@@ -22,8 +22,16 @@
22
22
  */
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.patchAnthropic = patchAnthropic;
25
+ exports.wrapMessagesCreate = wrapMessagesCreate;
26
+ exports.wrapMessagesStream = wrapMessagesStream;
27
+ exports.wrapCompletions = wrapCompletions;
25
28
  const runtime_1 = require("../runtime");
29
+ const data_handling_1 = require("../data_handling");
30
+ const policy_1 = require("../policy");
31
+ const quotas_1 = require("../quotas");
32
+ const context_1 = require("../context");
26
33
  const lineage_1 = require("../lineage");
34
+ const governance_1 = require("./governance");
27
35
  /**
28
36
  * Patch an Anthropic client to automatically trace all API calls.
29
37
  */
@@ -45,57 +53,110 @@ function patchAnthropic(client, options = {}) {
45
53
  client.completions.create = wrapCompletions(originalCreate, dataClassification, purpose, reason);
46
54
  }
47
55
  }
56
+ function isGovernanceError(error) {
57
+ return (error instanceof data_handling_1.DataHandlingViolation ||
58
+ error instanceof policy_1.PolicyViolation ||
59
+ error instanceof quotas_1.QuotaExceededError);
60
+ }
48
61
  function wrapMessagesCreate(originalFn, dataClassification, purpose, reason) {
49
62
  return async function wrappedMessagesCreate(...args) {
50
63
  const kwargs = args[0] || {};
51
64
  const model = kwargs.model || 'unknown';
52
65
  const messages = kwargs.messages || [];
53
66
  const isStreaming = kwargs.stream === true;
54
- const state = (0, runtime_1.ensureState)();
55
- const startEvent = state.eventBuilder.build('llm_call', {
67
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
68
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
56
69
  model,
57
- provider: 'anthropic',
58
- api: 'messages',
59
- num_messages: messages.length,
60
- messages: messages.slice(0, 10),
61
- stream: isStreaming,
62
- max_tokens: kwargs.max_tokens,
63
- temperature: kwargs.temperature,
64
- top_p: kwargs.top_p,
65
- system: kwargs.system?.slice?.(0, 500) || null,
66
- }, {
70
+ requestPayload,
67
71
  dataClassification,
68
72
  purpose,
69
73
  reason,
74
+ provider: 'anthropic',
75
+ spanName: 'llm_call:anthropic.messages',
76
+ });
77
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
78
+ const event = state.eventBuilder.build('llm_call', {
79
+ model,
80
+ provider: 'anthropic',
81
+ api: 'messages',
82
+ num_messages: messages.length,
83
+ messages: messages.slice(0, 10),
84
+ stream: isStreaming,
85
+ max_tokens: kwargs.max_tokens,
86
+ temperature: kwargs.temperature,
87
+ top_p: kwargs.top_p,
88
+ system: kwargs.system?.slice?.(0, 500) || null,
89
+ status: 'started',
90
+ }, {
91
+ dataClassification,
92
+ purpose,
93
+ reason,
94
+ });
95
+ (0, runtime_1.emitEvent)(event);
96
+ return event;
70
97
  });
71
- (0, runtime_1.emitEvent)(startEvent);
72
98
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
73
99
  try {
74
- const response = await originalFn(...args);
100
+ const response = await originalFn.apply(this, args);
75
101
  if (isStreaming) {
76
- return wrapStreamingResponse(response, model, startEvent.event_id, dataClassification, purpose, state);
102
+ return wrapStreamingResponse(response, {
103
+ model,
104
+ parentEventId: startEvent.event_id,
105
+ dataClassification,
106
+ purpose,
107
+ reason,
108
+ state,
109
+ trace,
110
+ });
77
111
  }
78
112
  // Non-streaming response
79
113
  const completionData = extractMessageResponse(response, model);
80
- const completionEvent = state.eventBuilder.build('llm_call', completionData, {
114
+ (0, context_1.runInContext)(trace.context, () => {
115
+ const completionEvent = state.eventBuilder.build('llm_call', { ...completionData, status: 'success' }, {
116
+ dataClassification,
117
+ purpose,
118
+ parentEventId: startEvent.event_id,
119
+ });
120
+ (0, runtime_1.emitEvent)(completionEvent);
121
+ });
122
+ await (0, governance_1.postflightLlmCall)({
123
+ state,
124
+ trace,
125
+ model,
126
+ response,
81
127
  dataClassification,
82
128
  purpose,
83
- parentEventId: startEvent.event_id,
129
+ reason,
84
130
  });
85
- (0, runtime_1.emitEvent)(completionEvent);
86
131
  return response;
87
132
  }
88
133
  catch (error) {
89
- const errorEvent = state.eventBuilder.build('llm_call', {
134
+ if (isGovernanceError(error)) {
135
+ throw error;
136
+ }
137
+ (0, context_1.runInContext)(trace.context, () => {
138
+ const errorEvent = state.eventBuilder.build('llm_call', {
139
+ model,
140
+ error: error.message || String(error),
141
+ error_type: error.constructor?.name || 'Error',
142
+ status: 'error',
143
+ }, {
144
+ dataClassification,
145
+ purpose,
146
+ parentEventId: startEvent.event_id,
147
+ });
148
+ (0, runtime_1.emitEvent)(errorEvent);
149
+ });
150
+ await (0, governance_1.postflightLlmCall)({
151
+ state,
152
+ trace,
90
153
  model,
91
- error: error.message || String(error),
92
- error_type: error.constructor?.name || 'Error',
93
- }, {
154
+ response: null,
94
155
  dataClassification,
95
156
  purpose,
96
- parentEventId: startEvent.event_id,
157
+ reason,
158
+ error: true,
97
159
  });
98
- (0, runtime_1.emitEvent)(errorEvent);
99
160
  throw error;
100
161
  }
101
162
  };
@@ -105,30 +166,43 @@ function wrapMessagesStream(originalFn, dataClassification, purpose, reason) {
105
166
  const kwargs = args[0] || {};
106
167
  const model = kwargs.model || 'unknown';
107
168
  const messages = kwargs.messages || [];
108
- const state = (0, runtime_1.ensureState)();
109
- const startEvent = state.eventBuilder.build('llm_call', {
169
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
170
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
110
171
  model,
111
- provider: 'anthropic',
112
- api: 'messages.stream',
113
- num_messages: messages.length,
114
- messages: messages.slice(0, 10),
115
- stream: true,
116
- max_tokens: kwargs.max_tokens,
117
- temperature: kwargs.temperature,
118
- }, {
172
+ requestPayload,
119
173
  dataClassification,
120
174
  purpose,
121
175
  reason,
176
+ provider: 'anthropic',
177
+ spanName: 'llm_call:anthropic.messages.stream',
178
+ });
179
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
180
+ const event = state.eventBuilder.build('llm_call', {
181
+ model,
182
+ provider: 'anthropic',
183
+ api: 'messages.stream',
184
+ num_messages: messages.length,
185
+ messages: messages.slice(0, 10),
186
+ stream: true,
187
+ max_tokens: kwargs.max_tokens,
188
+ temperature: kwargs.temperature,
189
+ status: 'started',
190
+ }, {
191
+ dataClassification,
192
+ purpose,
193
+ reason,
194
+ });
195
+ (0, runtime_1.emitEvent)(event);
196
+ return event;
122
197
  });
123
- (0, runtime_1.emitEvent)(startEvent);
124
198
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
125
- const streamManager = originalFn(...args);
199
+ const streamManager = originalFn.apply(this, args);
126
200
  // Return wrapped stream manager
127
- return new StreamManagerWrapper(streamManager, model, startEvent.event_id, dataClassification, purpose, state);
201
+ return new StreamManagerWrapper(streamManager, model, startEvent.event_id, dataClassification, purpose, reason, state, trace);
128
202
  };
129
203
  }
130
204
  class StreamManagerWrapper {
131
- constructor(streamManager, model, parentEventId, dataClassification, purpose, state) {
205
+ constructor(streamManager, model, parentEventId, dataClassification, purpose, reason, state, trace) {
132
206
  this.accumulatedText = '';
133
207
  this.usage = {};
134
208
  this.streamManager = streamManager;
@@ -136,17 +210,24 @@ class StreamManagerWrapper {
136
210
  this.parentEventId = parentEventId;
137
211
  this.dataClassification = dataClassification;
138
212
  this.purpose = purpose;
213
+ this.reason = reason;
139
214
  this.state = state;
215
+ this.trace = trace;
140
216
  }
141
217
  async *[Symbol.asyncIterator]() {
218
+ let error = null;
142
219
  try {
143
220
  for await (const event of this.streamManager) {
144
221
  this.processEvent(event);
145
222
  yield event;
146
223
  }
147
224
  }
225
+ catch (err) {
226
+ error = err;
227
+ throw err;
228
+ }
148
229
  finally {
149
- this.emitCompletion();
230
+ await this.emitCompletion(error);
150
231
  }
151
232
  }
152
233
  processEvent(event) {
@@ -163,32 +244,74 @@ class StreamManagerWrapper {
163
244
  }
164
245
  }
165
246
  }
166
- emitCompletion() {
167
- const completionEvent = this.state.eventBuilder.build('llm_call', {
247
+ async emitCompletion(error) {
248
+ if (error) {
249
+ (0, context_1.runInContext)(this.trace.context, () => {
250
+ const errorEvent = this.state.eventBuilder.build('llm_call', {
251
+ model: this.model,
252
+ error: error.message || String(error),
253
+ error_type: error.constructor?.name || 'Error',
254
+ status: 'error',
255
+ }, {
256
+ dataClassification: this.dataClassification,
257
+ purpose: this.purpose,
258
+ parentEventId: this.parentEventId,
259
+ });
260
+ (0, runtime_1.emitEvent)(errorEvent);
261
+ });
262
+ await (0, governance_1.postflightLlmCall)({
263
+ state: this.state,
264
+ trace: this.trace,
265
+ model: this.model,
266
+ response: null,
267
+ dataClassification: this.dataClassification,
268
+ purpose: this.purpose,
269
+ reason: this.reason,
270
+ error: true,
271
+ });
272
+ return;
273
+ }
274
+ (0, context_1.runInContext)(this.trace.context, () => {
275
+ const completionEvent = this.state.eventBuilder.build('llm_call', {
276
+ model: this.model,
277
+ content: this.accumulatedText.slice(0, 500) || null,
278
+ content_length: this.accumulatedText.length,
279
+ usage: this.usage,
280
+ stream_complete: true,
281
+ status: 'success',
282
+ }, {
283
+ dataClassification: this.dataClassification,
284
+ purpose: this.purpose,
285
+ parentEventId: this.parentEventId,
286
+ });
287
+ (0, runtime_1.emitEvent)(completionEvent);
288
+ });
289
+ await (0, governance_1.postflightLlmCall)({
290
+ state: this.state,
291
+ trace: this.trace,
168
292
  model: this.model,
169
- content: this.accumulatedText.slice(0, 500) || null,
170
- content_length: this.accumulatedText.length,
171
- usage: this.usage,
172
- stream_complete: true,
173
- }, {
293
+ response: this.usage ? { usage: this.usage } : null,
174
294
  dataClassification: this.dataClassification,
175
295
  purpose: this.purpose,
176
- parentEventId: this.parentEventId,
296
+ reason: this.reason,
177
297
  });
178
- (0, runtime_1.emitEvent)(completionEvent);
179
298
  }
180
299
  // Delegate other methods to underlying stream manager
181
300
  on(event, callback) {
182
301
  this.streamManager.on?.(event, callback);
183
302
  return this;
184
303
  }
304
+ get controller() {
305
+ return this.streamManager?.controller;
306
+ }
185
307
  async finalMessage() {
186
308
  return this.streamManager.finalMessage?.();
187
309
  }
188
310
  }
189
- async function* wrapStreamingResponse(stream, model, parentEventId, dataClassification, purpose, state) {
311
+ async function* wrapStreamingResponse(stream, options) {
190
312
  let accumulatedText = '';
191
313
  let usage = {};
314
+ let error = null;
192
315
  try {
193
316
  for await (const event of stream) {
194
317
  // Track content from streaming events
@@ -207,20 +330,62 @@ async function* wrapStreamingResponse(stream, model, parentEventId, dataClassifi
207
330
  yield event;
208
331
  }
209
332
  }
333
+ catch (err) {
334
+ error = err;
335
+ throw err;
336
+ }
210
337
  finally {
338
+ if (error) {
339
+ (0, context_1.runInContext)(options.trace.context, () => {
340
+ const errorEvent = options.state.eventBuilder.build('llm_call', {
341
+ model: options.model,
342
+ error: error.message || String(error),
343
+ error_type: error.constructor?.name || 'Error',
344
+ status: 'error',
345
+ }, {
346
+ dataClassification: options.dataClassification,
347
+ purpose: options.purpose,
348
+ parentEventId: options.parentEventId,
349
+ });
350
+ (0, runtime_1.emitEvent)(errorEvent);
351
+ });
352
+ await (0, governance_1.postflightLlmCall)({
353
+ state: options.state,
354
+ trace: options.trace,
355
+ model: options.model,
356
+ response: null,
357
+ dataClassification: options.dataClassification,
358
+ purpose: options.purpose,
359
+ reason: options.reason,
360
+ error: true,
361
+ });
362
+ return;
363
+ }
211
364
  // Emit completion event when stream ends
212
- const completionEvent = state.eventBuilder.build('llm_call', {
213
- model,
214
- content: accumulatedText.slice(0, 500) || null,
215
- content_length: accumulatedText.length,
216
- usage,
217
- stream_complete: true,
218
- }, {
219
- dataClassification,
220
- purpose,
221
- parentEventId,
365
+ (0, context_1.runInContext)(options.trace.context, () => {
366
+ const completionEvent = options.state.eventBuilder.build('llm_call', {
367
+ model: options.model,
368
+ content: accumulatedText.slice(0, 500) || null,
369
+ content_length: accumulatedText.length,
370
+ usage,
371
+ stream_complete: true,
372
+ status: 'success',
373
+ }, {
374
+ dataClassification: options.dataClassification,
375
+ purpose: options.purpose,
376
+ parentEventId: options.parentEventId,
377
+ });
378
+ (0, runtime_1.emitEvent)(completionEvent);
379
+ });
380
+ await (0, governance_1.postflightLlmCall)({
381
+ state: options.state,
382
+ trace: options.trace,
383
+ model: options.model,
384
+ response: usage ? { usage } : null,
385
+ dataClassification: options.dataClassification,
386
+ purpose: options.purpose,
387
+ reason: options.reason,
222
388
  });
223
- (0, runtime_1.emitEvent)(completionEvent);
224
389
  }
225
390
  }
226
391
  function extractMessageResponse(response, model) {
@@ -255,23 +420,36 @@ function wrapCompletions(originalFn, dataClassification, purpose, reason) {
255
420
  const kwargs = args[0] || {};
256
421
  const model = kwargs.model || 'unknown';
257
422
  const prompt = kwargs.prompt || '';
258
- const state = (0, runtime_1.ensureState)();
259
- const startEvent = state.eventBuilder.build('llm_call', {
423
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
424
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
260
425
  model,
261
- provider: 'anthropic',
262
- api: 'completions',
263
- prompt: String(prompt).slice(0, 1000),
264
- max_tokens_to_sample: kwargs.max_tokens_to_sample,
265
- temperature: kwargs.temperature,
266
- }, {
426
+ requestPayload,
267
427
  dataClassification,
268
428
  purpose,
269
429
  reason,
430
+ provider: 'anthropic',
431
+ spanName: 'llm_call:anthropic.completions',
432
+ });
433
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
434
+ const event = state.eventBuilder.build('llm_call', {
435
+ model,
436
+ provider: 'anthropic',
437
+ api: 'completions',
438
+ prompt: String(prompt).slice(0, 1000),
439
+ max_tokens_to_sample: kwargs.max_tokens_to_sample,
440
+ temperature: kwargs.temperature,
441
+ status: 'started',
442
+ }, {
443
+ dataClassification,
444
+ purpose,
445
+ reason,
446
+ });
447
+ (0, runtime_1.emitEvent)(event);
448
+ return event;
270
449
  });
271
- (0, runtime_1.emitEvent)(startEvent);
272
450
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
273
451
  try {
274
- const response = await originalFn(...args);
452
+ const response = await originalFn.apply(this, args);
275
453
  const completionData = {
276
454
  model: response.model || model,
277
455
  };
@@ -281,25 +459,52 @@ function wrapCompletions(originalFn, dataClassification, purpose, reason) {
281
459
  if (response.stop_reason) {
282
460
  completionData.stop_reason = response.stop_reason;
283
461
  }
284
- const completionEvent = state.eventBuilder.build('llm_call', completionData, {
462
+ (0, context_1.runInContext)(trace.context, () => {
463
+ const completionEvent = state.eventBuilder.build('llm_call', { ...completionData, status: 'success' }, {
464
+ dataClassification,
465
+ purpose,
466
+ parentEventId: startEvent.event_id,
467
+ });
468
+ (0, runtime_1.emitEvent)(completionEvent);
469
+ });
470
+ await (0, governance_1.postflightLlmCall)({
471
+ state,
472
+ trace,
473
+ model,
474
+ response,
285
475
  dataClassification,
286
476
  purpose,
287
- parentEventId: startEvent.event_id,
477
+ reason,
288
478
  });
289
- (0, runtime_1.emitEvent)(completionEvent);
290
479
  return response;
291
480
  }
292
481
  catch (error) {
293
- const errorEvent = state.eventBuilder.build('llm_call', {
482
+ if (isGovernanceError(error)) {
483
+ throw error;
484
+ }
485
+ (0, context_1.runInContext)(trace.context, () => {
486
+ const errorEvent = state.eventBuilder.build('llm_call', {
487
+ model,
488
+ error: error.message || String(error),
489
+ error_type: error.constructor?.name || 'Error',
490
+ status: 'error',
491
+ }, {
492
+ dataClassification,
493
+ purpose,
494
+ parentEventId: startEvent.event_id,
495
+ });
496
+ (0, runtime_1.emitEvent)(errorEvent);
497
+ });
498
+ await (0, governance_1.postflightLlmCall)({
499
+ state,
500
+ trace,
294
501
  model,
295
- error: error.message || String(error),
296
- error_type: error.constructor?.name || 'Error',
297
- }, {
502
+ response: null,
298
503
  dataClassification,
299
504
  purpose,
300
- parentEventId: startEvent.event_id,
505
+ reason,
506
+ error: true,
301
507
  });
302
- (0, runtime_1.emitEvent)(errorEvent);
303
508
  throw error;
304
509
  }
305
510
  };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared governance helpers for SDK integrations.
3
+ */
4
+ import { ensureState } from '../runtime';
5
+ import type { Span, TraceContext } from '../context';
6
+ export interface LlmTrace {
7
+ span: Span;
8
+ context: TraceContext;
9
+ isRoot: boolean;
10
+ }
11
+ export declare function preflightLlmCall(options: {
12
+ model?: string;
13
+ requestPayload: any;
14
+ dataClassification: string;
15
+ purpose: string;
16
+ reason?: string;
17
+ provider?: string;
18
+ spanName: string;
19
+ }): {
20
+ state: ReturnType<typeof ensureState>;
21
+ trace: LlmTrace;
22
+ };
23
+ export declare function postflightLlmCall(options: {
24
+ state: ReturnType<typeof ensureState>;
25
+ trace: LlmTrace;
26
+ model?: string;
27
+ response: any;
28
+ dataClassification: string;
29
+ purpose: string;
30
+ reason?: string;
31
+ error?: boolean;
32
+ }): Promise<void>;
33
+ //# sourceMappingURL=governance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"governance.d.ts","sourceRoot":"","sources":["../../src/integrations/governance.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,WAAW,EAIZ,MAAM,YAAY,CAAC;AAYpB,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIrD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,OAAO,CAAC;CACjB;AA6DD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,GAAG,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG;IAAE,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,CAoH7D;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACtC,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2ChB"}