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.
- package/README.md +441 -150
- package/dist/aims_governance.d.ts +238 -0
- package/dist/aims_governance.d.ts.map +1 -0
- package/dist/aims_governance.js +922 -0
- package/dist/alerts.d.ts +16 -0
- package/dist/alerts.d.ts.map +1 -1
- package/dist/alerts.js +16 -0
- package/dist/api.d.ts +6 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -0
- package/dist/assessment.d.ts +269 -0
- package/dist/assessment.d.ts.map +1 -0
- package/dist/assessment.js +1232 -0
- package/dist/attestation.js +23 -1
- package/dist/attribution.d.ts +349 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +987 -0
- package/dist/autodetect.d.ts +69 -1
- package/dist/autodetect.d.ts.map +1 -1
- package/dist/autodetect.js +644 -1
- package/dist/bias.d.ts +130 -0
- package/dist/bias.d.ts.map +1 -0
- package/dist/bias.js +223 -0
- package/dist/circuit_breaker.js +3 -3
- package/dist/cli/diagnostics.d.ts +5 -1
- package/dist/cli/diagnostics.d.ts.map +1 -1
- package/dist/cli/diagnostics.js +31 -8
- package/dist/cli/doctor.d.ts +25 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +381 -0
- package/dist/cli/fix.d.ts +16 -0
- package/dist/cli/fix.d.ts.map +1 -0
- package/dist/cli/fix.js +284 -0
- package/dist/cli/init.d.ts +57 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +205 -0
- package/dist/cli.js +1611 -126
- package/dist/complianceTargets.d.ts +111 -0
- package/dist/complianceTargets.d.ts.map +1 -0
- package/dist/complianceTargets.js +521 -0
- package/dist/config.d.ts +301 -17
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +428 -36
- package/dist/config_migrations.d.ts +41 -0
- package/dist/config_migrations.d.ts.map +1 -1
- package/dist/config_migrations.js +205 -0
- package/dist/config_schema.d.ts +2900 -731
- package/dist/config_schema.d.ts.map +1 -1
- package/dist/config_schema.js +257 -55
- package/dist/context.d.ts +34 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +118 -7
- package/dist/control_backbone.d.ts +122 -0
- package/dist/control_backbone.d.ts.map +1 -0
- package/dist/control_backbone.js +698 -0
- package/dist/data-governance.d.ts +187 -0
- package/dist/data-governance.d.ts.map +1 -0
- package/dist/data-governance.js +424 -0
- package/dist/dataResidency.d.ts +44 -0
- package/dist/dataResidency.d.ts.map +1 -0
- package/dist/dataResidency.js +203 -0
- package/dist/dispatcher.d.ts +32 -0
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +91 -4
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +38 -0
- package/dist/evidence_store.d.ts +103 -0
- package/dist/evidence_store.d.ts.map +1 -0
- package/dist/evidence_store.js +459 -0
- package/dist/executiveSummary.d.ts +65 -8
- package/dist/executiveSummary.d.ts.map +1 -1
- package/dist/executiveSummary.js +289 -26
- package/dist/identity.d.ts +143 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +231 -0
- package/dist/impact-assessment.d.ts +350 -0
- package/dist/impact-assessment.d.ts.map +1 -0
- package/dist/impact-assessment.js +580 -0
- package/dist/index.d.ts +25 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +300 -4
- package/dist/instrumentation.d.ts +1 -1
- package/dist/instrumentation.d.ts.map +1 -1
- package/dist/instrumentation.js +243 -27
- package/dist/integrations/anthropic.d.ts +3 -0
- package/dist/integrations/anthropic.d.ts.map +1 -1
- package/dist/integrations/anthropic.js +284 -79
- package/dist/integrations/governance.d.ts +33 -0
- package/dist/integrations/governance.d.ts.map +1 -0
- package/dist/integrations/governance.js +208 -0
- package/dist/integrations/langchain.d.ts +7 -0
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +387 -143
- package/dist/integrations/openai.d.ts +9 -0
- package/dist/integrations/openai.d.ts.map +1 -1
- package/dist/integrations/openai.js +673 -73
- package/dist/iso42001_consolidation.d.ts +16 -0
- package/dist/iso42001_consolidation.d.ts.map +1 -0
- package/dist/iso42001_consolidation.js +413 -0
- package/dist/iso42001_workflows.d.ts +263 -0
- package/dist/iso42001_workflows.d.ts.map +1 -0
- package/dist/iso42001_workflows.js +781 -0
- package/dist/lifecycle.d.ts +299 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +624 -0
- package/dist/lineage.d.ts +2 -2
- package/dist/lineage.d.ts.map +1 -1
- package/dist/lineage.js +12 -17
- package/dist/middleware/express.d.ts.map +1 -1
- package/dist/middleware/express.js +33 -3
- package/dist/middleware/nextjs.d.ts.map +1 -1
- package/dist/middleware/nextjs.js +42 -68
- package/dist/model.d.ts +143 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +371 -0
- package/dist/onboarding.d.ts +42 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +1022 -0
- package/dist/oversight.d.ts +264 -0
- package/dist/oversight.d.ts.map +1 -0
- package/dist/oversight.js +497 -0
- package/dist/pdf_report.d.ts.map +1 -1
- package/dist/pdf_report.js +42 -21
- package/dist/presets.d.ts +88 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +520 -0
- package/dist/propagation.d.ts.map +1 -1
- package/dist/propagation.js +34 -2
- package/dist/quotas.d.ts +171 -0
- package/dist/quotas.d.ts.map +1 -0
- package/dist/quotas.js +259 -0
- package/dist/register.d.ts +13 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +99 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/registryData.json +43 -6
- package/dist/report.d.ts +2 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +189 -2
- package/dist/reporting.d.ts +125 -0
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +196 -5
- package/dist/resources.d.ts +285 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +643 -0
- package/dist/risk.d.ts +120 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +220 -0
- package/dist/runtime.d.ts +74 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +598 -22
- package/dist/schemaInference.d.ts +92 -0
- package/dist/schemaInference.d.ts.map +1 -0
- package/dist/schemaInference.js +466 -0
- package/dist/schema_validation.js +2 -2
- package/dist/schemas/config.schema.json +169 -6
- package/dist/schemas/event.schema.json +4 -0
- package/dist/security_report.js +4 -4
- package/dist/signing.d.ts +1 -1
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +4 -0
- package/dist/sinks/file.d.ts +19 -1
- package/dist/sinks/file.d.ts.map +1 -1
- package/dist/sinks/file.js +82 -13
- package/dist/sinks/https.d.ts +10 -0
- package/dist/sinks/https.d.ts.map +1 -1
- package/dist/sinks/https.js +76 -16
- package/dist/sinks/stdout.d.ts +1 -0
- package/dist/sinks/stdout.d.ts.map +1 -1
- package/dist/sinks/stdout.js +12 -1
- package/dist/spec.d.ts +159 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +391 -0
- package/dist/stakeholders.d.ts +199 -0
- package/dist/stakeholders.d.ts.map +1 -0
- package/dist/stakeholders.js +398 -0
- package/dist/standards.d.ts.map +1 -1
- package/dist/standards.js +160 -2
- package/dist/standards_ingest.d.ts +2 -2
- package/dist/standards_ingest.d.ts.map +1 -1
- package/dist/standards_ingest.js +105 -23
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +7 -2
- package/dist/telemetry.d.ts +16 -2
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +79 -14
- package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
- package/dist/traced_emitter.d.ts +3 -0
- package/dist/traced_emitter.d.ts.map +1 -1
- package/dist/traced_emitter.js +142 -25
- package/dist/trust_package.d.ts +21 -1
- package/dist/trust_package.d.ts.map +1 -1
- package/dist/trust_package.js +101 -4
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +9 -2
- package/dist/wal.d.ts.map +1 -1
- package/dist/wal.js +2 -1
- package/package.json +14 -1
- package/scripts/postinstall.js +119 -97
- 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
|
|
54
|
-
const
|
|
77
|
+
const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
|
|
78
|
+
const { state, trace } = (0, governance_1.preflightLlmCall)({
|
|
55
79
|
model,
|
|
56
|
-
|
|
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(
|
|
109
|
+
const response = await originalFn.apply(this, args);
|
|
73
110
|
if (isStreaming) {
|
|
74
|
-
return wrapStreamingResponse(response,
|
|
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
|
-
|
|
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
|
-
|
|
160
|
+
reason,
|
|
101
161
|
});
|
|
102
|
-
(0, runtime_1.emitEvent)(completionEvent);
|
|
103
162
|
return response;
|
|
104
163
|
}
|
|
105
164
|
catch (error) {
|
|
106
|
-
|
|
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
|
-
|
|
109
|
-
error_type: error.constructor?.name || 'Error',
|
|
110
|
-
}, {
|
|
185
|
+
response: null,
|
|
111
186
|
dataClassification,
|
|
112
187
|
purpose,
|
|
113
|
-
|
|
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,
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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,
|
|
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
|
|
165
|
-
const
|
|
523
|
+
const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
|
|
524
|
+
const { state, trace } = (0, governance_1.preflightLlmCall)({
|
|
166
525
|
model,
|
|
167
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
588
|
+
reason,
|
|
202
589
|
});
|
|
203
|
-
(0, runtime_1.emitEvent)(completionEvent);
|
|
204
590
|
return response;
|
|
205
591
|
}
|
|
206
592
|
catch (error) {
|
|
207
|
-
|
|
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
|
-
|
|
210
|
-
error_type: error.constructor?.name || 'Error',
|
|
211
|
-
}, {
|
|
613
|
+
response: null,
|
|
212
614
|
dataClassification,
|
|
213
615
|
purpose,
|
|
214
|
-
|
|
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
|
|
231
|
-
const
|
|
632
|
+
const requestPayload = Object.keys(kwargs).length > 0 ? kwargs : { args };
|
|
633
|
+
const { state, trace } = (0, governance_1.preflightLlmCall)({
|
|
232
634
|
model,
|
|
233
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
689
|
+
reason,
|
|
260
690
|
});
|
|
261
|
-
(0, runtime_1.emitEvent)(completionEvent);
|
|
262
691
|
return response;
|
|
263
692
|
}
|
|
264
693
|
catch (error) {
|
|
265
|
-
|
|
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
|
-
|
|
268
|
-
|
|
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
|
-
|
|
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
|
};
|