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
@@ -21,8 +21,18 @@
21
21
  */
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.patchOpenAI = patchOpenAI;
24
+ exports.wrapChatCompletions = wrapChatCompletions;
25
+ exports.wrapCompletions = wrapCompletions;
26
+ exports.wrapEmbeddings = wrapEmbeddings;
27
+ exports.wrapResponsesStreamMethod = wrapResponsesStreamMethod;
28
+ exports.wrapResponses = wrapResponses;
24
29
  const runtime_1 = require("../runtime");
30
+ const data_handling_1 = require("../data_handling");
31
+ const policy_1 = require("../policy");
32
+ const quotas_1 = require("../quotas");
33
+ const context_1 = require("../context");
25
34
  const lineage_1 = require("../lineage");
35
+ const governance_1 = require("./governance");
26
36
  /**
27
37
  * Patch an OpenAI client to automatically trace all API calls.
28
38
  */
@@ -43,6 +53,20 @@ function patchOpenAI(client, options = {}) {
43
53
  const originalCreate = client.embeddings.create.bind(client.embeddings);
44
54
  client.embeddings.create = wrapEmbeddings(originalCreate, dataClassification, purpose, reason);
45
55
  }
56
+ // Patch responses API (OpenAI Responses)
57
+ if (client.responses) {
58
+ const originalCreate = client.responses.create.bind(client.responses);
59
+ client.responses.create = wrapResponses(originalCreate, dataClassification, purpose, reason);
60
+ if (client.responses.stream) {
61
+ const originalStream = client.responses.stream.bind(client.responses);
62
+ client.responses.stream = wrapResponsesStreamMethod(originalStream, dataClassification, purpose, reason);
63
+ }
64
+ }
65
+ }
66
+ function isGovernanceError(error) {
67
+ return (error instanceof data_handling_1.DataHandlingViolation ||
68
+ error instanceof policy_1.PolicyViolation ||
69
+ error instanceof quotas_1.QuotaExceededError);
46
70
  }
47
71
  function wrapChatCompletions(originalFn, dataClassification, purpose, reason) {
48
72
  return async function wrappedChatCompletions(...args) {
@@ -50,28 +74,49 @@ function wrapChatCompletions(originalFn, dataClassification, purpose, reason) {
50
74
  const model = kwargs.model || 'unknown';
51
75
  const messages = kwargs.messages || [];
52
76
  const isStreaming = kwargs.stream === true;
53
- const state = (0, runtime_1.ensureState)();
54
- const startEvent = state.eventBuilder.build('llm_call', {
77
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
78
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
55
79
  model,
56
- provider: 'openai',
57
- api: 'chat.completions',
58
- num_messages: messages.length,
59
- messages: messages.slice(0, 10),
60
- stream: isStreaming,
61
- temperature: kwargs.temperature,
62
- max_tokens: kwargs.max_tokens,
63
- top_p: kwargs.top_p,
64
- }, {
80
+ requestPayload,
65
81
  dataClassification,
66
82
  purpose,
67
83
  reason,
84
+ provider: 'openai',
85
+ spanName: 'llm_call:openai.chat.completions',
86
+ });
87
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
88
+ const event = state.eventBuilder.build('llm_call', {
89
+ model,
90
+ provider: 'openai',
91
+ api: 'chat.completions',
92
+ num_messages: messages.length,
93
+ messages: messages.slice(0, 10),
94
+ stream: isStreaming,
95
+ temperature: kwargs.temperature,
96
+ max_tokens: kwargs.max_tokens,
97
+ top_p: kwargs.top_p,
98
+ status: 'started',
99
+ }, {
100
+ dataClassification,
101
+ purpose,
102
+ reason,
103
+ });
104
+ (0, runtime_1.emitEvent)(event);
105
+ return event;
68
106
  });
69
- (0, runtime_1.emitEvent)(startEvent);
70
107
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
71
108
  try {
72
- const response = await originalFn(...args);
109
+ const response = await originalFn.apply(this, args);
73
110
  if (isStreaming) {
74
- return wrapStreamingResponse(response, model, startEvent.event_id, dataClassification, purpose, state);
111
+ return wrapStreamingResponse(response, {
112
+ model,
113
+ parentEventId: startEvent.event_id,
114
+ dataClassification,
115
+ purpose,
116
+ reason,
117
+ state,
118
+ trace,
119
+ });
75
120
  }
76
121
  // Non-streaming response
77
122
  const completionData = {
@@ -94,33 +139,65 @@ function wrapChatCompletions(originalFn, dataClassification, purpose, reason) {
94
139
  },
95
140
  }));
96
141
  }
97
- const completionEvent = state.eventBuilder.build('llm_call', completionData, {
142
+ (0, context_1.runInContext)(trace.context, () => {
143
+ const completionEvent = state.eventBuilder.build('llm_call', {
144
+ ...completionData,
145
+ status: 'success',
146
+ }, {
147
+ dataClassification,
148
+ purpose,
149
+ parentEventId: startEvent.event_id,
150
+ });
151
+ (0, runtime_1.emitEvent)(completionEvent);
152
+ });
153
+ await (0, governance_1.postflightLlmCall)({
154
+ state,
155
+ trace,
156
+ model,
157
+ response,
98
158
  dataClassification,
99
159
  purpose,
100
- parentEventId: startEvent.event_id,
160
+ reason,
101
161
  });
102
- (0, runtime_1.emitEvent)(completionEvent);
103
162
  return response;
104
163
  }
105
164
  catch (error) {
106
- const errorEvent = state.eventBuilder.build('llm_call', {
165
+ if (isGovernanceError(error)) {
166
+ throw error;
167
+ }
168
+ (0, context_1.runInContext)(trace.context, () => {
169
+ const errorEvent = state.eventBuilder.build('llm_call', {
170
+ model,
171
+ error: error.message || String(error),
172
+ error_type: error.constructor?.name || 'Error',
173
+ status: 'error',
174
+ }, {
175
+ dataClassification,
176
+ purpose,
177
+ parentEventId: startEvent.event_id,
178
+ });
179
+ (0, runtime_1.emitEvent)(errorEvent);
180
+ });
181
+ await (0, governance_1.postflightLlmCall)({
182
+ state,
183
+ trace,
107
184
  model,
108
- error: error.message || String(error),
109
- error_type: error.constructor?.name || 'Error',
110
- }, {
185
+ response: null,
111
186
  dataClassification,
112
187
  purpose,
113
- parentEventId: startEvent.event_id,
188
+ reason,
189
+ error: true,
114
190
  });
115
- (0, runtime_1.emitEvent)(errorEvent);
116
191
  throw error;
117
192
  }
118
193
  };
119
194
  }
120
- async function* wrapStreamingResponse(stream, model, parentEventId, dataClassification, purpose, state) {
195
+ async function* wrapStreamingResponse(stream, options) {
121
196
  let accumulatedContent = '';
122
197
  let finishReason = null;
123
198
  let role = null;
199
+ let usage = null;
200
+ let error = null;
124
201
  try {
125
202
  for await (const chunk of stream) {
126
203
  // Track content from streaming chunks
@@ -136,24 +213,306 @@ async function* wrapStreamingResponse(stream, model, parentEventId, dataClassifi
136
213
  finishReason = choice.finish_reason;
137
214
  }
138
215
  }
216
+ if (chunk.usage) {
217
+ usage = chunk.usage;
218
+ }
139
219
  yield chunk;
140
220
  }
141
221
  }
222
+ catch (err) {
223
+ error = err;
224
+ throw err;
225
+ }
142
226
  finally {
143
- // Emit completion event when stream ends
144
- const completionEvent = state.eventBuilder.build('llm_call', {
145
- model,
146
- stream_complete: true,
147
- content: accumulatedContent.slice(0, 500) || null,
148
- content_length: accumulatedContent.length,
149
- finish_reason: finishReason,
150
- role,
151
- }, {
152
- dataClassification,
153
- purpose,
154
- parentEventId,
227
+ const responseStub = usage ? { usage } : null;
228
+ if (error) {
229
+ (0, context_1.runInContext)(options.trace.context, () => {
230
+ const errorEvent = options.state.eventBuilder.build('llm_call', {
231
+ model: options.model,
232
+ error: error.message || String(error),
233
+ error_type: error.constructor?.name || 'Error',
234
+ status: 'error',
235
+ }, {
236
+ dataClassification: options.dataClassification,
237
+ purpose: options.purpose,
238
+ parentEventId: options.parentEventId,
239
+ });
240
+ (0, runtime_1.emitEvent)(errorEvent);
241
+ });
242
+ await (0, governance_1.postflightLlmCall)({
243
+ state: options.state,
244
+ trace: options.trace,
245
+ model: options.model,
246
+ response: null,
247
+ dataClassification: options.dataClassification,
248
+ purpose: options.purpose,
249
+ reason: options.reason,
250
+ error: true,
251
+ });
252
+ }
253
+ if (!error) {
254
+ // Emit completion event when stream ends
255
+ (0, context_1.runInContext)(options.trace.context, () => {
256
+ const completionEvent = options.state.eventBuilder.build('llm_call', {
257
+ model: options.model,
258
+ stream_complete: true,
259
+ content: accumulatedContent.slice(0, 500) || null,
260
+ content_length: accumulatedContent.length,
261
+ finish_reason: finishReason,
262
+ role,
263
+ usage: usage || undefined,
264
+ status: 'success',
265
+ }, {
266
+ dataClassification: options.dataClassification,
267
+ purpose: options.purpose,
268
+ parentEventId: options.parentEventId,
269
+ });
270
+ (0, runtime_1.emitEvent)(completionEvent);
271
+ });
272
+ await (0, governance_1.postflightLlmCall)({
273
+ state: options.state,
274
+ trace: options.trace,
275
+ model: options.model,
276
+ response: responseStub,
277
+ dataClassification: options.dataClassification,
278
+ purpose: options.purpose,
279
+ reason: options.reason,
280
+ });
281
+ }
282
+ }
283
+ }
284
+ function formatInputPreview(input) {
285
+ if (typeof input === 'string') {
286
+ return input.slice(0, 500);
287
+ }
288
+ try {
289
+ return JSON.stringify(input).slice(0, 500);
290
+ }
291
+ catch {
292
+ return String(input).slice(0, 500);
293
+ }
294
+ }
295
+ function extractResponseText(chunk) {
296
+ if (!chunk) {
297
+ return null;
298
+ }
299
+ if (typeof chunk === 'string') {
300
+ return chunk;
301
+ }
302
+ if (typeof chunk.output_text === 'string') {
303
+ return chunk.output_text;
304
+ }
305
+ if (typeof chunk.text === 'string') {
306
+ return chunk.text;
307
+ }
308
+ if (typeof chunk.content === 'string') {
309
+ return chunk.content;
310
+ }
311
+ if (typeof chunk.delta === 'string') {
312
+ return chunk.delta;
313
+ }
314
+ if (chunk.type === 'response.output_text.delta' && typeof chunk.delta === 'string') {
315
+ return chunk.delta;
316
+ }
317
+ const response = chunk.response ?? chunk.data ?? null;
318
+ if (response) {
319
+ if (typeof response.output_text === 'string') {
320
+ return response.output_text;
321
+ }
322
+ if (typeof response.text === 'string') {
323
+ return response.text;
324
+ }
325
+ if (typeof response.content === 'string') {
326
+ return response.content;
327
+ }
328
+ }
329
+ return null;
330
+ }
331
+ function extractResponseUsage(chunk) {
332
+ if (!chunk) {
333
+ return null;
334
+ }
335
+ const usage = chunk.usage ?? chunk.response?.usage ?? chunk.data?.usage;
336
+ if (usage && typeof usage === 'object') {
337
+ return usage;
338
+ }
339
+ return null;
340
+ }
341
+ async function* wrapResponsesStream(stream, options) {
342
+ let accumulatedContent = '';
343
+ let usage = null;
344
+ let error = null;
345
+ try {
346
+ for await (const chunk of stream) {
347
+ const text = extractResponseText(chunk);
348
+ if (text) {
349
+ accumulatedContent += text;
350
+ }
351
+ const chunkUsage = extractResponseUsage(chunk);
352
+ if (chunkUsage) {
353
+ usage = chunkUsage;
354
+ }
355
+ yield chunk;
356
+ }
357
+ }
358
+ catch (err) {
359
+ error = err;
360
+ throw err;
361
+ }
362
+ finally {
363
+ const responseStub = usage ? { usage } : null;
364
+ if (error) {
365
+ (0, context_1.runInContext)(options.trace.context, () => {
366
+ const errorEvent = options.state.eventBuilder.build('llm_call', {
367
+ model: options.model,
368
+ error: error.message || String(error),
369
+ error_type: error.constructor?.name || 'Error',
370
+ status: 'error',
371
+ }, {
372
+ dataClassification: options.dataClassification,
373
+ purpose: options.purpose,
374
+ parentEventId: options.parentEventId,
375
+ });
376
+ (0, runtime_1.emitEvent)(errorEvent);
377
+ });
378
+ await (0, governance_1.postflightLlmCall)({
379
+ state: options.state,
380
+ trace: options.trace,
381
+ model: options.model,
382
+ response: null,
383
+ dataClassification: options.dataClassification,
384
+ purpose: options.purpose,
385
+ reason: options.reason,
386
+ error: true,
387
+ });
388
+ throw error;
389
+ }
390
+ (0, context_1.runInContext)(options.trace.context, () => {
391
+ const completionEvent = options.state.eventBuilder.build('llm_call', {
392
+ model: options.model,
393
+ stream_complete: true,
394
+ content: accumulatedContent.slice(0, 500) || null,
395
+ content_length: accumulatedContent.length,
396
+ usage: usage || undefined,
397
+ status: 'success',
398
+ }, {
399
+ dataClassification: options.dataClassification,
400
+ purpose: options.purpose,
401
+ parentEventId: options.parentEventId,
402
+ });
403
+ (0, runtime_1.emitEvent)(completionEvent);
155
404
  });
156
- (0, runtime_1.emitEvent)(completionEvent);
405
+ await (0, governance_1.postflightLlmCall)({
406
+ state: options.state,
407
+ trace: options.trace,
408
+ model: options.model,
409
+ response: responseStub,
410
+ dataClassification: options.dataClassification,
411
+ purpose: options.purpose,
412
+ reason: options.reason,
413
+ });
414
+ }
415
+ }
416
+ class ResponsesStreamManagerWrapper {
417
+ constructor(streamManager, model, parentEventId, dataClassification, purpose, reason, state, trace) {
418
+ this.accumulatedContent = '';
419
+ this.usage = null;
420
+ this.streamManager = streamManager;
421
+ this.model = model;
422
+ this.parentEventId = parentEventId;
423
+ this.dataClassification = dataClassification;
424
+ this.purpose = purpose;
425
+ this.reason = reason;
426
+ this.state = state;
427
+ this.trace = trace;
428
+ }
429
+ async *[Symbol.asyncIterator]() {
430
+ let error = null;
431
+ try {
432
+ for await (const chunk of this.streamManager) {
433
+ const text = extractResponseText(chunk);
434
+ if (text) {
435
+ this.accumulatedContent += text;
436
+ }
437
+ const chunkUsage = extractResponseUsage(chunk);
438
+ if (chunkUsage) {
439
+ this.usage = chunkUsage;
440
+ }
441
+ yield chunk;
442
+ }
443
+ }
444
+ catch (err) {
445
+ error = err;
446
+ throw err;
447
+ }
448
+ finally {
449
+ await this.emitCompletion(error);
450
+ }
451
+ }
452
+ async emitCompletion(error) {
453
+ if (error) {
454
+ (0, context_1.runInContext)(this.trace.context, () => {
455
+ const errorEvent = this.state.eventBuilder.build('llm_call', {
456
+ model: this.model,
457
+ error: error.message || String(error),
458
+ error_type: error.constructor?.name || 'Error',
459
+ status: 'error',
460
+ }, {
461
+ dataClassification: this.dataClassification,
462
+ purpose: this.purpose,
463
+ parentEventId: this.parentEventId,
464
+ });
465
+ (0, runtime_1.emitEvent)(errorEvent);
466
+ });
467
+ await (0, governance_1.postflightLlmCall)({
468
+ state: this.state,
469
+ trace: this.trace,
470
+ model: this.model,
471
+ response: null,
472
+ dataClassification: this.dataClassification,
473
+ purpose: this.purpose,
474
+ reason: this.reason,
475
+ error: true,
476
+ });
477
+ return;
478
+ }
479
+ (0, context_1.runInContext)(this.trace.context, () => {
480
+ const completionEvent = this.state.eventBuilder.build('llm_call', {
481
+ model: this.model,
482
+ stream_complete: true,
483
+ content: this.accumulatedContent.slice(0, 500) || null,
484
+ content_length: this.accumulatedContent.length,
485
+ usage: this.usage || undefined,
486
+ status: 'success',
487
+ }, {
488
+ dataClassification: this.dataClassification,
489
+ purpose: this.purpose,
490
+ parentEventId: this.parentEventId,
491
+ });
492
+ (0, runtime_1.emitEvent)(completionEvent);
493
+ });
494
+ await (0, governance_1.postflightLlmCall)({
495
+ state: this.state,
496
+ trace: this.trace,
497
+ model: this.model,
498
+ response: this.usage ? { usage: this.usage } : null,
499
+ dataClassification: this.dataClassification,
500
+ purpose: this.purpose,
501
+ reason: this.reason,
502
+ });
503
+ }
504
+ on(event, callback) {
505
+ this.streamManager.on?.(event, callback);
506
+ return this;
507
+ }
508
+ get controller() {
509
+ return this.streamManager.controller;
510
+ }
511
+ async finalResponse() {
512
+ return this.streamManager.finalResponse?.();
513
+ }
514
+ async getFinalResponse() {
515
+ return this.streamManager.getFinalResponse?.();
157
516
  }
158
517
  }
159
518
  function wrapCompletions(originalFn, dataClassification, purpose, reason) {
@@ -161,23 +520,36 @@ function wrapCompletions(originalFn, dataClassification, purpose, reason) {
161
520
  const kwargs = args[0] || {};
162
521
  const model = kwargs.model || 'unknown';
163
522
  const prompt = kwargs.prompt || '';
164
- const state = (0, runtime_1.ensureState)();
165
- const startEvent = state.eventBuilder.build('llm_call', {
523
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
524
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
166
525
  model,
167
- provider: 'openai',
168
- api: 'completions',
169
- prompt: String(prompt).slice(0, 1000),
170
- max_tokens: kwargs.max_tokens,
171
- temperature: kwargs.temperature,
172
- }, {
526
+ requestPayload,
173
527
  dataClassification,
174
528
  purpose,
175
529
  reason,
530
+ provider: 'openai',
531
+ spanName: 'llm_call:openai.completions',
532
+ });
533
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
534
+ const event = state.eventBuilder.build('llm_call', {
535
+ model,
536
+ provider: 'openai',
537
+ api: 'completions',
538
+ prompt: String(prompt).slice(0, 1000),
539
+ max_tokens: kwargs.max_tokens,
540
+ temperature: kwargs.temperature,
541
+ status: 'started',
542
+ }, {
543
+ dataClassification,
544
+ purpose,
545
+ reason,
546
+ });
547
+ (0, runtime_1.emitEvent)(event);
548
+ return event;
176
549
  });
177
- (0, runtime_1.emitEvent)(startEvent);
178
550
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
179
551
  try {
180
- const response = await originalFn(...args);
552
+ const response = await originalFn.apply(this, args);
181
553
  const completionData = {
182
554
  model: response.model || model,
183
555
  };
@@ -195,25 +567,55 @@ function wrapCompletions(originalFn, dataClassification, purpose, reason) {
195
567
  finish_reason: choice.finish_reason,
196
568
  }));
197
569
  }
198
- const completionEvent = state.eventBuilder.build('llm_call', completionData, {
570
+ (0, context_1.runInContext)(trace.context, () => {
571
+ const completionEvent = state.eventBuilder.build('llm_call', {
572
+ ...completionData,
573
+ status: 'success',
574
+ }, {
575
+ dataClassification,
576
+ purpose,
577
+ parentEventId: startEvent.event_id,
578
+ });
579
+ (0, runtime_1.emitEvent)(completionEvent);
580
+ });
581
+ await (0, governance_1.postflightLlmCall)({
582
+ state,
583
+ trace,
584
+ model,
585
+ response,
199
586
  dataClassification,
200
587
  purpose,
201
- parentEventId: startEvent.event_id,
588
+ reason,
202
589
  });
203
- (0, runtime_1.emitEvent)(completionEvent);
204
590
  return response;
205
591
  }
206
592
  catch (error) {
207
- const errorEvent = state.eventBuilder.build('llm_call', {
593
+ if (isGovernanceError(error)) {
594
+ throw error;
595
+ }
596
+ (0, context_1.runInContext)(trace.context, () => {
597
+ const errorEvent = state.eventBuilder.build('llm_call', {
598
+ model,
599
+ error: error.message || String(error),
600
+ error_type: error.constructor?.name || 'Error',
601
+ status: 'error',
602
+ }, {
603
+ dataClassification,
604
+ purpose,
605
+ parentEventId: startEvent.event_id,
606
+ });
607
+ (0, runtime_1.emitEvent)(errorEvent);
608
+ });
609
+ await (0, governance_1.postflightLlmCall)({
610
+ state,
611
+ trace,
208
612
  model,
209
- error: error.message || String(error),
210
- error_type: error.constructor?.name || 'Error',
211
- }, {
613
+ response: null,
212
614
  dataClassification,
213
615
  purpose,
214
- parentEventId: startEvent.event_id,
616
+ reason,
617
+ error: true,
215
618
  });
216
- (0, runtime_1.emitEvent)(errorEvent);
217
619
  throw error;
218
620
  }
219
621
  };
@@ -227,22 +629,35 @@ function wrapEmbeddings(originalFn, dataClassification, purpose, reason) {
227
629
  const inputPreview = Array.isArray(input)
228
630
  ? input.slice(0, 3)
229
631
  : [String(input).slice(0, 500)];
230
- const state = (0, runtime_1.ensureState)();
231
- const startEvent = state.eventBuilder.build('llm_call', {
632
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
633
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
232
634
  model,
233
- provider: 'openai',
234
- api: 'embeddings',
235
- num_inputs: numInputs,
236
- input_preview: inputPreview,
237
- }, {
635
+ requestPayload,
238
636
  dataClassification,
239
637
  purpose,
240
638
  reason,
639
+ provider: 'openai',
640
+ spanName: 'llm_call:openai.embeddings',
641
+ });
642
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
643
+ const event = state.eventBuilder.build('llm_call', {
644
+ model,
645
+ provider: 'openai',
646
+ api: 'embeddings',
647
+ num_inputs: numInputs,
648
+ input_preview: inputPreview,
649
+ status: 'started',
650
+ }, {
651
+ dataClassification,
652
+ purpose,
653
+ reason,
654
+ });
655
+ (0, runtime_1.emitEvent)(event);
656
+ return event;
241
657
  });
242
- (0, runtime_1.emitEvent)(startEvent);
243
658
  (0, lineage_1.setCurrentEvent)(startEvent.event_id);
244
659
  try {
245
- const response = await originalFn(...args);
660
+ const response = await originalFn.apply(this, args);
246
661
  const completionData = {
247
662
  model: response.model || model,
248
663
  num_embeddings: response.data?.length || 0,
@@ -253,25 +668,210 @@ function wrapEmbeddings(originalFn, dataClassification, purpose, reason) {
253
668
  total_tokens: response.usage.total_tokens,
254
669
  };
255
670
  }
256
- const completionEvent = state.eventBuilder.build('llm_call', completionData, {
671
+ (0, context_1.runInContext)(trace.context, () => {
672
+ const completionEvent = state.eventBuilder.build('llm_call', {
673
+ ...completionData,
674
+ status: 'success',
675
+ }, {
676
+ dataClassification,
677
+ purpose,
678
+ parentEventId: startEvent.event_id,
679
+ });
680
+ (0, runtime_1.emitEvent)(completionEvent);
681
+ });
682
+ await (0, governance_1.postflightLlmCall)({
683
+ state,
684
+ trace,
685
+ model,
686
+ response,
257
687
  dataClassification,
258
688
  purpose,
259
- parentEventId: startEvent.event_id,
689
+ reason,
260
690
  });
261
- (0, runtime_1.emitEvent)(completionEvent);
262
691
  return response;
263
692
  }
264
693
  catch (error) {
265
- const errorEvent = state.eventBuilder.build('llm_call', {
694
+ if (isGovernanceError(error)) {
695
+ throw error;
696
+ }
697
+ (0, context_1.runInContext)(trace.context, () => {
698
+ const errorEvent = state.eventBuilder.build('llm_call', {
699
+ model,
700
+ error: error.message || String(error),
701
+ error_type: error.constructor?.name || 'Error',
702
+ status: 'error',
703
+ }, {
704
+ dataClassification,
705
+ purpose,
706
+ parentEventId: startEvent.event_id,
707
+ });
708
+ (0, runtime_1.emitEvent)(errorEvent);
709
+ });
710
+ await (0, governance_1.postflightLlmCall)({
711
+ state,
712
+ trace,
713
+ model,
714
+ response: null,
715
+ dataClassification,
716
+ purpose,
717
+ reason,
718
+ error: true,
719
+ });
720
+ throw error;
721
+ }
722
+ };
723
+ }
724
+ function wrapResponsesStreamMethod(originalFn, dataClassification, purpose, reason) {
725
+ return function wrappedResponsesStream(...args) {
726
+ const kwargs = args[0] || {};
727
+ const model = kwargs.model || 'unknown';
728
+ const input = kwargs.input ?? '';
729
+ const numInputs = Array.isArray(input) ? input.length : 1;
730
+ const inputPreview = Array.isArray(input)
731
+ ? input.slice(0, 3).map((item) => formatInputPreview(item))
732
+ : [formatInputPreview(input)];
733
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
734
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
735
+ model,
736
+ requestPayload,
737
+ dataClassification,
738
+ purpose,
739
+ reason,
740
+ provider: 'openai',
741
+ spanName: 'llm_call:openai.responses.stream',
742
+ });
743
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
744
+ const event = state.eventBuilder.build('llm_call', {
266
745
  model,
267
- error: error.message || String(error),
268
- error_type: error.constructor?.name || 'Error',
746
+ provider: 'openai',
747
+ api: 'responses.stream',
748
+ num_inputs: numInputs,
749
+ input_preview: inputPreview,
750
+ stream: true,
751
+ status: 'started',
269
752
  }, {
270
753
  dataClassification,
271
754
  purpose,
272
- parentEventId: startEvent.event_id,
755
+ reason,
756
+ });
757
+ (0, runtime_1.emitEvent)(event);
758
+ return event;
759
+ });
760
+ (0, lineage_1.setCurrentEvent)(startEvent.event_id);
761
+ const streamManager = originalFn.apply(this, args);
762
+ return new ResponsesStreamManagerWrapper(streamManager, model, startEvent.event_id, dataClassification, purpose, reason, state, trace);
763
+ };
764
+ }
765
+ function wrapResponses(originalFn, dataClassification, purpose, reason) {
766
+ return async function wrappedResponses(...args) {
767
+ const kwargs = args[0] || {};
768
+ const model = kwargs.model || 'unknown';
769
+ const input = kwargs.input ?? '';
770
+ const isStreaming = kwargs.stream === true;
771
+ const numInputs = Array.isArray(input) ? input.length : 1;
772
+ const inputPreview = Array.isArray(input)
773
+ ? input.slice(0, 3).map((item) => formatInputPreview(item))
774
+ : [formatInputPreview(input)];
775
+ const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
776
+ const { state, trace } = (0, governance_1.preflightLlmCall)({
777
+ model,
778
+ requestPayload,
779
+ dataClassification,
780
+ purpose,
781
+ reason,
782
+ provider: 'openai',
783
+ spanName: 'llm_call:openai.responses',
784
+ });
785
+ const startEvent = (0, context_1.runInContext)(trace.context, () => {
786
+ const event = state.eventBuilder.build('llm_call', {
787
+ model,
788
+ provider: 'openai',
789
+ api: 'responses',
790
+ num_inputs: numInputs,
791
+ input_preview: inputPreview,
792
+ stream: isStreaming,
793
+ status: 'started',
794
+ }, {
795
+ dataClassification,
796
+ purpose,
797
+ reason,
798
+ });
799
+ (0, runtime_1.emitEvent)(event);
800
+ return event;
801
+ });
802
+ (0, lineage_1.setCurrentEvent)(startEvent.event_id);
803
+ try {
804
+ const response = await originalFn.apply(this, args);
805
+ if (isStreaming) {
806
+ return wrapResponsesStream(response, {
807
+ model,
808
+ parentEventId: startEvent.event_id,
809
+ dataClassification,
810
+ purpose,
811
+ reason,
812
+ state,
813
+ trace,
814
+ });
815
+ }
816
+ const completionData = {
817
+ model: response.model || model,
818
+ };
819
+ if (response.usage) {
820
+ completionData.usage = response.usage;
821
+ }
822
+ if (typeof response.output_text === 'string') {
823
+ completionData.output_text = response.output_text.slice(0, 500);
824
+ completionData.output_length = response.output_text.length;
825
+ }
826
+ (0, context_1.runInContext)(trace.context, () => {
827
+ const completionEvent = state.eventBuilder.build('llm_call', {
828
+ ...completionData,
829
+ status: 'success',
830
+ }, {
831
+ dataClassification,
832
+ purpose,
833
+ parentEventId: startEvent.event_id,
834
+ });
835
+ (0, runtime_1.emitEvent)(completionEvent);
836
+ });
837
+ await (0, governance_1.postflightLlmCall)({
838
+ state,
839
+ trace,
840
+ model,
841
+ response,
842
+ dataClassification,
843
+ purpose,
844
+ reason,
845
+ });
846
+ return response;
847
+ }
848
+ catch (error) {
849
+ if (isGovernanceError(error)) {
850
+ throw error;
851
+ }
852
+ (0, context_1.runInContext)(trace.context, () => {
853
+ const errorEvent = state.eventBuilder.build('llm_call', {
854
+ model,
855
+ error: error.message || String(error),
856
+ error_type: error.constructor?.name || 'Error',
857
+ status: 'error',
858
+ }, {
859
+ dataClassification,
860
+ purpose,
861
+ parentEventId: startEvent.event_id,
862
+ });
863
+ (0, runtime_1.emitEvent)(errorEvent);
864
+ });
865
+ await (0, governance_1.postflightLlmCall)({
866
+ state,
867
+ trace,
868
+ model,
869
+ response: null,
870
+ dataClassification,
871
+ purpose,
872
+ reason,
873
+ error: true,
273
874
  });
274
- (0, runtime_1.emitEvent)(errorEvent);
275
875
  throw error;
276
876
  }
277
877
  };