@ax-llm/ax 12.0.19 → 12.0.21
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/index.cjs +2132 -121
- package/index.cjs.map +1 -1
- package/index.d.cts +178 -2
- package/index.d.ts +178 -2
- package/index.js +2125 -121
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -586,6 +586,16 @@ var apiCall = async (api, json) => {
|
|
|
586
586
|
import crypto2 from "crypto";
|
|
587
587
|
import { context, SpanKind } from "@opentelemetry/api";
|
|
588
588
|
|
|
589
|
+
// dsp/globals.ts
|
|
590
|
+
var axGlobals = {
|
|
591
|
+
signatureStrict: true,
|
|
592
|
+
// Controls reservedNames enforcement in signature parsing/validation
|
|
593
|
+
tracer: void 0,
|
|
594
|
+
// Global OpenTelemetry tracer for all AI operations
|
|
595
|
+
meter: void 0
|
|
596
|
+
// Global OpenTelemetry meter for metrics collection
|
|
597
|
+
};
|
|
598
|
+
|
|
589
599
|
// trace/trace.ts
|
|
590
600
|
var axSpanAttributes = {
|
|
591
601
|
// LLM
|
|
@@ -1021,6 +1031,326 @@ var logResponseDelta = (delta, logger = defaultLogger) => {
|
|
|
1021
1031
|
logger(delta, { tags: ["responseContent"] });
|
|
1022
1032
|
};
|
|
1023
1033
|
|
|
1034
|
+
// ai/metrics.ts
|
|
1035
|
+
var sanitizeLabels = (labels) => {
|
|
1036
|
+
const sanitized = {};
|
|
1037
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
1038
|
+
if (value !== void 0 && value !== null) {
|
|
1039
|
+
const stringValue = String(value);
|
|
1040
|
+
sanitized[key] = stringValue.length > 100 ? stringValue.substring(0, 100) : stringValue;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
return sanitized;
|
|
1044
|
+
};
|
|
1045
|
+
var globalAIMetricsInstruments;
|
|
1046
|
+
var getOrCreateAIMetricsInstruments = (meter) => {
|
|
1047
|
+
if (globalAIMetricsInstruments) {
|
|
1048
|
+
return globalAIMetricsInstruments;
|
|
1049
|
+
}
|
|
1050
|
+
if (meter) {
|
|
1051
|
+
globalAIMetricsInstruments = createMetricsInstruments(meter);
|
|
1052
|
+
return globalAIMetricsInstruments;
|
|
1053
|
+
}
|
|
1054
|
+
return void 0;
|
|
1055
|
+
};
|
|
1056
|
+
var createMetricsInstruments = (meter) => {
|
|
1057
|
+
return {
|
|
1058
|
+
latencyHistogram: meter.createHistogram("ax_llm_request_duration_ms", {
|
|
1059
|
+
description: "Duration of LLM requests in milliseconds",
|
|
1060
|
+
unit: "ms"
|
|
1061
|
+
}),
|
|
1062
|
+
errorCounter: meter.createCounter("ax_llm_errors_total", {
|
|
1063
|
+
description: "Total number of LLM request errors"
|
|
1064
|
+
}),
|
|
1065
|
+
requestCounter: meter.createCounter("ax_llm_requests_total", {
|
|
1066
|
+
description: "Total number of LLM requests"
|
|
1067
|
+
}),
|
|
1068
|
+
tokenCounter: meter.createCounter("ax_llm_tokens_total", {
|
|
1069
|
+
description: "Total number of LLM tokens consumed"
|
|
1070
|
+
}),
|
|
1071
|
+
inputTokenCounter: meter.createCounter("ax_llm_input_tokens_total", {
|
|
1072
|
+
description: "Total number of input/prompt tokens consumed"
|
|
1073
|
+
}),
|
|
1074
|
+
outputTokenCounter: meter.createCounter("ax_llm_output_tokens_total", {
|
|
1075
|
+
description: "Total number of output/completion tokens generated"
|
|
1076
|
+
}),
|
|
1077
|
+
errorRateGauge: meter.createGauge("ax_llm_error_rate", {
|
|
1078
|
+
description: "Current error rate as a percentage (0-100)"
|
|
1079
|
+
}),
|
|
1080
|
+
meanLatencyGauge: meter.createGauge("ax_llm_mean_latency_ms", {
|
|
1081
|
+
description: "Mean latency of LLM requests in milliseconds",
|
|
1082
|
+
unit: "ms"
|
|
1083
|
+
}),
|
|
1084
|
+
p95LatencyGauge: meter.createGauge("ax_llm_p95_latency_ms", {
|
|
1085
|
+
description: "95th percentile latency of LLM requests in milliseconds",
|
|
1086
|
+
unit: "ms"
|
|
1087
|
+
}),
|
|
1088
|
+
p99LatencyGauge: meter.createGauge("ax_llm_p99_latency_ms", {
|
|
1089
|
+
description: "99th percentile latency of LLM requests in milliseconds",
|
|
1090
|
+
unit: "ms"
|
|
1091
|
+
}),
|
|
1092
|
+
streamingRequestsCounter: meter.createCounter(
|
|
1093
|
+
"ax_llm_streaming_requests_total",
|
|
1094
|
+
{
|
|
1095
|
+
description: "Total number of streaming LLM requests"
|
|
1096
|
+
}
|
|
1097
|
+
),
|
|
1098
|
+
functionCallsCounter: meter.createCounter("ax_llm_function_calls_total", {
|
|
1099
|
+
description: "Total number of function/tool calls made"
|
|
1100
|
+
}),
|
|
1101
|
+
functionCallLatencyHistogram: meter.createHistogram(
|
|
1102
|
+
"ax_llm_function_call_latency_ms",
|
|
1103
|
+
{
|
|
1104
|
+
description: "Latency of function calls in milliseconds",
|
|
1105
|
+
unit: "ms"
|
|
1106
|
+
}
|
|
1107
|
+
),
|
|
1108
|
+
requestSizeHistogram: meter.createHistogram("ax_llm_request_size_bytes", {
|
|
1109
|
+
description: "Size of LLM request payloads in bytes",
|
|
1110
|
+
unit: "By"
|
|
1111
|
+
}),
|
|
1112
|
+
responseSizeHistogram: meter.createHistogram("ax_llm_response_size_bytes", {
|
|
1113
|
+
description: "Size of LLM response payloads in bytes",
|
|
1114
|
+
unit: "By"
|
|
1115
|
+
}),
|
|
1116
|
+
temperatureGauge: meter.createGauge("ax_llm_temperature_gauge", {
|
|
1117
|
+
description: "Temperature setting used for LLM requests"
|
|
1118
|
+
}),
|
|
1119
|
+
maxTokensGauge: meter.createGauge("ax_llm_max_tokens_gauge", {
|
|
1120
|
+
description: "Maximum tokens setting used for LLM requests"
|
|
1121
|
+
}),
|
|
1122
|
+
estimatedCostCounter: meter.createCounter("ax_llm_estimated_cost_total", {
|
|
1123
|
+
description: "Estimated cost of LLM requests in USD",
|
|
1124
|
+
unit: "$"
|
|
1125
|
+
}),
|
|
1126
|
+
promptLengthHistogram: meter.createHistogram("ax_llm_prompt_length_chars", {
|
|
1127
|
+
description: "Length of prompts in characters"
|
|
1128
|
+
}),
|
|
1129
|
+
contextWindowUsageGauge: meter.createGauge(
|
|
1130
|
+
"ax_llm_context_window_usage_ratio",
|
|
1131
|
+
{
|
|
1132
|
+
description: "Context window utilization ratio (0-1)"
|
|
1133
|
+
}
|
|
1134
|
+
),
|
|
1135
|
+
timeoutsCounter: meter.createCounter("ax_llm_timeouts_total", {
|
|
1136
|
+
description: "Total number of timed out LLM requests"
|
|
1137
|
+
}),
|
|
1138
|
+
abortsCounter: meter.createCounter("ax_llm_aborts_total", {
|
|
1139
|
+
description: "Total number of aborted LLM requests"
|
|
1140
|
+
}),
|
|
1141
|
+
thinkingBudgetUsageCounter: meter.createCounter(
|
|
1142
|
+
"ax_llm_thinking_budget_usage_total",
|
|
1143
|
+
{
|
|
1144
|
+
description: "Total thinking budget tokens used"
|
|
1145
|
+
}
|
|
1146
|
+
),
|
|
1147
|
+
multimodalRequestsCounter: meter.createCounter(
|
|
1148
|
+
"ax_llm_multimodal_requests_total",
|
|
1149
|
+
{
|
|
1150
|
+
description: "Total number of multimodal requests (with images/audio)"
|
|
1151
|
+
}
|
|
1152
|
+
)
|
|
1153
|
+
};
|
|
1154
|
+
};
|
|
1155
|
+
var recordLatencyMetric = (instruments, type, duration, aiService, model) => {
|
|
1156
|
+
try {
|
|
1157
|
+
if (instruments.latencyHistogram) {
|
|
1158
|
+
const labels = sanitizeLabels({
|
|
1159
|
+
operation: type,
|
|
1160
|
+
ai_service: aiService,
|
|
1161
|
+
...model ? { model } : {}
|
|
1162
|
+
});
|
|
1163
|
+
instruments.latencyHistogram.record(duration, labels);
|
|
1164
|
+
}
|
|
1165
|
+
} catch (error) {
|
|
1166
|
+
console.warn("Failed to record latency metric:", error);
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
var recordLatencyStatsMetrics = (instruments, type, meanLatency, p95Latency, p99Latency, aiService, model) => {
|
|
1170
|
+
const labels = {
|
|
1171
|
+
operation: type,
|
|
1172
|
+
ai_service: aiService,
|
|
1173
|
+
...model ? { model } : {}
|
|
1174
|
+
};
|
|
1175
|
+
if (instruments.meanLatencyGauge) {
|
|
1176
|
+
instruments.meanLatencyGauge.record(meanLatency, labels);
|
|
1177
|
+
}
|
|
1178
|
+
if (instruments.p95LatencyGauge) {
|
|
1179
|
+
instruments.p95LatencyGauge.record(p95Latency, labels);
|
|
1180
|
+
}
|
|
1181
|
+
if (instruments.p99LatencyGauge) {
|
|
1182
|
+
instruments.p99LatencyGauge.record(p99Latency, labels);
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
var recordErrorMetric = (instruments, type, aiService, model) => {
|
|
1186
|
+
try {
|
|
1187
|
+
if (instruments.errorCounter) {
|
|
1188
|
+
const labels = sanitizeLabels({
|
|
1189
|
+
operation: type,
|
|
1190
|
+
ai_service: aiService,
|
|
1191
|
+
...model ? { model } : {}
|
|
1192
|
+
});
|
|
1193
|
+
instruments.errorCounter.add(1, labels);
|
|
1194
|
+
}
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
console.warn("Failed to record error metric:", error);
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
var recordErrorRateMetric = (instruments, type, errorRate, aiService, model) => {
|
|
1200
|
+
if (instruments.errorRateGauge) {
|
|
1201
|
+
instruments.errorRateGauge.record(errorRate * 100, {
|
|
1202
|
+
// Convert to percentage
|
|
1203
|
+
operation: type,
|
|
1204
|
+
ai_service: aiService,
|
|
1205
|
+
...model ? { model } : {}
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
};
|
|
1209
|
+
var recordRequestMetric = (instruments, type, aiService, model) => {
|
|
1210
|
+
if (instruments.requestCounter) {
|
|
1211
|
+
instruments.requestCounter.add(1, {
|
|
1212
|
+
operation: type,
|
|
1213
|
+
ai_service: aiService,
|
|
1214
|
+
...model ? { model } : {}
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
var recordTokenMetric = (instruments, type, tokens, aiService, model) => {
|
|
1219
|
+
try {
|
|
1220
|
+
const labels = sanitizeLabels({
|
|
1221
|
+
ai_service: aiService,
|
|
1222
|
+
...model ? { model } : {}
|
|
1223
|
+
});
|
|
1224
|
+
if (instruments.tokenCounter) {
|
|
1225
|
+
instruments.tokenCounter.add(tokens, {
|
|
1226
|
+
token_type: type,
|
|
1227
|
+
...labels
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
if (type === "input" && instruments.inputTokenCounter) {
|
|
1231
|
+
instruments.inputTokenCounter.add(tokens, labels);
|
|
1232
|
+
}
|
|
1233
|
+
if (type === "output" && instruments.outputTokenCounter) {
|
|
1234
|
+
instruments.outputTokenCounter.add(tokens, labels);
|
|
1235
|
+
}
|
|
1236
|
+
} catch (error) {
|
|
1237
|
+
console.warn("Failed to record token metric:", error);
|
|
1238
|
+
}
|
|
1239
|
+
};
|
|
1240
|
+
var recordStreamingRequestMetric = (instruments, type, isStreaming, aiService, model) => {
|
|
1241
|
+
if (isStreaming && instruments.streamingRequestsCounter) {
|
|
1242
|
+
instruments.streamingRequestsCounter.add(1, {
|
|
1243
|
+
operation: type,
|
|
1244
|
+
ai_service: aiService,
|
|
1245
|
+
...model ? { model } : {}
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
var recordFunctionCallMetric = (instruments, functionName, latency, aiService, model) => {
|
|
1250
|
+
const labels = {
|
|
1251
|
+
function_name: functionName,
|
|
1252
|
+
...aiService ? { ai_service: aiService } : {},
|
|
1253
|
+
...model ? { model } : {}
|
|
1254
|
+
};
|
|
1255
|
+
if (instruments.functionCallsCounter) {
|
|
1256
|
+
instruments.functionCallsCounter.add(1, labels);
|
|
1257
|
+
}
|
|
1258
|
+
if (latency && instruments.functionCallLatencyHistogram) {
|
|
1259
|
+
instruments.functionCallLatencyHistogram.record(latency, labels);
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
var recordRequestSizeMetric = (instruments, type, sizeBytes, aiService, model) => {
|
|
1263
|
+
if (instruments.requestSizeHistogram) {
|
|
1264
|
+
instruments.requestSizeHistogram.record(sizeBytes, {
|
|
1265
|
+
operation: type,
|
|
1266
|
+
ai_service: aiService,
|
|
1267
|
+
...model ? { model } : {}
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
var recordResponseSizeMetric = (instruments, type, sizeBytes, aiService, model) => {
|
|
1272
|
+
if (instruments.responseSizeHistogram) {
|
|
1273
|
+
instruments.responseSizeHistogram.record(sizeBytes, {
|
|
1274
|
+
operation: type,
|
|
1275
|
+
ai_service: aiService,
|
|
1276
|
+
...model ? { model } : {}
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
var recordModelConfigMetrics = (instruments, temperature, maxTokens, aiService, model) => {
|
|
1281
|
+
const labels = {
|
|
1282
|
+
...aiService ? { ai_service: aiService } : {},
|
|
1283
|
+
...model ? { model } : {}
|
|
1284
|
+
};
|
|
1285
|
+
if (temperature !== void 0 && instruments.temperatureGauge) {
|
|
1286
|
+
instruments.temperatureGauge.record(temperature, labels);
|
|
1287
|
+
}
|
|
1288
|
+
if (maxTokens !== void 0 && instruments.maxTokensGauge) {
|
|
1289
|
+
instruments.maxTokensGauge.record(maxTokens, labels);
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
var recordEstimatedCostMetric = (instruments, type, costUSD, aiService, model) => {
|
|
1293
|
+
if (instruments.estimatedCostCounter) {
|
|
1294
|
+
instruments.estimatedCostCounter.add(costUSD, {
|
|
1295
|
+
operation: type,
|
|
1296
|
+
ai_service: aiService,
|
|
1297
|
+
...model ? { model } : {}
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
};
|
|
1301
|
+
var recordPromptLengthMetric = (instruments, lengthChars, aiService, model) => {
|
|
1302
|
+
if (instruments.promptLengthHistogram) {
|
|
1303
|
+
instruments.promptLengthHistogram.record(lengthChars, {
|
|
1304
|
+
ai_service: aiService,
|
|
1305
|
+
...model ? { model } : {}
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
};
|
|
1309
|
+
var recordContextWindowUsageMetric = (instruments, usageRatio, aiService, model) => {
|
|
1310
|
+
if (instruments.contextWindowUsageGauge) {
|
|
1311
|
+
instruments.contextWindowUsageGauge.record(usageRatio, {
|
|
1312
|
+
ai_service: aiService,
|
|
1313
|
+
...model ? { model } : {}
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
var recordTimeoutMetric = (instruments, type, aiService, model) => {
|
|
1318
|
+
if (instruments.timeoutsCounter) {
|
|
1319
|
+
instruments.timeoutsCounter.add(1, {
|
|
1320
|
+
operation: type,
|
|
1321
|
+
ai_service: aiService,
|
|
1322
|
+
...model ? { model } : {}
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
var recordAbortMetric = (instruments, type, aiService, model) => {
|
|
1327
|
+
if (instruments.abortsCounter) {
|
|
1328
|
+
instruments.abortsCounter.add(1, {
|
|
1329
|
+
operation: type,
|
|
1330
|
+
ai_service: aiService,
|
|
1331
|
+
...model ? { model } : {}
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1335
|
+
var recordThinkingBudgetUsageMetric = (instruments, tokensUsed, aiService, model) => {
|
|
1336
|
+
if (instruments.thinkingBudgetUsageCounter) {
|
|
1337
|
+
instruments.thinkingBudgetUsageCounter.add(tokensUsed, {
|
|
1338
|
+
ai_service: aiService,
|
|
1339
|
+
...model ? { model } : {}
|
|
1340
|
+
});
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
var recordMultimodalRequestMetric = (instruments, hasImages, hasAudio, aiService, model) => {
|
|
1344
|
+
if ((hasImages || hasAudio) && instruments.multimodalRequestsCounter) {
|
|
1345
|
+
instruments.multimodalRequestsCounter.add(1, {
|
|
1346
|
+
ai_service: aiService,
|
|
1347
|
+
has_images: hasImages.toString(),
|
|
1348
|
+
has_audio: hasAudio.toString(),
|
|
1349
|
+
...model ? { model } : {}
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1024
1354
|
// ai/base.ts
|
|
1025
1355
|
var axBaseAIDefaultConfig = () => structuredClone({
|
|
1026
1356
|
temperature: 0,
|
|
@@ -1051,7 +1381,8 @@ var AxBaseAI = class {
|
|
|
1051
1381
|
this.apiURL = apiURL;
|
|
1052
1382
|
this.headers = headers;
|
|
1053
1383
|
this.supportFor = supportFor;
|
|
1054
|
-
this.tracer = options.tracer;
|
|
1384
|
+
this.tracer = options.tracer ?? axGlobals.tracer;
|
|
1385
|
+
this.meter = options.meter ?? axGlobals.meter;
|
|
1055
1386
|
this.modelInfo = modelInfo;
|
|
1056
1387
|
this.models = models;
|
|
1057
1388
|
this.id = crypto2.randomUUID();
|
|
@@ -1070,6 +1401,7 @@ var AxBaseAI = class {
|
|
|
1070
1401
|
rt;
|
|
1071
1402
|
fetch;
|
|
1072
1403
|
tracer;
|
|
1404
|
+
meter;
|
|
1073
1405
|
timeout;
|
|
1074
1406
|
excludeContentFromTrace;
|
|
1075
1407
|
models;
|
|
@@ -1116,6 +1448,9 @@ var AxBaseAI = class {
|
|
|
1116
1448
|
}
|
|
1117
1449
|
}
|
|
1118
1450
|
};
|
|
1451
|
+
getMetricsInstruments() {
|
|
1452
|
+
return getOrCreateAIMetricsInstruments(this.meter);
|
|
1453
|
+
}
|
|
1119
1454
|
setName(name) {
|
|
1120
1455
|
this.name = name;
|
|
1121
1456
|
}
|
|
@@ -1133,7 +1468,8 @@ var AxBaseAI = class {
|
|
|
1133
1468
|
this.rt = options.rateLimiter;
|
|
1134
1469
|
this.fetch = options.fetch;
|
|
1135
1470
|
this.timeout = options.timeout;
|
|
1136
|
-
this.tracer = options.tracer;
|
|
1471
|
+
this.tracer = options.tracer ?? axGlobals.tracer;
|
|
1472
|
+
this.meter = options.meter ?? axGlobals.meter;
|
|
1137
1473
|
this.excludeContentFromTrace = options.excludeContentFromTrace;
|
|
1138
1474
|
this.abortSignal = options.abortSignal;
|
|
1139
1475
|
this.logger = options.logger ?? defaultLogger2;
|
|
@@ -1144,6 +1480,7 @@ var AxBaseAI = class {
|
|
|
1144
1480
|
rateLimiter: this.rt,
|
|
1145
1481
|
fetch: this.fetch,
|
|
1146
1482
|
tracer: this.tracer,
|
|
1483
|
+
meter: this.meter,
|
|
1147
1484
|
timeout: this.timeout,
|
|
1148
1485
|
excludeContentFromTrace: this.excludeContentFromTrace,
|
|
1149
1486
|
abortSignal: this.abortSignal,
|
|
@@ -1208,6 +1545,20 @@ var AxBaseAI = class {
|
|
|
1208
1545
|
metrics.mean = metrics.samples.reduce((a, b) => a + b, 0) / metrics.samples.length;
|
|
1209
1546
|
metrics.p95 = this.calculatePercentile(metrics.samples, 95);
|
|
1210
1547
|
metrics.p99 = this.calculatePercentile(metrics.samples, 99);
|
|
1548
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1549
|
+
if (metricsInstruments) {
|
|
1550
|
+
const model = type === "chat" ? this.lastUsedChatModel : this.lastUsedEmbedModel;
|
|
1551
|
+
recordLatencyMetric(metricsInstruments, type, duration, this.name, model);
|
|
1552
|
+
recordLatencyStatsMetrics(
|
|
1553
|
+
metricsInstruments,
|
|
1554
|
+
type,
|
|
1555
|
+
metrics.mean,
|
|
1556
|
+
metrics.p95,
|
|
1557
|
+
metrics.p99,
|
|
1558
|
+
this.name,
|
|
1559
|
+
model
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1211
1562
|
}
|
|
1212
1563
|
// Method to update error metrics
|
|
1213
1564
|
updateErrorMetrics(type, isError) {
|
|
@@ -1217,6 +1568,319 @@ var AxBaseAI = class {
|
|
|
1217
1568
|
metrics.count++;
|
|
1218
1569
|
}
|
|
1219
1570
|
metrics.rate = metrics.count / metrics.total;
|
|
1571
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1572
|
+
if (metricsInstruments) {
|
|
1573
|
+
const model = type === "chat" ? this.lastUsedChatModel : this.lastUsedEmbedModel;
|
|
1574
|
+
recordRequestMetric(metricsInstruments, type, this.name, model);
|
|
1575
|
+
if (isError) {
|
|
1576
|
+
recordErrorMetric(metricsInstruments, type, this.name, model);
|
|
1577
|
+
}
|
|
1578
|
+
recordErrorRateMetric(
|
|
1579
|
+
metricsInstruments,
|
|
1580
|
+
type,
|
|
1581
|
+
metrics.rate,
|
|
1582
|
+
this.name,
|
|
1583
|
+
model
|
|
1584
|
+
);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
// Method to record token usage metrics
|
|
1588
|
+
recordTokenUsage(modelUsage) {
|
|
1589
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1590
|
+
if (metricsInstruments && modelUsage?.tokens) {
|
|
1591
|
+
const { promptTokens, completionTokens, totalTokens, thoughtsTokens } = modelUsage.tokens;
|
|
1592
|
+
if (promptTokens) {
|
|
1593
|
+
recordTokenMetric(
|
|
1594
|
+
metricsInstruments,
|
|
1595
|
+
"input",
|
|
1596
|
+
promptTokens,
|
|
1597
|
+
this.name,
|
|
1598
|
+
modelUsage.model
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
if (completionTokens) {
|
|
1602
|
+
recordTokenMetric(
|
|
1603
|
+
metricsInstruments,
|
|
1604
|
+
"output",
|
|
1605
|
+
completionTokens,
|
|
1606
|
+
this.name,
|
|
1607
|
+
modelUsage.model
|
|
1608
|
+
);
|
|
1609
|
+
}
|
|
1610
|
+
if (totalTokens) {
|
|
1611
|
+
recordTokenMetric(
|
|
1612
|
+
metricsInstruments,
|
|
1613
|
+
"total",
|
|
1614
|
+
totalTokens,
|
|
1615
|
+
this.name,
|
|
1616
|
+
modelUsage.model
|
|
1617
|
+
);
|
|
1618
|
+
}
|
|
1619
|
+
if (thoughtsTokens) {
|
|
1620
|
+
recordTokenMetric(
|
|
1621
|
+
metricsInstruments,
|
|
1622
|
+
"thoughts",
|
|
1623
|
+
thoughtsTokens,
|
|
1624
|
+
this.name,
|
|
1625
|
+
modelUsage.model
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
// Helper method to calculate request size in bytes
|
|
1631
|
+
calculateRequestSize(req) {
|
|
1632
|
+
try {
|
|
1633
|
+
return new TextEncoder().encode(JSON.stringify(req)).length;
|
|
1634
|
+
} catch {
|
|
1635
|
+
return 0;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
// Helper method to calculate response size in bytes
|
|
1639
|
+
calculateResponseSize(response) {
|
|
1640
|
+
try {
|
|
1641
|
+
return new TextEncoder().encode(JSON.stringify(response)).length;
|
|
1642
|
+
} catch {
|
|
1643
|
+
return 0;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
// Helper method to detect multimodal content
|
|
1647
|
+
detectMultimodalContent(req) {
|
|
1648
|
+
let hasImages = false;
|
|
1649
|
+
let hasAudio = false;
|
|
1650
|
+
if (req.chatPrompt && Array.isArray(req.chatPrompt)) {
|
|
1651
|
+
for (const message of req.chatPrompt) {
|
|
1652
|
+
if (message.role === "user" && Array.isArray(message.content)) {
|
|
1653
|
+
for (const part of message.content) {
|
|
1654
|
+
if (part.type === "image") {
|
|
1655
|
+
hasImages = true;
|
|
1656
|
+
} else if (part.type === "audio") {
|
|
1657
|
+
hasAudio = true;
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
return { hasImages, hasAudio };
|
|
1664
|
+
}
|
|
1665
|
+
// Helper method to calculate prompt length
|
|
1666
|
+
calculatePromptLength(req) {
|
|
1667
|
+
let totalLength = 0;
|
|
1668
|
+
if (req.chatPrompt && Array.isArray(req.chatPrompt)) {
|
|
1669
|
+
for (const message of req.chatPrompt) {
|
|
1670
|
+
if (message.role === "system" || message.role === "assistant") {
|
|
1671
|
+
if (message.content) {
|
|
1672
|
+
totalLength += message.content.length;
|
|
1673
|
+
}
|
|
1674
|
+
} else if (message.role === "user") {
|
|
1675
|
+
if (typeof message.content === "string") {
|
|
1676
|
+
totalLength += message.content.length;
|
|
1677
|
+
} else if (Array.isArray(message.content)) {
|
|
1678
|
+
for (const part of message.content) {
|
|
1679
|
+
if (part.type === "text") {
|
|
1680
|
+
totalLength += part.text.length;
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
} else if (message.role === "function") {
|
|
1685
|
+
if (message.result) {
|
|
1686
|
+
totalLength += message.result.length;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
return totalLength;
|
|
1692
|
+
}
|
|
1693
|
+
// Helper method to calculate context window usage
|
|
1694
|
+
calculateContextWindowUsage(model, modelUsage) {
|
|
1695
|
+
if (!modelUsage?.tokens?.promptTokens) return 0;
|
|
1696
|
+
const modelInfo = this.modelInfo.find(
|
|
1697
|
+
(info) => info.name === model
|
|
1698
|
+
);
|
|
1699
|
+
if (!modelInfo?.contextWindow) return 0;
|
|
1700
|
+
return modelUsage.tokens.promptTokens / modelInfo.contextWindow;
|
|
1701
|
+
}
|
|
1702
|
+
// Helper method to estimate cost
|
|
1703
|
+
estimateCost(model, modelUsage) {
|
|
1704
|
+
if (!modelUsage?.tokens) return 0;
|
|
1705
|
+
const modelInfo = this.modelInfo.find(
|
|
1706
|
+
(info) => info.name === model
|
|
1707
|
+
);
|
|
1708
|
+
if (!modelInfo || !modelInfo.promptTokenCostPer1M && !modelInfo.completionTokenCostPer1M)
|
|
1709
|
+
return 0;
|
|
1710
|
+
const { promptTokens = 0, completionTokens = 0 } = modelUsage.tokens;
|
|
1711
|
+
const promptCostPer1M = modelInfo.promptTokenCostPer1M || 0;
|
|
1712
|
+
const completionCostPer1M = modelInfo.completionTokenCostPer1M || 0;
|
|
1713
|
+
return promptTokens * promptCostPer1M / 1e6 + completionTokens * completionCostPer1M / 1e6;
|
|
1714
|
+
}
|
|
1715
|
+
// Helper method to estimate cost by model name
|
|
1716
|
+
estimateCostByName(modelName, modelUsage) {
|
|
1717
|
+
if (!modelUsage?.tokens) return 0;
|
|
1718
|
+
const modelInfo = this.modelInfo.find((info) => info.name === modelName);
|
|
1719
|
+
if (!modelInfo || !modelInfo.promptTokenCostPer1M && !modelInfo.completionTokenCostPer1M)
|
|
1720
|
+
return 0;
|
|
1721
|
+
const { promptTokens = 0, completionTokens = 0 } = modelUsage.tokens;
|
|
1722
|
+
const promptCostPer1M = modelInfo.promptTokenCostPer1M || 0;
|
|
1723
|
+
const completionCostPer1M = modelInfo.completionTokenCostPer1M || 0;
|
|
1724
|
+
return promptTokens * promptCostPer1M / 1e6 + completionTokens * completionCostPer1M / 1e6;
|
|
1725
|
+
}
|
|
1726
|
+
// Helper method to record function call metrics
|
|
1727
|
+
recordFunctionCallMetrics(functionCalls, model) {
|
|
1728
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1729
|
+
if (!metricsInstruments || !functionCalls) return;
|
|
1730
|
+
for (const call of functionCalls) {
|
|
1731
|
+
if (call && typeof call === "object" && "function" in call && call.function && typeof call.function === "object" && "name" in call.function) {
|
|
1732
|
+
recordFunctionCallMetric(
|
|
1733
|
+
metricsInstruments,
|
|
1734
|
+
call.function.name,
|
|
1735
|
+
void 0,
|
|
1736
|
+
// latency would need to be tracked separately
|
|
1737
|
+
this.name,
|
|
1738
|
+
model
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
// Helper method to record timeout metrics
|
|
1744
|
+
recordTimeoutMetric(type) {
|
|
1745
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1746
|
+
if (metricsInstruments) {
|
|
1747
|
+
const model = type === "chat" ? this.lastUsedChatModel : this.lastUsedEmbedModel;
|
|
1748
|
+
recordTimeoutMetric(metricsInstruments, type, this.name, model);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
// Helper method to record abort metrics
|
|
1752
|
+
recordAbortMetric(type) {
|
|
1753
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1754
|
+
if (metricsInstruments) {
|
|
1755
|
+
const model = type === "chat" ? this.lastUsedChatModel : this.lastUsedEmbedModel;
|
|
1756
|
+
recordAbortMetric(metricsInstruments, type, this.name, model);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
// Comprehensive method to record all chat-related metrics
|
|
1760
|
+
recordChatMetrics(req, options, result) {
|
|
1761
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1762
|
+
if (!metricsInstruments) return;
|
|
1763
|
+
const model = this.lastUsedChatModel;
|
|
1764
|
+
const modelConfig = this.lastUsedModelConfig;
|
|
1765
|
+
const isStreaming = modelConfig?.stream ?? false;
|
|
1766
|
+
recordStreamingRequestMetric(
|
|
1767
|
+
metricsInstruments,
|
|
1768
|
+
"chat",
|
|
1769
|
+
isStreaming,
|
|
1770
|
+
this.name,
|
|
1771
|
+
model
|
|
1772
|
+
);
|
|
1773
|
+
const { hasImages, hasAudio } = this.detectMultimodalContent(req);
|
|
1774
|
+
recordMultimodalRequestMetric(
|
|
1775
|
+
metricsInstruments,
|
|
1776
|
+
hasImages,
|
|
1777
|
+
hasAudio,
|
|
1778
|
+
this.name,
|
|
1779
|
+
model
|
|
1780
|
+
);
|
|
1781
|
+
const promptLength = this.calculatePromptLength(req);
|
|
1782
|
+
recordPromptLengthMetric(metricsInstruments, promptLength, this.name, model);
|
|
1783
|
+
recordModelConfigMetrics(
|
|
1784
|
+
metricsInstruments,
|
|
1785
|
+
modelConfig?.temperature,
|
|
1786
|
+
modelConfig?.maxTokens,
|
|
1787
|
+
this.name,
|
|
1788
|
+
model
|
|
1789
|
+
);
|
|
1790
|
+
if (options?.thinkingTokenBudget && this.modelUsage?.tokens?.thoughtsTokens) {
|
|
1791
|
+
recordThinkingBudgetUsageMetric(
|
|
1792
|
+
metricsInstruments,
|
|
1793
|
+
this.modelUsage.tokens.thoughtsTokens,
|
|
1794
|
+
this.name,
|
|
1795
|
+
model
|
|
1796
|
+
);
|
|
1797
|
+
}
|
|
1798
|
+
const requestSize = this.calculateRequestSize(req);
|
|
1799
|
+
recordRequestSizeMetric(
|
|
1800
|
+
metricsInstruments,
|
|
1801
|
+
"chat",
|
|
1802
|
+
requestSize,
|
|
1803
|
+
this.name,
|
|
1804
|
+
model
|
|
1805
|
+
);
|
|
1806
|
+
if (result && !isStreaming) {
|
|
1807
|
+
const chatResponse = result;
|
|
1808
|
+
const responseSize = this.calculateResponseSize(chatResponse);
|
|
1809
|
+
recordResponseSizeMetric(
|
|
1810
|
+
metricsInstruments,
|
|
1811
|
+
"chat",
|
|
1812
|
+
responseSize,
|
|
1813
|
+
this.name,
|
|
1814
|
+
model
|
|
1815
|
+
);
|
|
1816
|
+
if (chatResponse.results) {
|
|
1817
|
+
for (const chatResult of chatResponse.results) {
|
|
1818
|
+
if (chatResult.functionCalls) {
|
|
1819
|
+
this.recordFunctionCallMetrics(
|
|
1820
|
+
chatResult.functionCalls,
|
|
1821
|
+
this.lastUsedChatModel
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
const contextUsage = this.calculateContextWindowUsage(
|
|
1827
|
+
this.lastUsedChatModel,
|
|
1828
|
+
chatResponse.modelUsage
|
|
1829
|
+
);
|
|
1830
|
+
if (contextUsage > 0) {
|
|
1831
|
+
recordContextWindowUsageMetric(
|
|
1832
|
+
metricsInstruments,
|
|
1833
|
+
contextUsage,
|
|
1834
|
+
this.name,
|
|
1835
|
+
model
|
|
1836
|
+
);
|
|
1837
|
+
}
|
|
1838
|
+
const estimatedCost = this.estimateCost(
|
|
1839
|
+
this.lastUsedChatModel,
|
|
1840
|
+
chatResponse.modelUsage
|
|
1841
|
+
);
|
|
1842
|
+
if (estimatedCost > 0) {
|
|
1843
|
+
recordEstimatedCostMetric(
|
|
1844
|
+
metricsInstruments,
|
|
1845
|
+
"chat",
|
|
1846
|
+
estimatedCost,
|
|
1847
|
+
this.name,
|
|
1848
|
+
model
|
|
1849
|
+
);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
// Comprehensive method to record all embed-related metrics
|
|
1854
|
+
recordEmbedMetrics(req, result) {
|
|
1855
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
1856
|
+
if (!metricsInstruments) return;
|
|
1857
|
+
const model = this.lastUsedEmbedModel;
|
|
1858
|
+
const requestSize = this.calculateRequestSize(req);
|
|
1859
|
+
recordRequestSizeMetric(
|
|
1860
|
+
metricsInstruments,
|
|
1861
|
+
"embed",
|
|
1862
|
+
requestSize,
|
|
1863
|
+
this.name,
|
|
1864
|
+
model
|
|
1865
|
+
);
|
|
1866
|
+
const responseSize = this.calculateResponseSize(result);
|
|
1867
|
+
recordResponseSizeMetric(
|
|
1868
|
+
metricsInstruments,
|
|
1869
|
+
"embed",
|
|
1870
|
+
responseSize,
|
|
1871
|
+
this.name,
|
|
1872
|
+
model
|
|
1873
|
+
);
|
|
1874
|
+
const estimatedCost = this.estimateCostByName(model, result.modelUsage);
|
|
1875
|
+
if (estimatedCost > 0) {
|
|
1876
|
+
recordEstimatedCostMetric(
|
|
1877
|
+
metricsInstruments,
|
|
1878
|
+
"embed",
|
|
1879
|
+
estimatedCost,
|
|
1880
|
+
this.name,
|
|
1881
|
+
model
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1220
1884
|
}
|
|
1221
1885
|
// Public method to get metrics
|
|
1222
1886
|
getMetrics() {
|
|
@@ -1225,16 +1889,27 @@ var AxBaseAI = class {
|
|
|
1225
1889
|
async chat(req, options) {
|
|
1226
1890
|
const startTime = performance.now();
|
|
1227
1891
|
let isError = false;
|
|
1892
|
+
let result;
|
|
1228
1893
|
try {
|
|
1229
|
-
|
|
1894
|
+
result = await this._chat1(req, options);
|
|
1230
1895
|
return result;
|
|
1231
1896
|
} catch (error) {
|
|
1232
1897
|
isError = true;
|
|
1898
|
+
if (error instanceof Error) {
|
|
1899
|
+
if (error.message.includes("timeout") || error.name === "TimeoutError") {
|
|
1900
|
+
this.recordTimeoutMetric("chat");
|
|
1901
|
+
} else if (error.message.includes("abort") || error.name === "AbortError") {
|
|
1902
|
+
this.recordAbortMetric("chat");
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1233
1905
|
throw error;
|
|
1234
1906
|
} finally {
|
|
1235
1907
|
const duration = performance.now() - startTime;
|
|
1236
1908
|
this.updateLatencyMetrics("chat", duration);
|
|
1237
1909
|
this.updateErrorMetrics("chat", isError);
|
|
1910
|
+
if (!isError) {
|
|
1911
|
+
this.recordChatMetrics(req, options, result);
|
|
1912
|
+
}
|
|
1238
1913
|
}
|
|
1239
1914
|
}
|
|
1240
1915
|
async _chat1(req, options) {
|
|
@@ -1381,6 +2056,7 @@ var AxBaseAI = class {
|
|
|
1381
2056
|
}
|
|
1382
2057
|
}
|
|
1383
2058
|
this.modelUsage = res2.modelUsage;
|
|
2059
|
+
this.recordTokenUsage(res2.modelUsage);
|
|
1384
2060
|
if (span?.isRecording()) {
|
|
1385
2061
|
setChatResponseEvents(res2, span, this.excludeContentFromTrace);
|
|
1386
2062
|
}
|
|
@@ -1423,6 +2099,7 @@ var AxBaseAI = class {
|
|
|
1423
2099
|
}
|
|
1424
2100
|
if (res.modelUsage) {
|
|
1425
2101
|
this.modelUsage = res.modelUsage;
|
|
2102
|
+
this.recordTokenUsage(res.modelUsage);
|
|
1426
2103
|
}
|
|
1427
2104
|
if (span?.isRecording()) {
|
|
1428
2105
|
setChatResponseEvents(res, span, this.excludeContentFromTrace);
|
|
@@ -1439,15 +2116,27 @@ var AxBaseAI = class {
|
|
|
1439
2116
|
async embed(req, options) {
|
|
1440
2117
|
const startTime = performance.now();
|
|
1441
2118
|
let isError = false;
|
|
2119
|
+
let result;
|
|
1442
2120
|
try {
|
|
1443
|
-
|
|
2121
|
+
result = await this._embed1(req, options);
|
|
2122
|
+
return result;
|
|
1444
2123
|
} catch (error) {
|
|
1445
2124
|
isError = true;
|
|
2125
|
+
if (error instanceof Error) {
|
|
2126
|
+
if (error.message.includes("timeout") || error.name === "TimeoutError") {
|
|
2127
|
+
this.recordTimeoutMetric("embed");
|
|
2128
|
+
} else if (error.message.includes("abort") || error.name === "AbortError") {
|
|
2129
|
+
this.recordAbortMetric("embed");
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
1446
2132
|
throw error;
|
|
1447
2133
|
} finally {
|
|
1448
2134
|
const duration = performance.now() - startTime;
|
|
1449
2135
|
this.updateLatencyMetrics("embed", duration);
|
|
1450
2136
|
this.updateErrorMetrics("embed", isError);
|
|
2137
|
+
if (!isError) {
|
|
2138
|
+
this.recordEmbedMetrics(req, result);
|
|
2139
|
+
}
|
|
1451
2140
|
}
|
|
1452
2141
|
}
|
|
1453
2142
|
async _embed1(req, options) {
|
|
@@ -1522,6 +2211,7 @@ var AxBaseAI = class {
|
|
|
1522
2211
|
}
|
|
1523
2212
|
}
|
|
1524
2213
|
this.embedModelUsage = res.modelUsage;
|
|
2214
|
+
this.recordTokenUsage(res.modelUsage);
|
|
1525
2215
|
if (span?.isRecording() && res.modelUsage?.tokens) {
|
|
1526
2216
|
span.addEvent(axSpanEvents.GEN_AI_USAGE, {
|
|
1527
2217
|
[axSpanAttributes.LLM_USAGE_INPUT_TOKENS]: res.modelUsage.tokens.promptTokens,
|
|
@@ -7858,88 +8548,577 @@ function createFunctionConfig(functionList, definedFunctionCall, firstStep) {
|
|
|
7858
8548
|
return { functions, functionCall };
|
|
7859
8549
|
}
|
|
7860
8550
|
|
|
7861
|
-
// dsp/
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
fc.function.params += _fc.function.params;
|
|
7874
|
-
}
|
|
7875
|
-
if (typeof _fc.function.params == "object") {
|
|
7876
|
-
fc.function.params = _fc.function.params;
|
|
7877
|
-
}
|
|
7878
|
-
} else {
|
|
7879
|
-
functionCalls.push(_fc);
|
|
7880
|
-
}
|
|
7881
|
-
}
|
|
7882
|
-
}
|
|
7883
|
-
|
|
7884
|
-
// dsp/sig.ts
|
|
7885
|
-
import { createHash } from "crypto";
|
|
7886
|
-
|
|
7887
|
-
// dsp/globals.ts
|
|
7888
|
-
var axGlobals = {
|
|
7889
|
-
signatureStrict: true
|
|
7890
|
-
// Controls reservedNames enforcement in signature parsing/validation
|
|
8551
|
+
// dsp/metrics.ts
|
|
8552
|
+
var axDefaultMetricsConfig = {
|
|
8553
|
+
enabled: true,
|
|
8554
|
+
enabledCategories: [
|
|
8555
|
+
"generation",
|
|
8556
|
+
"streaming",
|
|
8557
|
+
"functions",
|
|
8558
|
+
"errors",
|
|
8559
|
+
"performance"
|
|
8560
|
+
],
|
|
8561
|
+
maxLabelLength: 100,
|
|
8562
|
+
samplingRate: 1
|
|
7891
8563
|
};
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
super(message);
|
|
7897
|
-
this.position = position;
|
|
7898
|
-
this.context = context3;
|
|
7899
|
-
this.suggestion = suggestion;
|
|
7900
|
-
this.name = "SignatureValidationError";
|
|
8564
|
+
var globalGenMetricsInstruments;
|
|
8565
|
+
var getOrCreateGenMetricsInstruments = (meter) => {
|
|
8566
|
+
if (globalGenMetricsInstruments) {
|
|
8567
|
+
return globalGenMetricsInstruments;
|
|
7901
8568
|
}
|
|
8569
|
+
const activeMeter = meter ?? axGlobals.meter;
|
|
8570
|
+
if (activeMeter) {
|
|
8571
|
+
globalGenMetricsInstruments = createGenMetricsInstruments(activeMeter);
|
|
8572
|
+
return globalGenMetricsInstruments;
|
|
8573
|
+
}
|
|
8574
|
+
return void 0;
|
|
7902
8575
|
};
|
|
7903
|
-
var
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
currentSection = "description";
|
|
7908
|
-
constructor(input) {
|
|
7909
|
-
this.input = input.trim();
|
|
7910
|
-
this.position = 0;
|
|
7911
|
-
if (!this.input) {
|
|
7912
|
-
throw new SignatureValidationError(
|
|
7913
|
-
"Empty signature provided",
|
|
7914
|
-
0,
|
|
7915
|
-
"",
|
|
7916
|
-
'A signature must contain at least input and output fields separated by "->". Example: "userQuery:string -> aiResponse:string"'
|
|
7917
|
-
);
|
|
7918
|
-
}
|
|
8576
|
+
var axCheckMetricsHealth = () => {
|
|
8577
|
+
const issues = [];
|
|
8578
|
+
if (!axGlobals.meter) {
|
|
8579
|
+
issues.push("Global meter not initialized");
|
|
7919
8580
|
}
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
}
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
8581
|
+
if (!globalGenMetricsInstruments && axGlobals.meter) {
|
|
8582
|
+
issues.push("Metrics instruments not created despite available meter");
|
|
8583
|
+
}
|
|
8584
|
+
return {
|
|
8585
|
+
healthy: issues.length === 0,
|
|
8586
|
+
issues
|
|
8587
|
+
};
|
|
8588
|
+
};
|
|
8589
|
+
var createGenMetricsInstruments = (meter) => {
|
|
8590
|
+
return {
|
|
8591
|
+
// Generation flow metrics
|
|
8592
|
+
// Note: Histogram buckets should be configured at the exporter level
|
|
8593
|
+
// Recommended buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000] ms
|
|
8594
|
+
generationLatencyHistogram: meter.createHistogram(
|
|
8595
|
+
"ax_gen_generation_duration_ms",
|
|
8596
|
+
{
|
|
8597
|
+
description: "End-to-end duration of AxGen generation requests",
|
|
8598
|
+
unit: "ms"
|
|
8599
|
+
}
|
|
8600
|
+
),
|
|
8601
|
+
generationRequestsCounter: meter.createCounter(
|
|
8602
|
+
"ax_gen_generation_requests_total",
|
|
8603
|
+
{
|
|
8604
|
+
description: "Total number of AxGen generation requests"
|
|
8605
|
+
}
|
|
8606
|
+
),
|
|
8607
|
+
generationErrorsCounter: meter.createCounter(
|
|
8608
|
+
"ax_gen_generation_errors_total",
|
|
8609
|
+
{
|
|
8610
|
+
description: "Total number of failed AxGen generations"
|
|
8611
|
+
}
|
|
8612
|
+
),
|
|
8613
|
+
// Multi-step flow metrics
|
|
8614
|
+
multiStepGenerationsCounter: meter.createCounter(
|
|
8615
|
+
"ax_gen_multistep_generations_total",
|
|
8616
|
+
{
|
|
8617
|
+
description: "Total number of generations that required multiple steps"
|
|
8618
|
+
}
|
|
8619
|
+
),
|
|
8620
|
+
stepsPerGenerationHistogram: meter.createHistogram(
|
|
8621
|
+
"ax_gen_steps_per_generation",
|
|
8622
|
+
{
|
|
8623
|
+
description: "Number of steps taken per generation"
|
|
8624
|
+
}
|
|
8625
|
+
),
|
|
8626
|
+
maxStepsReachedCounter: meter.createCounter(
|
|
8627
|
+
"ax_gen_max_steps_reached_total",
|
|
8628
|
+
{
|
|
8629
|
+
description: "Total number of generations that hit max steps limit"
|
|
8630
|
+
}
|
|
8631
|
+
),
|
|
8632
|
+
// Error correction metrics
|
|
8633
|
+
validationErrorsCounter: meter.createCounter(
|
|
8634
|
+
"ax_gen_validation_errors_total",
|
|
8635
|
+
{
|
|
8636
|
+
description: "Total number of validation errors encountered"
|
|
8637
|
+
}
|
|
8638
|
+
),
|
|
8639
|
+
assertionErrorsCounter: meter.createCounter(
|
|
8640
|
+
"ax_gen_assertion_errors_total",
|
|
8641
|
+
{
|
|
8642
|
+
description: "Total number of assertion errors encountered"
|
|
8643
|
+
}
|
|
8644
|
+
),
|
|
8645
|
+
errorCorrectionAttemptsHistogram: meter.createHistogram(
|
|
8646
|
+
"ax_gen_error_correction_attempts",
|
|
8647
|
+
{
|
|
8648
|
+
description: "Number of error correction attempts per generation"
|
|
8649
|
+
}
|
|
8650
|
+
),
|
|
8651
|
+
errorCorrectionSuccessCounter: meter.createCounter(
|
|
8652
|
+
"ax_gen_error_correction_success_total",
|
|
8653
|
+
{
|
|
8654
|
+
description: "Total number of successful error corrections"
|
|
8655
|
+
}
|
|
8656
|
+
),
|
|
8657
|
+
errorCorrectionFailureCounter: meter.createCounter(
|
|
8658
|
+
"ax_gen_error_correction_failure_total",
|
|
8659
|
+
{
|
|
8660
|
+
description: "Total number of failed error corrections"
|
|
8661
|
+
}
|
|
8662
|
+
),
|
|
8663
|
+
maxRetriesReachedCounter: meter.createCounter(
|
|
8664
|
+
"ax_gen_max_retries_reached_total",
|
|
8665
|
+
{
|
|
8666
|
+
description: "Total number of generations that hit max retries limit"
|
|
8667
|
+
}
|
|
8668
|
+
),
|
|
8669
|
+
// Function calling metrics
|
|
8670
|
+
functionsEnabledGenerationsCounter: meter.createCounter(
|
|
8671
|
+
"ax_gen_functions_enabled_generations_total",
|
|
8672
|
+
{
|
|
8673
|
+
description: "Total number of generations with functions enabled"
|
|
8674
|
+
}
|
|
8675
|
+
),
|
|
8676
|
+
functionCallStepsCounter: meter.createCounter(
|
|
8677
|
+
"ax_gen_function_call_steps_total",
|
|
8678
|
+
{
|
|
8679
|
+
description: "Total number of steps that included function calls"
|
|
8680
|
+
}
|
|
8681
|
+
),
|
|
8682
|
+
functionsExecutedPerGenerationHistogram: meter.createHistogram(
|
|
8683
|
+
"ax_gen_functions_executed_per_generation",
|
|
8684
|
+
{
|
|
8685
|
+
description: "Number of unique functions executed per generation"
|
|
8686
|
+
}
|
|
8687
|
+
),
|
|
8688
|
+
functionErrorCorrectionCounter: meter.createCounter(
|
|
8689
|
+
"ax_gen_function_error_correction_total",
|
|
8690
|
+
{
|
|
8691
|
+
description: "Total number of function-related error corrections"
|
|
8692
|
+
}
|
|
8693
|
+
),
|
|
8694
|
+
// Field processing metrics
|
|
8695
|
+
fieldProcessorsExecutedCounter: meter.createCounter(
|
|
8696
|
+
"ax_gen_field_processors_executed_total",
|
|
8697
|
+
{
|
|
8698
|
+
description: "Total number of field processors executed"
|
|
8699
|
+
}
|
|
8700
|
+
),
|
|
8701
|
+
streamingFieldProcessorsExecutedCounter: meter.createCounter(
|
|
8702
|
+
"ax_gen_streaming_field_processors_executed_total",
|
|
8703
|
+
{
|
|
8704
|
+
description: "Total number of streaming field processors executed"
|
|
8705
|
+
}
|
|
8706
|
+
),
|
|
8707
|
+
// Streaming specific metrics
|
|
8708
|
+
streamingGenerationsCounter: meter.createCounter(
|
|
8709
|
+
"ax_gen_streaming_generations_total",
|
|
8710
|
+
{
|
|
8711
|
+
description: "Total number of streaming generations"
|
|
8712
|
+
}
|
|
8713
|
+
),
|
|
8714
|
+
streamingDeltasEmittedCounter: meter.createCounter(
|
|
8715
|
+
"ax_gen_streaming_deltas_emitted_total",
|
|
8716
|
+
{
|
|
8717
|
+
description: "Total number of streaming deltas emitted"
|
|
8718
|
+
}
|
|
8719
|
+
),
|
|
8720
|
+
streamingFinalizationLatencyHistogram: meter.createHistogram(
|
|
8721
|
+
"ax_gen_streaming_finalization_duration_ms",
|
|
8722
|
+
{
|
|
8723
|
+
description: "Duration of streaming response finalization",
|
|
8724
|
+
unit: "ms"
|
|
8725
|
+
}
|
|
8726
|
+
),
|
|
8727
|
+
// Memory and samples metrics
|
|
8728
|
+
samplesGeneratedHistogram: meter.createHistogram(
|
|
8729
|
+
"ax_gen_samples_generated",
|
|
8730
|
+
{
|
|
8731
|
+
description: "Number of samples generated per request"
|
|
8732
|
+
}
|
|
8733
|
+
),
|
|
8734
|
+
resultPickerUsageCounter: meter.createCounter(
|
|
8735
|
+
"ax_gen_result_picker_usage_total",
|
|
8736
|
+
{
|
|
8737
|
+
description: "Total number of times result picker was used"
|
|
8738
|
+
}
|
|
8739
|
+
),
|
|
8740
|
+
resultPickerLatencyHistogram: meter.createHistogram(
|
|
8741
|
+
"ax_gen_result_picker_duration_ms",
|
|
8742
|
+
{
|
|
8743
|
+
description: "Duration of result picker execution",
|
|
8744
|
+
unit: "ms"
|
|
8745
|
+
}
|
|
8746
|
+
),
|
|
8747
|
+
// Signature complexity metrics
|
|
8748
|
+
inputFieldsGauge: meter.createGauge("ax_gen_input_fields", {
|
|
8749
|
+
description: "Number of input fields in signature"
|
|
8750
|
+
}),
|
|
8751
|
+
outputFieldsGauge: meter.createGauge("ax_gen_output_fields", {
|
|
8752
|
+
description: "Number of output fields in signature"
|
|
8753
|
+
}),
|
|
8754
|
+
examplesUsedGauge: meter.createGauge("ax_gen_examples_used", {
|
|
8755
|
+
description: "Number of examples used in generation"
|
|
8756
|
+
}),
|
|
8757
|
+
demosUsedGauge: meter.createGauge("ax_gen_demos_used", {
|
|
8758
|
+
description: "Number of demos used in generation"
|
|
8759
|
+
}),
|
|
8760
|
+
// Performance metrics
|
|
8761
|
+
promptRenderLatencyHistogram: meter.createHistogram(
|
|
8762
|
+
"ax_gen_prompt_render_duration_ms",
|
|
8763
|
+
{
|
|
8764
|
+
description: "Duration of prompt template rendering",
|
|
8765
|
+
unit: "ms"
|
|
8766
|
+
}
|
|
8767
|
+
),
|
|
8768
|
+
extractionLatencyHistogram: meter.createHistogram(
|
|
8769
|
+
"ax_gen_extraction_duration_ms",
|
|
8770
|
+
{
|
|
8771
|
+
description: "Duration of value extraction from responses",
|
|
8772
|
+
unit: "ms"
|
|
8773
|
+
}
|
|
8774
|
+
),
|
|
8775
|
+
assertionLatencyHistogram: meter.createHistogram(
|
|
8776
|
+
"ax_gen_assertion_duration_ms",
|
|
8777
|
+
{
|
|
8778
|
+
description: "Duration of assertion checking",
|
|
8779
|
+
unit: "ms"
|
|
8780
|
+
}
|
|
8781
|
+
),
|
|
8782
|
+
// State management
|
|
8783
|
+
stateCreationLatencyHistogram: meter.createHistogram(
|
|
8784
|
+
"ax_gen_state_creation_duration_ms",
|
|
8785
|
+
{
|
|
8786
|
+
description: "Duration of state creation for multiple samples",
|
|
8787
|
+
unit: "ms"
|
|
8788
|
+
}
|
|
8789
|
+
),
|
|
8790
|
+
memoryUpdateLatencyHistogram: meter.createHistogram(
|
|
8791
|
+
"ax_gen_memory_update_duration_ms",
|
|
8792
|
+
{
|
|
8793
|
+
description: "Duration of memory updates during generation",
|
|
8794
|
+
unit: "ms"
|
|
8795
|
+
}
|
|
8796
|
+
)
|
|
8797
|
+
};
|
|
8798
|
+
};
|
|
8799
|
+
var currentMetricsConfig = axDefaultMetricsConfig;
|
|
8800
|
+
var axUpdateMetricsConfig = (config) => {
|
|
8801
|
+
currentMetricsConfig = { ...currentMetricsConfig, ...config };
|
|
8802
|
+
};
|
|
8803
|
+
var axGetMetricsConfig = () => {
|
|
8804
|
+
return { ...currentMetricsConfig };
|
|
8805
|
+
};
|
|
8806
|
+
var sanitizeLabels2 = (labels) => {
|
|
8807
|
+
const sanitized = {};
|
|
8808
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
8809
|
+
if (value !== void 0 && value !== null) {
|
|
8810
|
+
const stringValue = String(value);
|
|
8811
|
+
const maxLength = currentMetricsConfig.maxLabelLength;
|
|
8812
|
+
sanitized[key] = stringValue.length > maxLength ? stringValue.substring(0, maxLength) : stringValue;
|
|
8813
|
+
}
|
|
8814
|
+
}
|
|
8815
|
+
return sanitized;
|
|
8816
|
+
};
|
|
8817
|
+
var recordGenerationMetric = (instruments, duration, success, signatureName, aiService, model) => {
|
|
8818
|
+
try {
|
|
8819
|
+
const labels = sanitizeLabels2({
|
|
8820
|
+
success: success.toString(),
|
|
8821
|
+
...signatureName ? { signature: signatureName } : {},
|
|
8822
|
+
...aiService ? { ai_service: aiService } : {},
|
|
8823
|
+
...model ? { model } : {}
|
|
8824
|
+
});
|
|
8825
|
+
if (instruments.generationLatencyHistogram) {
|
|
8826
|
+
instruments.generationLatencyHistogram.record(duration, labels);
|
|
8827
|
+
}
|
|
8828
|
+
if (instruments.generationRequestsCounter) {
|
|
8829
|
+
instruments.generationRequestsCounter.add(1, labels);
|
|
8830
|
+
}
|
|
8831
|
+
if (!success && instruments.generationErrorsCounter) {
|
|
8832
|
+
instruments.generationErrorsCounter.add(1, labels);
|
|
8833
|
+
}
|
|
8834
|
+
} catch (error) {
|
|
8835
|
+
console.warn("Failed to record generation metric:", error);
|
|
8836
|
+
}
|
|
8837
|
+
};
|
|
8838
|
+
var recordMultiStepMetric = (instruments, stepsUsed, maxSteps, signatureName) => {
|
|
8839
|
+
try {
|
|
8840
|
+
const labels = sanitizeLabels2({
|
|
8841
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8842
|
+
});
|
|
8843
|
+
if (stepsUsed > 1 && instruments.multiStepGenerationsCounter) {
|
|
8844
|
+
instruments.multiStepGenerationsCounter.add(1, labels);
|
|
8845
|
+
}
|
|
8846
|
+
if (instruments.stepsPerGenerationHistogram) {
|
|
8847
|
+
instruments.stepsPerGenerationHistogram.record(stepsUsed, labels);
|
|
8848
|
+
}
|
|
8849
|
+
if (stepsUsed >= maxSteps && instruments.maxStepsReachedCounter) {
|
|
8850
|
+
instruments.maxStepsReachedCounter.add(1, labels);
|
|
8851
|
+
}
|
|
8852
|
+
} catch (error) {
|
|
8853
|
+
console.warn("Failed to record multi-step metric:", error);
|
|
8854
|
+
}
|
|
8855
|
+
};
|
|
8856
|
+
var recordValidationErrorMetric = (instruments, errorType, signatureName) => {
|
|
8857
|
+
try {
|
|
8858
|
+
const labels = sanitizeLabels2({
|
|
8859
|
+
error_type: errorType,
|
|
8860
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8861
|
+
});
|
|
8862
|
+
if (errorType === "validation" && instruments.validationErrorsCounter) {
|
|
8863
|
+
instruments.validationErrorsCounter.add(1, labels);
|
|
8864
|
+
}
|
|
8865
|
+
if (errorType === "assertion" && instruments.assertionErrorsCounter) {
|
|
8866
|
+
instruments.assertionErrorsCounter.add(1, labels);
|
|
8867
|
+
}
|
|
8868
|
+
} catch (error) {
|
|
8869
|
+
console.warn("Failed to record validation error metric:", error);
|
|
8870
|
+
}
|
|
8871
|
+
};
|
|
8872
|
+
var recordErrorCorrectionMetric = (instruments, attempts, success, maxRetries, signatureName) => {
|
|
8873
|
+
try {
|
|
8874
|
+
const labels = sanitizeLabels2({
|
|
8875
|
+
success: success.toString(),
|
|
8876
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8877
|
+
});
|
|
8878
|
+
if (instruments.errorCorrectionAttemptsHistogram) {
|
|
8879
|
+
instruments.errorCorrectionAttemptsHistogram.record(attempts, labels);
|
|
8880
|
+
}
|
|
8881
|
+
if (success && instruments.errorCorrectionSuccessCounter) {
|
|
8882
|
+
instruments.errorCorrectionSuccessCounter.add(1, labels);
|
|
8883
|
+
}
|
|
8884
|
+
if (!success) {
|
|
8885
|
+
if (instruments.errorCorrectionFailureCounter) {
|
|
8886
|
+
instruments.errorCorrectionFailureCounter.add(1, labels);
|
|
8887
|
+
}
|
|
8888
|
+
if (attempts >= maxRetries && instruments.maxRetriesReachedCounter) {
|
|
8889
|
+
instruments.maxRetriesReachedCounter.add(1, labels);
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8892
|
+
} catch (error) {
|
|
8893
|
+
console.warn("Failed to record error correction metric:", error);
|
|
8894
|
+
}
|
|
8895
|
+
};
|
|
8896
|
+
var recordFunctionCallingMetric = (instruments, functionsEnabled, functionsExecuted, hadFunctionCalls, functionErrorCorrection = false, signatureName) => {
|
|
8897
|
+
try {
|
|
8898
|
+
const labels = sanitizeLabels2({
|
|
8899
|
+
functions_enabled: functionsEnabled.toString(),
|
|
8900
|
+
had_function_calls: hadFunctionCalls.toString(),
|
|
8901
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8902
|
+
});
|
|
8903
|
+
if (functionsEnabled && instruments.functionsEnabledGenerationsCounter) {
|
|
8904
|
+
instruments.functionsEnabledGenerationsCounter.add(1, labels);
|
|
8905
|
+
}
|
|
8906
|
+
if (hadFunctionCalls && instruments.functionCallStepsCounter) {
|
|
8907
|
+
instruments.functionCallStepsCounter.add(1, labels);
|
|
8908
|
+
}
|
|
8909
|
+
if (functionsExecuted > 0 && instruments.functionsExecutedPerGenerationHistogram) {
|
|
8910
|
+
instruments.functionsExecutedPerGenerationHistogram.record(
|
|
8911
|
+
functionsExecuted,
|
|
8912
|
+
labels
|
|
8913
|
+
);
|
|
8914
|
+
}
|
|
8915
|
+
if (functionErrorCorrection && instruments.functionErrorCorrectionCounter) {
|
|
8916
|
+
instruments.functionErrorCorrectionCounter.add(1, labels);
|
|
8917
|
+
}
|
|
8918
|
+
} catch (error) {
|
|
8919
|
+
console.warn("Failed to record function calling metric:", error);
|
|
8920
|
+
}
|
|
8921
|
+
};
|
|
8922
|
+
var recordFieldProcessingMetric = (instruments, fieldProcessorsExecuted, streamingFieldProcessorsExecuted, signatureName) => {
|
|
8923
|
+
try {
|
|
8924
|
+
const labels = sanitizeLabels2({
|
|
8925
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8926
|
+
});
|
|
8927
|
+
if (fieldProcessorsExecuted > 0 && instruments.fieldProcessorsExecutedCounter) {
|
|
8928
|
+
instruments.fieldProcessorsExecutedCounter.add(
|
|
8929
|
+
fieldProcessorsExecuted,
|
|
8930
|
+
labels
|
|
8931
|
+
);
|
|
8932
|
+
}
|
|
8933
|
+
if (streamingFieldProcessorsExecuted > 0 && instruments.streamingFieldProcessorsExecutedCounter) {
|
|
8934
|
+
instruments.streamingFieldProcessorsExecutedCounter.add(
|
|
8935
|
+
streamingFieldProcessorsExecuted,
|
|
8936
|
+
labels
|
|
8937
|
+
);
|
|
8938
|
+
}
|
|
8939
|
+
} catch (error) {
|
|
8940
|
+
console.warn("Failed to record field processing metric:", error);
|
|
8941
|
+
}
|
|
8942
|
+
};
|
|
8943
|
+
var recordStreamingMetric = (instruments, isStreaming, deltasEmitted, finalizationDuration, signatureName) => {
|
|
8944
|
+
try {
|
|
8945
|
+
const labels = sanitizeLabels2({
|
|
8946
|
+
is_streaming: isStreaming.toString(),
|
|
8947
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8948
|
+
});
|
|
8949
|
+
if (isStreaming && instruments.streamingGenerationsCounter) {
|
|
8950
|
+
instruments.streamingGenerationsCounter.add(1, labels);
|
|
8951
|
+
}
|
|
8952
|
+
if (deltasEmitted > 0 && instruments.streamingDeltasEmittedCounter) {
|
|
8953
|
+
instruments.streamingDeltasEmittedCounter.add(deltasEmitted, labels);
|
|
8954
|
+
}
|
|
8955
|
+
if (finalizationDuration && instruments.streamingFinalizationLatencyHistogram) {
|
|
8956
|
+
instruments.streamingFinalizationLatencyHistogram.record(
|
|
8957
|
+
finalizationDuration,
|
|
8958
|
+
labels
|
|
8959
|
+
);
|
|
8960
|
+
}
|
|
8961
|
+
} catch (error) {
|
|
8962
|
+
console.warn("Failed to record streaming metric:", error);
|
|
8963
|
+
}
|
|
8964
|
+
};
|
|
8965
|
+
var recordSamplesMetric = (instruments, samplesCount, resultPickerUsed, resultPickerLatency, signatureName) => {
|
|
8966
|
+
try {
|
|
8967
|
+
const labels = sanitizeLabels2({
|
|
8968
|
+
result_picker_used: resultPickerUsed.toString(),
|
|
8969
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8970
|
+
});
|
|
8971
|
+
if (instruments.samplesGeneratedHistogram) {
|
|
8972
|
+
instruments.samplesGeneratedHistogram.record(samplesCount, labels);
|
|
8973
|
+
}
|
|
8974
|
+
if (resultPickerUsed && instruments.resultPickerUsageCounter) {
|
|
8975
|
+
instruments.resultPickerUsageCounter.add(1, labels);
|
|
8976
|
+
}
|
|
8977
|
+
if (resultPickerLatency && instruments.resultPickerLatencyHistogram) {
|
|
8978
|
+
instruments.resultPickerLatencyHistogram.record(
|
|
8979
|
+
resultPickerLatency,
|
|
8980
|
+
labels
|
|
8981
|
+
);
|
|
8982
|
+
}
|
|
8983
|
+
} catch (error) {
|
|
8984
|
+
console.warn("Failed to record samples metric:", error);
|
|
8985
|
+
}
|
|
8986
|
+
};
|
|
8987
|
+
var recordSignatureComplexityMetrics = (instruments, inputFields, outputFields, examplesCount, demosCount, signatureName) => {
|
|
8988
|
+
try {
|
|
8989
|
+
const labels = sanitizeLabels2({
|
|
8990
|
+
...signatureName ? { signature: signatureName } : {}
|
|
8991
|
+
});
|
|
8992
|
+
if (instruments.inputFieldsGauge) {
|
|
8993
|
+
instruments.inputFieldsGauge.record(inputFields, labels);
|
|
8994
|
+
}
|
|
8995
|
+
if (instruments.outputFieldsGauge) {
|
|
8996
|
+
instruments.outputFieldsGauge.record(outputFields, labels);
|
|
8997
|
+
}
|
|
8998
|
+
if (instruments.examplesUsedGauge) {
|
|
8999
|
+
instruments.examplesUsedGauge.record(examplesCount, labels);
|
|
9000
|
+
}
|
|
9001
|
+
if (instruments.demosUsedGauge) {
|
|
9002
|
+
instruments.demosUsedGauge.record(demosCount, labels);
|
|
9003
|
+
}
|
|
9004
|
+
} catch (error) {
|
|
9005
|
+
console.warn("Failed to record signature complexity metrics:", error);
|
|
9006
|
+
}
|
|
9007
|
+
};
|
|
9008
|
+
var recordPerformanceMetric = (instruments, metricType, duration, signatureName) => {
|
|
9009
|
+
try {
|
|
9010
|
+
const labels = sanitizeLabels2({
|
|
9011
|
+
metric_type: metricType,
|
|
9012
|
+
...signatureName ? { signature: signatureName } : {}
|
|
9013
|
+
});
|
|
9014
|
+
switch (metricType) {
|
|
9015
|
+
case "prompt_render":
|
|
9016
|
+
if (instruments.promptRenderLatencyHistogram) {
|
|
9017
|
+
instruments.promptRenderLatencyHistogram.record(duration, labels);
|
|
9018
|
+
}
|
|
9019
|
+
break;
|
|
9020
|
+
case "extraction":
|
|
9021
|
+
if (instruments.extractionLatencyHistogram) {
|
|
9022
|
+
instruments.extractionLatencyHistogram.record(duration, labels);
|
|
9023
|
+
}
|
|
9024
|
+
break;
|
|
9025
|
+
case "assertion":
|
|
9026
|
+
if (instruments.assertionLatencyHistogram) {
|
|
9027
|
+
instruments.assertionLatencyHistogram.record(duration, labels);
|
|
9028
|
+
}
|
|
9029
|
+
break;
|
|
9030
|
+
case "state_creation":
|
|
9031
|
+
if (instruments.stateCreationLatencyHistogram) {
|
|
9032
|
+
instruments.stateCreationLatencyHistogram.record(duration, labels);
|
|
9033
|
+
}
|
|
9034
|
+
break;
|
|
9035
|
+
case "memory_update":
|
|
9036
|
+
if (instruments.memoryUpdateLatencyHistogram) {
|
|
9037
|
+
instruments.memoryUpdateLatencyHistogram.record(duration, labels);
|
|
9038
|
+
}
|
|
9039
|
+
break;
|
|
9040
|
+
}
|
|
9041
|
+
} catch (error) {
|
|
9042
|
+
console.warn("Failed to record performance metric:", error);
|
|
9043
|
+
}
|
|
9044
|
+
};
|
|
9045
|
+
|
|
9046
|
+
// dsp/processResponse.ts
|
|
9047
|
+
import "stream/web";
|
|
9048
|
+
|
|
9049
|
+
// ai/util.ts
|
|
9050
|
+
function mergeFunctionCalls(functionCalls, functionCallDeltas) {
|
|
9051
|
+
for (const _fc of functionCallDeltas) {
|
|
9052
|
+
const fc = functionCalls.find((fc2) => fc2.id === _fc.id);
|
|
9053
|
+
if (fc) {
|
|
9054
|
+
if (typeof _fc.function.name == "string" && _fc.function.name.length > 0) {
|
|
9055
|
+
fc.function.name += _fc.function.name;
|
|
9056
|
+
}
|
|
9057
|
+
if (typeof _fc.function.params == "string" && _fc.function.params.length > 0) {
|
|
9058
|
+
fc.function.params += _fc.function.params;
|
|
9059
|
+
}
|
|
9060
|
+
if (typeof _fc.function.params == "object") {
|
|
9061
|
+
fc.function.params = _fc.function.params;
|
|
9062
|
+
}
|
|
9063
|
+
} else {
|
|
9064
|
+
functionCalls.push(_fc);
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
9067
|
+
}
|
|
9068
|
+
|
|
9069
|
+
// dsp/sig.ts
|
|
9070
|
+
import { createHash } from "crypto";
|
|
9071
|
+
|
|
9072
|
+
// dsp/parser.ts
|
|
9073
|
+
var SignatureValidationError = class extends Error {
|
|
9074
|
+
constructor(message, position, context3, suggestion) {
|
|
9075
|
+
super(message);
|
|
9076
|
+
this.position = position;
|
|
9077
|
+
this.context = context3;
|
|
9078
|
+
this.suggestion = suggestion;
|
|
9079
|
+
this.name = "SignatureValidationError";
|
|
9080
|
+
}
|
|
9081
|
+
};
|
|
9082
|
+
var SignatureParser = class {
|
|
9083
|
+
input;
|
|
9084
|
+
position;
|
|
9085
|
+
currentFieldName = null;
|
|
9086
|
+
currentSection = "description";
|
|
9087
|
+
constructor(input) {
|
|
9088
|
+
this.input = input.trim();
|
|
9089
|
+
this.position = 0;
|
|
9090
|
+
if (!this.input) {
|
|
9091
|
+
throw new SignatureValidationError(
|
|
9092
|
+
"Empty signature provided",
|
|
9093
|
+
0,
|
|
9094
|
+
"",
|
|
9095
|
+
'A signature must contain at least input and output fields separated by "->". Example: "userQuery:string -> aiResponse:string"'
|
|
9096
|
+
);
|
|
9097
|
+
}
|
|
9098
|
+
}
|
|
9099
|
+
parse() {
|
|
9100
|
+
try {
|
|
9101
|
+
this.skipWhitespace();
|
|
9102
|
+
const optionalDesc = this.parseParsedString();
|
|
9103
|
+
this.skipWhitespace();
|
|
9104
|
+
this.currentSection = "inputs";
|
|
9105
|
+
const inputs = this.parseFieldList(
|
|
9106
|
+
this.parseInputField.bind(this),
|
|
9107
|
+
"input"
|
|
9108
|
+
);
|
|
9109
|
+
this.skipWhitespace();
|
|
9110
|
+
if (this.position >= this.input.length) {
|
|
9111
|
+
throw new SignatureValidationError(
|
|
9112
|
+
"Incomplete signature: Missing output section",
|
|
9113
|
+
this.position,
|
|
9114
|
+
this.getErrorContext(),
|
|
9115
|
+
'Add "->" followed by output fields. Example: "-> responseText:string"'
|
|
9116
|
+
);
|
|
9117
|
+
}
|
|
9118
|
+
this.expectArrow();
|
|
9119
|
+
this.skipWhitespace();
|
|
9120
|
+
if (this.position >= this.input.length) {
|
|
9121
|
+
throw new SignatureValidationError(
|
|
7943
9122
|
'Incomplete signature: No output fields specified after "->"',
|
|
7944
9123
|
this.position,
|
|
7945
9124
|
this.getErrorContext(),
|
|
@@ -10256,6 +11435,15 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10256
11435
|
this.functions = parseFunctions(options.functions);
|
|
10257
11436
|
}
|
|
10258
11437
|
}
|
|
11438
|
+
getSignatureName() {
|
|
11439
|
+
return this.signature.getDescription() || "unknown_signature";
|
|
11440
|
+
}
|
|
11441
|
+
getMetricsInstruments() {
|
|
11442
|
+
return getOrCreateGenMetricsInstruments();
|
|
11443
|
+
}
|
|
11444
|
+
updateMeter(meter) {
|
|
11445
|
+
getOrCreateGenMetricsInstruments(meter);
|
|
11446
|
+
}
|
|
10259
11447
|
createStates(n) {
|
|
10260
11448
|
return Array.from({ length: n }, (_, index) => ({
|
|
10261
11449
|
index,
|
|
@@ -10445,6 +11633,7 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10445
11633
|
);
|
|
10446
11634
|
}
|
|
10447
11635
|
let prompt;
|
|
11636
|
+
const promptRenderStart = performance.now();
|
|
10448
11637
|
if (Array.isArray(values)) {
|
|
10449
11638
|
validateAxMessageArray(values);
|
|
10450
11639
|
prompt = this.promptTemplate.render(values, {
|
|
@@ -10458,7 +11647,27 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10458
11647
|
demos: this.demos
|
|
10459
11648
|
});
|
|
10460
11649
|
}
|
|
11650
|
+
const promptRenderDuration = performance.now() - promptRenderStart;
|
|
11651
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
11652
|
+
if (metricsInstruments) {
|
|
11653
|
+
recordPerformanceMetric(
|
|
11654
|
+
metricsInstruments,
|
|
11655
|
+
"prompt_render",
|
|
11656
|
+
promptRenderDuration,
|
|
11657
|
+
this.getSignatureName()
|
|
11658
|
+
);
|
|
11659
|
+
}
|
|
11660
|
+
const memoryUpdateStart = performance.now();
|
|
10461
11661
|
mem.addRequest(prompt, options.sessionId);
|
|
11662
|
+
const memoryUpdateDuration = performance.now() - memoryUpdateStart;
|
|
11663
|
+
if (metricsInstruments) {
|
|
11664
|
+
recordPerformanceMetric(
|
|
11665
|
+
metricsInstruments,
|
|
11666
|
+
"memory_update",
|
|
11667
|
+
memoryUpdateDuration,
|
|
11668
|
+
this.getSignatureName()
|
|
11669
|
+
);
|
|
11670
|
+
}
|
|
10462
11671
|
multiStepLoop: for (let n = 0; n < maxSteps; n++) {
|
|
10463
11672
|
const firstStep = n === 0;
|
|
10464
11673
|
for (let errCount = 0; errCount < maxRetries; errCount++) {
|
|
@@ -10487,8 +11696,48 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10487
11696
|
options?.sessionId
|
|
10488
11697
|
);
|
|
10489
11698
|
if (shouldContinue) {
|
|
11699
|
+
const metricsInstruments4 = this.getMetricsInstruments();
|
|
11700
|
+
if (metricsInstruments4) {
|
|
11701
|
+
recordMultiStepMetric(
|
|
11702
|
+
metricsInstruments4,
|
|
11703
|
+
n + 1,
|
|
11704
|
+
maxSteps,
|
|
11705
|
+
this.getSignatureName()
|
|
11706
|
+
);
|
|
11707
|
+
}
|
|
10490
11708
|
continue multiStepLoop;
|
|
10491
11709
|
}
|
|
11710
|
+
const metricsInstruments3 = this.getMetricsInstruments();
|
|
11711
|
+
if (metricsInstruments3) {
|
|
11712
|
+
recordMultiStepMetric(
|
|
11713
|
+
metricsInstruments3,
|
|
11714
|
+
n + 1,
|
|
11715
|
+
maxSteps,
|
|
11716
|
+
this.getSignatureName()
|
|
11717
|
+
);
|
|
11718
|
+
const allFunctionsExecuted = /* @__PURE__ */ new Set();
|
|
11719
|
+
states.forEach((state) => {
|
|
11720
|
+
state.functionsExecuted.forEach(
|
|
11721
|
+
(func) => allFunctionsExecuted.add(func)
|
|
11722
|
+
);
|
|
11723
|
+
});
|
|
11724
|
+
if (allFunctionsExecuted.size > 0) {
|
|
11725
|
+
recordFunctionCallingMetric(
|
|
11726
|
+
metricsInstruments3,
|
|
11727
|
+
true,
|
|
11728
|
+
allFunctionsExecuted.size,
|
|
11729
|
+
true,
|
|
11730
|
+
false,
|
|
11731
|
+
this.getSignatureName()
|
|
11732
|
+
);
|
|
11733
|
+
}
|
|
11734
|
+
recordFieldProcessingMetric(
|
|
11735
|
+
metricsInstruments3,
|
|
11736
|
+
this.fieldProcessors.length,
|
|
11737
|
+
this.streamingFieldProcessors.length,
|
|
11738
|
+
this.getSignatureName()
|
|
11739
|
+
);
|
|
11740
|
+
}
|
|
10492
11741
|
this.getLogger(ai, options)?.("", { tags: ["responseEnd"] });
|
|
10493
11742
|
return;
|
|
10494
11743
|
} catch (e) {
|
|
@@ -10497,6 +11746,14 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10497
11746
|
if (e instanceof ValidationError) {
|
|
10498
11747
|
errorFields = e.getFixingInstructions();
|
|
10499
11748
|
err = e;
|
|
11749
|
+
const metricsInstruments3 = this.getMetricsInstruments();
|
|
11750
|
+
if (metricsInstruments3) {
|
|
11751
|
+
recordValidationErrorMetric(
|
|
11752
|
+
metricsInstruments3,
|
|
11753
|
+
"validation",
|
|
11754
|
+
this.getSignatureName()
|
|
11755
|
+
);
|
|
11756
|
+
}
|
|
10500
11757
|
if (span) {
|
|
10501
11758
|
span.addEvent("validation.error", {
|
|
10502
11759
|
message: e.toString(),
|
|
@@ -10507,6 +11764,14 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10507
11764
|
const e1 = e;
|
|
10508
11765
|
errorFields = e1.getFixingInstructions();
|
|
10509
11766
|
err = e;
|
|
11767
|
+
const assertionMetricsInstruments = this.getMetricsInstruments();
|
|
11768
|
+
if (assertionMetricsInstruments) {
|
|
11769
|
+
recordValidationErrorMetric(
|
|
11770
|
+
assertionMetricsInstruments,
|
|
11771
|
+
"assertion",
|
|
11772
|
+
this.getSignatureName()
|
|
11773
|
+
);
|
|
11774
|
+
}
|
|
10510
11775
|
if (span) {
|
|
10511
11776
|
span.addEvent("assertion.error", {
|
|
10512
11777
|
message: e1.toString(),
|
|
@@ -10528,12 +11793,31 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10528
11793
|
}
|
|
10529
11794
|
}
|
|
10530
11795
|
}
|
|
11796
|
+
const metricsInstruments2 = this.getMetricsInstruments();
|
|
11797
|
+
if (metricsInstruments2) {
|
|
11798
|
+
recordErrorCorrectionMetric(
|
|
11799
|
+
metricsInstruments2,
|
|
11800
|
+
maxRetries,
|
|
11801
|
+
false,
|
|
11802
|
+
// failed
|
|
11803
|
+
maxRetries,
|
|
11804
|
+
this.getSignatureName()
|
|
11805
|
+
);
|
|
11806
|
+
}
|
|
10531
11807
|
throw enhanceError(
|
|
10532
11808
|
new Error(`Unable to fix validation error: ${err?.toString()}`),
|
|
10533
11809
|
ai,
|
|
10534
11810
|
this.signature
|
|
10535
11811
|
);
|
|
10536
11812
|
}
|
|
11813
|
+
if (metricsInstruments) {
|
|
11814
|
+
recordMultiStepMetric(
|
|
11815
|
+
metricsInstruments,
|
|
11816
|
+
maxSteps,
|
|
11817
|
+
maxSteps,
|
|
11818
|
+
this.getSignatureName()
|
|
11819
|
+
);
|
|
11820
|
+
}
|
|
10537
11821
|
throw enhanceError(
|
|
10538
11822
|
new Error(`Max steps reached: ${maxSteps}`),
|
|
10539
11823
|
ai,
|
|
@@ -10541,7 +11825,18 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10541
11825
|
);
|
|
10542
11826
|
}
|
|
10543
11827
|
async *_forward1(ai, values, options) {
|
|
11828
|
+
const stateCreationStart = performance.now();
|
|
10544
11829
|
const states = this.createStates(options.sampleCount ?? 1);
|
|
11830
|
+
const stateCreationDuration = performance.now() - stateCreationStart;
|
|
11831
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
11832
|
+
if (metricsInstruments) {
|
|
11833
|
+
recordPerformanceMetric(
|
|
11834
|
+
metricsInstruments,
|
|
11835
|
+
"state_creation",
|
|
11836
|
+
stateCreationDuration,
|
|
11837
|
+
this.getSignatureName()
|
|
11838
|
+
);
|
|
11839
|
+
}
|
|
10545
11840
|
const tracer = options?.tracer ?? this.options?.tracer ?? ai.getOptions().tracer;
|
|
10546
11841
|
let functions = this.functions;
|
|
10547
11842
|
if (options?.functions) {
|
|
@@ -10600,29 +11895,111 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
10600
11895
|
}
|
|
10601
11896
|
}
|
|
10602
11897
|
async forward(ai, values, options) {
|
|
10603
|
-
const
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
|
|
10607
|
-
|
|
10608
|
-
|
|
11898
|
+
const startTime = performance.now();
|
|
11899
|
+
const signatureName = this.getSignatureName();
|
|
11900
|
+
const isStreaming = options?.stream ?? false;
|
|
11901
|
+
let success = false;
|
|
11902
|
+
let errorCorrectionAttempts = 0;
|
|
11903
|
+
let functionsEnabled = false;
|
|
11904
|
+
let functionsExecuted = 0;
|
|
11905
|
+
let resultPickerUsed = false;
|
|
11906
|
+
try {
|
|
11907
|
+
const metricsInstruments = this.getMetricsInstruments();
|
|
11908
|
+
if (metricsInstruments) {
|
|
11909
|
+
recordSignatureComplexityMetrics(
|
|
11910
|
+
metricsInstruments,
|
|
11911
|
+
this.signature.getInputFields().length,
|
|
11912
|
+
this.signature.getOutputFields().length,
|
|
11913
|
+
this.examples?.length ?? 0,
|
|
11914
|
+
this.demos?.length ?? 0,
|
|
11915
|
+
signatureName
|
|
11916
|
+
);
|
|
11917
|
+
}
|
|
11918
|
+
functionsEnabled = !!(options?.functions || this.functions);
|
|
11919
|
+
const generator = this._forward1(ai, values, options ?? {});
|
|
11920
|
+
let buffer = [];
|
|
11921
|
+
let currentVersion = 0;
|
|
11922
|
+
let deltasEmitted = 0;
|
|
11923
|
+
for await (const delta of generator) {
|
|
11924
|
+
if (delta.version !== currentVersion) {
|
|
11925
|
+
buffer = [];
|
|
11926
|
+
}
|
|
11927
|
+
currentVersion = delta.version;
|
|
11928
|
+
buffer = mergeDeltas(buffer, delta);
|
|
11929
|
+
deltasEmitted++;
|
|
11930
|
+
}
|
|
11931
|
+
errorCorrectionAttempts = currentVersion;
|
|
11932
|
+
const resultPickerStart = performance.now();
|
|
11933
|
+
resultPickerUsed = !!options?.resultPicker;
|
|
11934
|
+
const selectedIndex = await selectFromSamples(
|
|
11935
|
+
buffer,
|
|
11936
|
+
{
|
|
11937
|
+
resultPicker: options?.resultPicker
|
|
11938
|
+
},
|
|
11939
|
+
// Pass memory to enable function result selection
|
|
11940
|
+
options?.mem,
|
|
11941
|
+
options?.sessionId
|
|
11942
|
+
);
|
|
11943
|
+
const resultPickerLatency = performance.now() - resultPickerStart;
|
|
11944
|
+
const selectedResult = buffer[selectedIndex];
|
|
11945
|
+
const result = selectedResult?.delta ?? {};
|
|
11946
|
+
this.trace = { ...values, ...result };
|
|
11947
|
+
success = true;
|
|
11948
|
+
if (metricsInstruments) {
|
|
11949
|
+
recordSamplesMetric(
|
|
11950
|
+
metricsInstruments,
|
|
11951
|
+
buffer.length,
|
|
11952
|
+
resultPickerUsed,
|
|
11953
|
+
resultPickerUsed ? resultPickerLatency : void 0,
|
|
11954
|
+
signatureName
|
|
11955
|
+
);
|
|
11956
|
+
recordStreamingMetric(
|
|
11957
|
+
metricsInstruments,
|
|
11958
|
+
isStreaming,
|
|
11959
|
+
deltasEmitted,
|
|
11960
|
+
void 0,
|
|
11961
|
+
// finalization latency not applicable here
|
|
11962
|
+
signatureName
|
|
11963
|
+
);
|
|
11964
|
+
}
|
|
11965
|
+
return result;
|
|
11966
|
+
} catch (error) {
|
|
11967
|
+
success = false;
|
|
11968
|
+
throw error;
|
|
11969
|
+
} finally {
|
|
11970
|
+
const duration = performance.now() - startTime;
|
|
11971
|
+
const finalMetricsInstruments = this.getMetricsInstruments();
|
|
11972
|
+
if (finalMetricsInstruments) {
|
|
11973
|
+
recordGenerationMetric(
|
|
11974
|
+
finalMetricsInstruments,
|
|
11975
|
+
duration,
|
|
11976
|
+
success,
|
|
11977
|
+
signatureName,
|
|
11978
|
+
ai.getName(),
|
|
11979
|
+
options?.model
|
|
11980
|
+
);
|
|
11981
|
+
if (functionsEnabled) {
|
|
11982
|
+
recordFunctionCallingMetric(
|
|
11983
|
+
finalMetricsInstruments,
|
|
11984
|
+
functionsEnabled,
|
|
11985
|
+
functionsExecuted,
|
|
11986
|
+
functionsExecuted > 0,
|
|
11987
|
+
false,
|
|
11988
|
+
// function error correction tracking would need more complex logic
|
|
11989
|
+
signatureName
|
|
11990
|
+
);
|
|
11991
|
+
}
|
|
11992
|
+
if (errorCorrectionAttempts > 0) {
|
|
11993
|
+
recordErrorCorrectionMetric(
|
|
11994
|
+
finalMetricsInstruments,
|
|
11995
|
+
errorCorrectionAttempts,
|
|
11996
|
+
success,
|
|
11997
|
+
options?.maxRetries ?? 10,
|
|
11998
|
+
signatureName
|
|
11999
|
+
);
|
|
12000
|
+
}
|
|
10609
12001
|
}
|
|
10610
|
-
currentVersion = delta.version;
|
|
10611
|
-
buffer = mergeDeltas(buffer, delta);
|
|
10612
12002
|
}
|
|
10613
|
-
const selectedIndex = await selectFromSamples(
|
|
10614
|
-
buffer,
|
|
10615
|
-
{
|
|
10616
|
-
resultPicker: options?.resultPicker
|
|
10617
|
-
},
|
|
10618
|
-
// Pass memory to enable function result selection
|
|
10619
|
-
options?.mem,
|
|
10620
|
-
options?.sessionId
|
|
10621
|
-
);
|
|
10622
|
-
const selectedResult = buffer[selectedIndex];
|
|
10623
|
-
const result = selectedResult?.delta ?? {};
|
|
10624
|
-
this.trace = { ...values, ...result };
|
|
10625
|
-
return result;
|
|
10626
12003
|
}
|
|
10627
12004
|
async *streamingForward(ai, values, options) {
|
|
10628
12005
|
if (!options?.resultPicker) {
|
|
@@ -11315,6 +12692,466 @@ function validateModels2(services) {
|
|
|
11315
12692
|
}
|
|
11316
12693
|
|
|
11317
12694
|
// dsp/optimizer.ts
|
|
12695
|
+
var axDefaultOptimizerMetricsConfig = {
|
|
12696
|
+
enabled: true,
|
|
12697
|
+
enabledCategories: [
|
|
12698
|
+
"optimization",
|
|
12699
|
+
"convergence",
|
|
12700
|
+
"resource_usage",
|
|
12701
|
+
"teacher_student",
|
|
12702
|
+
"checkpointing",
|
|
12703
|
+
"pareto"
|
|
12704
|
+
],
|
|
12705
|
+
maxLabelLength: 100,
|
|
12706
|
+
samplingRate: 1
|
|
12707
|
+
};
|
|
12708
|
+
var globalOptimizerMetricsInstruments;
|
|
12709
|
+
var getOrCreateOptimizerMetricsInstruments = (meter) => {
|
|
12710
|
+
if (globalOptimizerMetricsInstruments) {
|
|
12711
|
+
return globalOptimizerMetricsInstruments;
|
|
12712
|
+
}
|
|
12713
|
+
if (meter) {
|
|
12714
|
+
globalOptimizerMetricsInstruments = createOptimizerMetricsInstruments(meter);
|
|
12715
|
+
return globalOptimizerMetricsInstruments;
|
|
12716
|
+
}
|
|
12717
|
+
return void 0;
|
|
12718
|
+
};
|
|
12719
|
+
var currentOptimizerMetricsConfig = axDefaultOptimizerMetricsConfig;
|
|
12720
|
+
var axUpdateOptimizerMetricsConfig = (config) => {
|
|
12721
|
+
currentOptimizerMetricsConfig = {
|
|
12722
|
+
...currentOptimizerMetricsConfig,
|
|
12723
|
+
...config
|
|
12724
|
+
};
|
|
12725
|
+
};
|
|
12726
|
+
var axGetOptimizerMetricsConfig = () => {
|
|
12727
|
+
return { ...currentOptimizerMetricsConfig };
|
|
12728
|
+
};
|
|
12729
|
+
var createOptimizerMetricsInstruments = (meter) => {
|
|
12730
|
+
return {
|
|
12731
|
+
// Optimization flow metrics
|
|
12732
|
+
optimizationLatencyHistogram: meter.createHistogram(
|
|
12733
|
+
"ax_optimizer_optimization_duration_ms",
|
|
12734
|
+
{
|
|
12735
|
+
description: "End-to-end duration of optimization runs",
|
|
12736
|
+
unit: "ms"
|
|
12737
|
+
}
|
|
12738
|
+
),
|
|
12739
|
+
optimizationRequestsCounter: meter.createCounter(
|
|
12740
|
+
"ax_optimizer_optimization_requests_total",
|
|
12741
|
+
{
|
|
12742
|
+
description: "Total number of optimization requests"
|
|
12743
|
+
}
|
|
12744
|
+
),
|
|
12745
|
+
optimizationErrorsCounter: meter.createCounter(
|
|
12746
|
+
"ax_optimizer_optimization_errors_total",
|
|
12747
|
+
{
|
|
12748
|
+
description: "Total number of failed optimizations"
|
|
12749
|
+
}
|
|
12750
|
+
),
|
|
12751
|
+
// Convergence metrics
|
|
12752
|
+
convergenceRoundsHistogram: meter.createHistogram(
|
|
12753
|
+
"ax_optimizer_convergence_rounds",
|
|
12754
|
+
{
|
|
12755
|
+
description: "Number of rounds until convergence"
|
|
12756
|
+
}
|
|
12757
|
+
),
|
|
12758
|
+
convergenceScoreGauge: meter.createGauge("ax_optimizer_convergence_score", {
|
|
12759
|
+
description: "Current best score during optimization"
|
|
12760
|
+
}),
|
|
12761
|
+
convergenceImprovementGauge: meter.createGauge(
|
|
12762
|
+
"ax_optimizer_convergence_improvement",
|
|
12763
|
+
{
|
|
12764
|
+
description: "Improvement in score from baseline"
|
|
12765
|
+
}
|
|
12766
|
+
),
|
|
12767
|
+
stagnationRoundsGauge: meter.createGauge("ax_optimizer_stagnation_rounds", {
|
|
12768
|
+
description: "Number of rounds without improvement"
|
|
12769
|
+
}),
|
|
12770
|
+
earlyStoppingCounter: meter.createCounter(
|
|
12771
|
+
"ax_optimizer_early_stopping_total",
|
|
12772
|
+
{
|
|
12773
|
+
description: "Total number of early stopping events"
|
|
12774
|
+
}
|
|
12775
|
+
),
|
|
12776
|
+
// Resource usage metrics
|
|
12777
|
+
tokenUsageCounter: meter.createCounter("ax_optimizer_token_usage_total", {
|
|
12778
|
+
description: "Total tokens used during optimization"
|
|
12779
|
+
}),
|
|
12780
|
+
costUsageCounter: meter.createCounter("ax_optimizer_cost_usage_total", {
|
|
12781
|
+
description: "Total cost incurred during optimization",
|
|
12782
|
+
unit: "$"
|
|
12783
|
+
}),
|
|
12784
|
+
memoryUsageGauge: meter.createGauge("ax_optimizer_memory_usage_bytes", {
|
|
12785
|
+
description: "Peak memory usage during optimization",
|
|
12786
|
+
unit: "By"
|
|
12787
|
+
}),
|
|
12788
|
+
optimizationDurationHistogram: meter.createHistogram(
|
|
12789
|
+
"ax_optimizer_duration_ms",
|
|
12790
|
+
{
|
|
12791
|
+
description: "Duration of optimization runs",
|
|
12792
|
+
unit: "ms"
|
|
12793
|
+
}
|
|
12794
|
+
),
|
|
12795
|
+
// Teacher-student metrics
|
|
12796
|
+
teacherStudentUsageCounter: meter.createCounter(
|
|
12797
|
+
"ax_optimizer_teacher_student_usage_total",
|
|
12798
|
+
{
|
|
12799
|
+
description: "Total number of teacher-student interactions"
|
|
12800
|
+
}
|
|
12801
|
+
),
|
|
12802
|
+
teacherStudentLatencyHistogram: meter.createHistogram(
|
|
12803
|
+
"ax_optimizer_teacher_student_latency_ms",
|
|
12804
|
+
{
|
|
12805
|
+
description: "Latency of teacher-student interactions",
|
|
12806
|
+
unit: "ms"
|
|
12807
|
+
}
|
|
12808
|
+
),
|
|
12809
|
+
teacherStudentScoreImprovementGauge: meter.createGauge(
|
|
12810
|
+
"ax_optimizer_teacher_student_score_improvement",
|
|
12811
|
+
{
|
|
12812
|
+
description: "Score improvement from teacher-student interactions"
|
|
12813
|
+
}
|
|
12814
|
+
),
|
|
12815
|
+
// Checkpointing metrics
|
|
12816
|
+
checkpointSaveCounter: meter.createCounter(
|
|
12817
|
+
"ax_optimizer_checkpoint_save_total",
|
|
12818
|
+
{
|
|
12819
|
+
description: "Total number of checkpoint saves"
|
|
12820
|
+
}
|
|
12821
|
+
),
|
|
12822
|
+
checkpointLoadCounter: meter.createCounter(
|
|
12823
|
+
"ax_optimizer_checkpoint_load_total",
|
|
12824
|
+
{
|
|
12825
|
+
description: "Total number of checkpoint loads"
|
|
12826
|
+
}
|
|
12827
|
+
),
|
|
12828
|
+
checkpointSaveLatencyHistogram: meter.createHistogram(
|
|
12829
|
+
"ax_optimizer_checkpoint_save_latency_ms",
|
|
12830
|
+
{
|
|
12831
|
+
description: "Latency of checkpoint save operations",
|
|
12832
|
+
unit: "ms"
|
|
12833
|
+
}
|
|
12834
|
+
),
|
|
12835
|
+
checkpointLoadLatencyHistogram: meter.createHistogram(
|
|
12836
|
+
"ax_optimizer_checkpoint_load_latency_ms",
|
|
12837
|
+
{
|
|
12838
|
+
description: "Latency of checkpoint load operations",
|
|
12839
|
+
unit: "ms"
|
|
12840
|
+
}
|
|
12841
|
+
),
|
|
12842
|
+
// Pareto optimization metrics
|
|
12843
|
+
paretoOptimizationsCounter: meter.createCounter(
|
|
12844
|
+
"ax_optimizer_pareto_optimizations_total",
|
|
12845
|
+
{
|
|
12846
|
+
description: "Total number of Pareto optimizations"
|
|
12847
|
+
}
|
|
12848
|
+
),
|
|
12849
|
+
paretoFrontSizeHistogram: meter.createHistogram(
|
|
12850
|
+
"ax_optimizer_pareto_front_size",
|
|
12851
|
+
{
|
|
12852
|
+
description: "Size of Pareto frontier"
|
|
12853
|
+
}
|
|
12854
|
+
),
|
|
12855
|
+
paretoHypervolumeGauge: meter.createGauge(
|
|
12856
|
+
"ax_optimizer_pareto_hypervolume",
|
|
12857
|
+
{
|
|
12858
|
+
description: "Hypervolume of Pareto frontier"
|
|
12859
|
+
}
|
|
12860
|
+
),
|
|
12861
|
+
paretoSolutionsGeneratedHistogram: meter.createHistogram(
|
|
12862
|
+
"ax_optimizer_pareto_solutions_generated",
|
|
12863
|
+
{
|
|
12864
|
+
description: "Number of solutions generated for Pareto optimization"
|
|
12865
|
+
}
|
|
12866
|
+
),
|
|
12867
|
+
// Program complexity metrics
|
|
12868
|
+
programInputFieldsGauge: meter.createGauge(
|
|
12869
|
+
"ax_optimizer_program_input_fields",
|
|
12870
|
+
{
|
|
12871
|
+
description: "Number of input fields in optimized program"
|
|
12872
|
+
}
|
|
12873
|
+
),
|
|
12874
|
+
programOutputFieldsGauge: meter.createGauge(
|
|
12875
|
+
"ax_optimizer_program_output_fields",
|
|
12876
|
+
{
|
|
12877
|
+
description: "Number of output fields in optimized program"
|
|
12878
|
+
}
|
|
12879
|
+
),
|
|
12880
|
+
examplesCountGauge: meter.createGauge("ax_optimizer_examples_count", {
|
|
12881
|
+
description: "Number of training examples used"
|
|
12882
|
+
}),
|
|
12883
|
+
validationSetSizeGauge: meter.createGauge(
|
|
12884
|
+
"ax_optimizer_validation_set_size",
|
|
12885
|
+
{
|
|
12886
|
+
description: "Size of validation set used"
|
|
12887
|
+
}
|
|
12888
|
+
),
|
|
12889
|
+
// Performance metrics
|
|
12890
|
+
evaluationLatencyHistogram: meter.createHistogram(
|
|
12891
|
+
"ax_optimizer_evaluation_latency_ms",
|
|
12892
|
+
{
|
|
12893
|
+
description: "Latency of program evaluations",
|
|
12894
|
+
unit: "ms"
|
|
12895
|
+
}
|
|
12896
|
+
),
|
|
12897
|
+
demoGenerationLatencyHistogram: meter.createHistogram(
|
|
12898
|
+
"ax_optimizer_demo_generation_latency_ms",
|
|
12899
|
+
{
|
|
12900
|
+
description: "Latency of demo generation",
|
|
12901
|
+
unit: "ms"
|
|
12902
|
+
}
|
|
12903
|
+
),
|
|
12904
|
+
metricComputationLatencyHistogram: meter.createHistogram(
|
|
12905
|
+
"ax_optimizer_metric_computation_latency_ms",
|
|
12906
|
+
{
|
|
12907
|
+
description: "Latency of metric computation",
|
|
12908
|
+
unit: "ms"
|
|
12909
|
+
}
|
|
12910
|
+
),
|
|
12911
|
+
// Configuration metrics
|
|
12912
|
+
optimizerTypeGauge: meter.createGauge("ax_optimizer_type", {
|
|
12913
|
+
description: "Type of optimizer being used"
|
|
12914
|
+
}),
|
|
12915
|
+
targetScoreGauge: meter.createGauge("ax_optimizer_target_score", {
|
|
12916
|
+
description: "Target score for optimization"
|
|
12917
|
+
}),
|
|
12918
|
+
maxRoundsGauge: meter.createGauge("ax_optimizer_max_rounds", {
|
|
12919
|
+
description: "Maximum rounds for optimization"
|
|
12920
|
+
})
|
|
12921
|
+
};
|
|
12922
|
+
};
|
|
12923
|
+
var sanitizeOptimizerLabels = (labels) => {
|
|
12924
|
+
const sanitized = {};
|
|
12925
|
+
for (const [key, value] of Object.entries(labels)) {
|
|
12926
|
+
if (value !== void 0 && value !== null) {
|
|
12927
|
+
const stringValue = String(value);
|
|
12928
|
+
const maxLength = currentOptimizerMetricsConfig.maxLabelLength;
|
|
12929
|
+
sanitized[key] = stringValue.length > maxLength ? stringValue.substring(0, maxLength) : stringValue;
|
|
12930
|
+
}
|
|
12931
|
+
}
|
|
12932
|
+
return sanitized;
|
|
12933
|
+
};
|
|
12934
|
+
var recordOptimizationMetric = (instruments, duration, success, optimizerType, programSignature) => {
|
|
12935
|
+
try {
|
|
12936
|
+
const labels = sanitizeOptimizerLabels({
|
|
12937
|
+
success: success.toString(),
|
|
12938
|
+
optimizer_type: optimizerType,
|
|
12939
|
+
...programSignature ? { program_signature: programSignature } : {}
|
|
12940
|
+
});
|
|
12941
|
+
if (instruments.optimizationLatencyHistogram) {
|
|
12942
|
+
instruments.optimizationLatencyHistogram.record(duration, labels);
|
|
12943
|
+
}
|
|
12944
|
+
if (instruments.optimizationRequestsCounter) {
|
|
12945
|
+
instruments.optimizationRequestsCounter.add(1, labels);
|
|
12946
|
+
}
|
|
12947
|
+
if (!success && instruments.optimizationErrorsCounter) {
|
|
12948
|
+
instruments.optimizationErrorsCounter.add(1, labels);
|
|
12949
|
+
}
|
|
12950
|
+
} catch (error) {
|
|
12951
|
+
console.warn("Failed to record optimization metric:", error);
|
|
12952
|
+
}
|
|
12953
|
+
};
|
|
12954
|
+
var recordConvergenceMetric = (instruments, rounds, currentScore, improvement, stagnationRounds, optimizerType) => {
|
|
12955
|
+
try {
|
|
12956
|
+
const labels = sanitizeOptimizerLabels({
|
|
12957
|
+
optimizer_type: optimizerType
|
|
12958
|
+
});
|
|
12959
|
+
if (instruments.convergenceRoundsHistogram) {
|
|
12960
|
+
instruments.convergenceRoundsHistogram.record(rounds, labels);
|
|
12961
|
+
}
|
|
12962
|
+
if (instruments.convergenceScoreGauge) {
|
|
12963
|
+
instruments.convergenceScoreGauge.record(currentScore, labels);
|
|
12964
|
+
}
|
|
12965
|
+
if (instruments.convergenceImprovementGauge) {
|
|
12966
|
+
instruments.convergenceImprovementGauge.record(improvement, labels);
|
|
12967
|
+
}
|
|
12968
|
+
if (instruments.stagnationRoundsGauge) {
|
|
12969
|
+
instruments.stagnationRoundsGauge.record(stagnationRounds, labels);
|
|
12970
|
+
}
|
|
12971
|
+
} catch (error) {
|
|
12972
|
+
console.warn("Failed to record convergence metric:", error);
|
|
12973
|
+
}
|
|
12974
|
+
};
|
|
12975
|
+
var recordEarlyStoppingMetric = (instruments, reason, optimizerType) => {
|
|
12976
|
+
try {
|
|
12977
|
+
const labels = sanitizeOptimizerLabels({
|
|
12978
|
+
reason,
|
|
12979
|
+
optimizer_type: optimizerType
|
|
12980
|
+
});
|
|
12981
|
+
if (instruments.earlyStoppingCounter) {
|
|
12982
|
+
instruments.earlyStoppingCounter.add(1, labels);
|
|
12983
|
+
}
|
|
12984
|
+
} catch (error) {
|
|
12985
|
+
console.warn("Failed to record early stopping metric:", error);
|
|
12986
|
+
}
|
|
12987
|
+
};
|
|
12988
|
+
var recordResourceUsageMetric = (instruments, tokensUsed, costIncurred, optimizerType, memoryUsage) => {
|
|
12989
|
+
try {
|
|
12990
|
+
const labels = sanitizeOptimizerLabels({
|
|
12991
|
+
optimizer_type: optimizerType
|
|
12992
|
+
});
|
|
12993
|
+
if (instruments.tokenUsageCounter) {
|
|
12994
|
+
instruments.tokenUsageCounter.add(tokensUsed, labels);
|
|
12995
|
+
}
|
|
12996
|
+
if (instruments.costUsageCounter) {
|
|
12997
|
+
instruments.costUsageCounter.add(costIncurred, labels);
|
|
12998
|
+
}
|
|
12999
|
+
if (memoryUsage !== void 0 && instruments.memoryUsageGauge) {
|
|
13000
|
+
instruments.memoryUsageGauge.record(memoryUsage, labels);
|
|
13001
|
+
}
|
|
13002
|
+
} catch (error) {
|
|
13003
|
+
console.warn("Failed to record resource usage metric:", error);
|
|
13004
|
+
}
|
|
13005
|
+
};
|
|
13006
|
+
var recordOptimizationDurationMetric = (instruments, duration, optimizerType) => {
|
|
13007
|
+
try {
|
|
13008
|
+
const labels = sanitizeOptimizerLabels({
|
|
13009
|
+
optimizer_type: optimizerType
|
|
13010
|
+
});
|
|
13011
|
+
if (instruments.optimizationDurationHistogram) {
|
|
13012
|
+
instruments.optimizationDurationHistogram.record(duration, labels);
|
|
13013
|
+
}
|
|
13014
|
+
} catch (error) {
|
|
13015
|
+
console.warn("Failed to record optimization duration metric:", error);
|
|
13016
|
+
}
|
|
13017
|
+
};
|
|
13018
|
+
var recordTeacherStudentMetric = (instruments, latency, scoreImprovement, optimizerType) => {
|
|
13019
|
+
try {
|
|
13020
|
+
const labels = sanitizeOptimizerLabels({
|
|
13021
|
+
optimizer_type: optimizerType
|
|
13022
|
+
});
|
|
13023
|
+
if (instruments.teacherStudentUsageCounter) {
|
|
13024
|
+
instruments.teacherStudentUsageCounter.add(1, labels);
|
|
13025
|
+
}
|
|
13026
|
+
if (instruments.teacherStudentLatencyHistogram) {
|
|
13027
|
+
instruments.teacherStudentLatencyHistogram.record(latency, labels);
|
|
13028
|
+
}
|
|
13029
|
+
if (instruments.teacherStudentScoreImprovementGauge) {
|
|
13030
|
+
instruments.teacherStudentScoreImprovementGauge.record(
|
|
13031
|
+
scoreImprovement,
|
|
13032
|
+
labels
|
|
13033
|
+
);
|
|
13034
|
+
}
|
|
13035
|
+
} catch (error) {
|
|
13036
|
+
console.warn("Failed to record teacher-student metric:", error);
|
|
13037
|
+
}
|
|
13038
|
+
};
|
|
13039
|
+
var recordCheckpointMetric = (instruments, operation, latency, success, optimizerType) => {
|
|
13040
|
+
try {
|
|
13041
|
+
const labels = sanitizeOptimizerLabels({
|
|
13042
|
+
operation,
|
|
13043
|
+
success: success.toString(),
|
|
13044
|
+
optimizer_type: optimizerType
|
|
13045
|
+
});
|
|
13046
|
+
if (operation === "save") {
|
|
13047
|
+
if (instruments.checkpointSaveCounter) {
|
|
13048
|
+
instruments.checkpointSaveCounter.add(1, labels);
|
|
13049
|
+
}
|
|
13050
|
+
if (instruments.checkpointSaveLatencyHistogram) {
|
|
13051
|
+
instruments.checkpointSaveLatencyHistogram.record(latency, labels);
|
|
13052
|
+
}
|
|
13053
|
+
} else {
|
|
13054
|
+
if (instruments.checkpointLoadCounter) {
|
|
13055
|
+
instruments.checkpointLoadCounter.add(1, labels);
|
|
13056
|
+
}
|
|
13057
|
+
if (instruments.checkpointLoadLatencyHistogram) {
|
|
13058
|
+
instruments.checkpointLoadLatencyHistogram.record(latency, labels);
|
|
13059
|
+
}
|
|
13060
|
+
}
|
|
13061
|
+
} catch (error) {
|
|
13062
|
+
console.warn("Failed to record checkpoint metric:", error);
|
|
13063
|
+
}
|
|
13064
|
+
};
|
|
13065
|
+
var recordParetoMetric = (instruments, frontSize, solutionsGenerated, optimizerType, hypervolume) => {
|
|
13066
|
+
try {
|
|
13067
|
+
const labels = sanitizeOptimizerLabels({
|
|
13068
|
+
optimizer_type: optimizerType
|
|
13069
|
+
});
|
|
13070
|
+
if (instruments.paretoOptimizationsCounter) {
|
|
13071
|
+
instruments.paretoOptimizationsCounter.add(1, labels);
|
|
13072
|
+
}
|
|
13073
|
+
if (instruments.paretoFrontSizeHistogram) {
|
|
13074
|
+
instruments.paretoFrontSizeHistogram.record(frontSize, labels);
|
|
13075
|
+
}
|
|
13076
|
+
if (hypervolume !== void 0 && instruments.paretoHypervolumeGauge) {
|
|
13077
|
+
instruments.paretoHypervolumeGauge.record(hypervolume, labels);
|
|
13078
|
+
}
|
|
13079
|
+
if (instruments.paretoSolutionsGeneratedHistogram) {
|
|
13080
|
+
instruments.paretoSolutionsGeneratedHistogram.record(
|
|
13081
|
+
solutionsGenerated,
|
|
13082
|
+
labels
|
|
13083
|
+
);
|
|
13084
|
+
}
|
|
13085
|
+
} catch (error) {
|
|
13086
|
+
console.warn("Failed to record Pareto metric:", error);
|
|
13087
|
+
}
|
|
13088
|
+
};
|
|
13089
|
+
var recordProgramComplexityMetric = (instruments, inputFields, outputFields, examplesCount, validationSetSize, optimizerType) => {
|
|
13090
|
+
try {
|
|
13091
|
+
const labels = sanitizeOptimizerLabels({
|
|
13092
|
+
optimizer_type: optimizerType
|
|
13093
|
+
});
|
|
13094
|
+
if (instruments.programInputFieldsGauge) {
|
|
13095
|
+
instruments.programInputFieldsGauge.record(inputFields, labels);
|
|
13096
|
+
}
|
|
13097
|
+
if (instruments.programOutputFieldsGauge) {
|
|
13098
|
+
instruments.programOutputFieldsGauge.record(outputFields, labels);
|
|
13099
|
+
}
|
|
13100
|
+
if (instruments.examplesCountGauge) {
|
|
13101
|
+
instruments.examplesCountGauge.record(examplesCount, labels);
|
|
13102
|
+
}
|
|
13103
|
+
if (instruments.validationSetSizeGauge) {
|
|
13104
|
+
instruments.validationSetSizeGauge.record(validationSetSize, labels);
|
|
13105
|
+
}
|
|
13106
|
+
} catch (error) {
|
|
13107
|
+
console.warn("Failed to record program complexity metric:", error);
|
|
13108
|
+
}
|
|
13109
|
+
};
|
|
13110
|
+
var recordOptimizerPerformanceMetric = (instruments, metricType, duration, optimizerType) => {
|
|
13111
|
+
try {
|
|
13112
|
+
const labels = sanitizeOptimizerLabels({
|
|
13113
|
+
metric_type: metricType,
|
|
13114
|
+
optimizer_type: optimizerType
|
|
13115
|
+
});
|
|
13116
|
+
switch (metricType) {
|
|
13117
|
+
case "evaluation":
|
|
13118
|
+
if (instruments.evaluationLatencyHistogram) {
|
|
13119
|
+
instruments.evaluationLatencyHistogram.record(duration, labels);
|
|
13120
|
+
}
|
|
13121
|
+
break;
|
|
13122
|
+
case "demo_generation":
|
|
13123
|
+
if (instruments.demoGenerationLatencyHistogram) {
|
|
13124
|
+
instruments.demoGenerationLatencyHistogram.record(duration, labels);
|
|
13125
|
+
}
|
|
13126
|
+
break;
|
|
13127
|
+
case "metric_computation":
|
|
13128
|
+
if (instruments.metricComputationLatencyHistogram) {
|
|
13129
|
+
instruments.metricComputationLatencyHistogram.record(duration, labels);
|
|
13130
|
+
}
|
|
13131
|
+
break;
|
|
13132
|
+
}
|
|
13133
|
+
} catch (error) {
|
|
13134
|
+
console.warn("Failed to record optimizer performance metric:", error);
|
|
13135
|
+
}
|
|
13136
|
+
};
|
|
13137
|
+
var recordOptimizerConfigurationMetric = (instruments, optimizerType, targetScore, maxRounds) => {
|
|
13138
|
+
try {
|
|
13139
|
+
const labels = sanitizeOptimizerLabels({
|
|
13140
|
+
optimizer_type: optimizerType
|
|
13141
|
+
});
|
|
13142
|
+
if (instruments.optimizerTypeGauge) {
|
|
13143
|
+
instruments.optimizerTypeGauge.record(1, labels);
|
|
13144
|
+
}
|
|
13145
|
+
if (targetScore !== void 0 && instruments.targetScoreGauge) {
|
|
13146
|
+
instruments.targetScoreGauge.record(targetScore, labels);
|
|
13147
|
+
}
|
|
13148
|
+
if (maxRounds !== void 0 && instruments.maxRoundsGauge) {
|
|
13149
|
+
instruments.maxRoundsGauge.record(maxRounds, labels);
|
|
13150
|
+
}
|
|
13151
|
+
} catch (error) {
|
|
13152
|
+
console.warn("Failed to record optimizer configuration metric:", error);
|
|
13153
|
+
}
|
|
13154
|
+
};
|
|
11318
13155
|
var AxDefaultCostTracker = class {
|
|
11319
13156
|
tokenUsage = {};
|
|
11320
13157
|
totalTokens = 0;
|
|
@@ -11388,6 +13225,8 @@ var AxBaseOptimizer = class {
|
|
|
11388
13225
|
configurationHistory = [];
|
|
11389
13226
|
// Common optimization statistics
|
|
11390
13227
|
stats;
|
|
13228
|
+
// Metrics instruments
|
|
13229
|
+
metricsInstruments;
|
|
11391
13230
|
constructor(args) {
|
|
11392
13231
|
if (args.examples.length === 0) {
|
|
11393
13232
|
throw new Error("No examples found");
|
|
@@ -11411,6 +13250,9 @@ var AxBaseOptimizer = class {
|
|
|
11411
13250
|
maxTokens: 1e6
|
|
11412
13251
|
});
|
|
11413
13252
|
this.costTracker = args.costTracker ?? costTracker;
|
|
13253
|
+
this.metricsInstruments = getOrCreateOptimizerMetricsInstruments(
|
|
13254
|
+
axGlobals.meter
|
|
13255
|
+
);
|
|
11414
13256
|
this.stats = this.initializeStats();
|
|
11415
13257
|
}
|
|
11416
13258
|
/**
|
|
@@ -11482,6 +13324,7 @@ var AxBaseOptimizer = class {
|
|
|
11482
13324
|
patienceExhausted: reason.includes("improvement"),
|
|
11483
13325
|
reason
|
|
11484
13326
|
};
|
|
13327
|
+
this.recordEarlyStoppingMetrics(reason, "unknown");
|
|
11485
13328
|
if (this.onEarlyStop) {
|
|
11486
13329
|
this.onEarlyStop(reason, this.stats);
|
|
11487
13330
|
}
|
|
@@ -11625,6 +13468,12 @@ var AxBaseOptimizer = class {
|
|
|
11625
13468
|
}
|
|
11626
13469
|
this.updateResourceUsage(startTime);
|
|
11627
13470
|
this.stats.convergenceInfo.converged = true;
|
|
13471
|
+
this.recordParetoMetrics(
|
|
13472
|
+
paretoFront.length,
|
|
13473
|
+
allSolutions.length,
|
|
13474
|
+
"base_optimizer",
|
|
13475
|
+
hypervolume
|
|
13476
|
+
);
|
|
11628
13477
|
const bestScore = paretoFront.length > 0 ? Math.max(
|
|
11629
13478
|
...paretoFront.map((sol) => Math.max(...Object.values(sol.scores)))
|
|
11630
13479
|
) : 0;
|
|
@@ -11931,23 +13780,36 @@ var AxBaseOptimizer = class {
|
|
|
11931
13780
|
async saveCheckpoint(optimizerType, optimizerConfig, bestScore, bestConfiguration, optimizerState = {}, options) {
|
|
11932
13781
|
const saveFn = options?.overrideCheckpointSave || this.checkpointSave;
|
|
11933
13782
|
if (!saveFn) return void 0;
|
|
11934
|
-
const
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
11949
|
-
|
|
11950
|
-
|
|
13783
|
+
const startTime = Date.now();
|
|
13784
|
+
let success = false;
|
|
13785
|
+
let checkpointId;
|
|
13786
|
+
try {
|
|
13787
|
+
const checkpoint = {
|
|
13788
|
+
version: "1.0.0",
|
|
13789
|
+
timestamp: Date.now(),
|
|
13790
|
+
optimizerType,
|
|
13791
|
+
optimizerConfig,
|
|
13792
|
+
currentRound: this.currentRound,
|
|
13793
|
+
totalRounds: this.stats.resourceUsage.totalTime > 0 ? this.currentRound : 0,
|
|
13794
|
+
bestScore,
|
|
13795
|
+
bestConfiguration,
|
|
13796
|
+
scoreHistory: [...this.scoreHistory],
|
|
13797
|
+
configurationHistory: [...this.configurationHistory],
|
|
13798
|
+
stats: { ...this.stats },
|
|
13799
|
+
optimizerState,
|
|
13800
|
+
examples: this.examples,
|
|
13801
|
+
validationSet: this.validationSet
|
|
13802
|
+
};
|
|
13803
|
+
checkpointId = await saveFn(checkpoint);
|
|
13804
|
+
success = true;
|
|
13805
|
+
} catch (error) {
|
|
13806
|
+
success = false;
|
|
13807
|
+
throw error;
|
|
13808
|
+
} finally {
|
|
13809
|
+
const latency = Date.now() - startTime;
|
|
13810
|
+
this.recordCheckpointMetrics("save", latency, success, optimizerType);
|
|
13811
|
+
}
|
|
13812
|
+
return checkpointId;
|
|
11951
13813
|
}
|
|
11952
13814
|
/**
|
|
11953
13815
|
* Load optimization state from checkpoint
|
|
@@ -11955,7 +13817,20 @@ var AxBaseOptimizer = class {
|
|
|
11955
13817
|
async loadCheckpoint(checkpointId, options) {
|
|
11956
13818
|
const loadFn = options?.overrideCheckpointLoad || this.checkpointLoad;
|
|
11957
13819
|
if (!loadFn) return null;
|
|
11958
|
-
|
|
13820
|
+
const startTime = Date.now();
|
|
13821
|
+
let success = false;
|
|
13822
|
+
let checkpoint = null;
|
|
13823
|
+
try {
|
|
13824
|
+
checkpoint = await loadFn(checkpointId);
|
|
13825
|
+
success = checkpoint !== null;
|
|
13826
|
+
} catch (error) {
|
|
13827
|
+
success = false;
|
|
13828
|
+
throw error;
|
|
13829
|
+
} finally {
|
|
13830
|
+
const latency = Date.now() - startTime;
|
|
13831
|
+
this.recordCheckpointMetrics("load", latency, success, "unknown");
|
|
13832
|
+
}
|
|
13833
|
+
return checkpoint;
|
|
11959
13834
|
}
|
|
11960
13835
|
/**
|
|
11961
13836
|
* Restore optimizer state from checkpoint
|
|
@@ -12032,6 +13907,128 @@ var AxBaseOptimizer = class {
|
|
|
12032
13907
|
}
|
|
12033
13908
|
return this.verbose ?? true;
|
|
12034
13909
|
}
|
|
13910
|
+
/**
|
|
13911
|
+
* Record optimization start metrics
|
|
13912
|
+
*/
|
|
13913
|
+
recordOptimizationStart(optimizerType, programSignature) {
|
|
13914
|
+
if (!this.metricsInstruments) return;
|
|
13915
|
+
if (programSignature) {
|
|
13916
|
+
const inputFields = (programSignature.match(/input:/g) || []).length;
|
|
13917
|
+
const outputFields = (programSignature.match(/output:/g) || []).length;
|
|
13918
|
+
recordProgramComplexityMetric(
|
|
13919
|
+
this.metricsInstruments,
|
|
13920
|
+
inputFields,
|
|
13921
|
+
outputFields,
|
|
13922
|
+
this.examples.length,
|
|
13923
|
+
this.getValidationSet().length,
|
|
13924
|
+
optimizerType
|
|
13925
|
+
);
|
|
13926
|
+
}
|
|
13927
|
+
recordOptimizerConfigurationMetric(
|
|
13928
|
+
this.metricsInstruments,
|
|
13929
|
+
optimizerType,
|
|
13930
|
+
this.targetScore,
|
|
13931
|
+
void 0
|
|
13932
|
+
// maxRounds would be set by concrete optimizers
|
|
13933
|
+
);
|
|
13934
|
+
}
|
|
13935
|
+
/**
|
|
13936
|
+
* Record optimization completion metrics
|
|
13937
|
+
*/
|
|
13938
|
+
recordOptimizationComplete(duration, success, optimizerType, programSignature) {
|
|
13939
|
+
if (!this.metricsInstruments) return;
|
|
13940
|
+
recordOptimizationMetric(
|
|
13941
|
+
this.metricsInstruments,
|
|
13942
|
+
duration,
|
|
13943
|
+
success,
|
|
13944
|
+
optimizerType,
|
|
13945
|
+
programSignature
|
|
13946
|
+
);
|
|
13947
|
+
recordOptimizationDurationMetric(
|
|
13948
|
+
this.metricsInstruments,
|
|
13949
|
+
duration,
|
|
13950
|
+
optimizerType
|
|
13951
|
+
);
|
|
13952
|
+
const currentCost = this.costTracker?.getCurrentCost() ?? 0;
|
|
13953
|
+
const totalTokens = this.costTracker?.getTotalTokens() ?? 0;
|
|
13954
|
+
recordResourceUsageMetric(
|
|
13955
|
+
this.metricsInstruments,
|
|
13956
|
+
totalTokens,
|
|
13957
|
+
currentCost,
|
|
13958
|
+
optimizerType
|
|
13959
|
+
);
|
|
13960
|
+
}
|
|
13961
|
+
/**
|
|
13962
|
+
* Record convergence metrics
|
|
13963
|
+
*/
|
|
13964
|
+
recordConvergenceMetrics(rounds, currentScore, improvement, stagnationRounds, optimizerType) {
|
|
13965
|
+
if (!this.metricsInstruments) return;
|
|
13966
|
+
recordConvergenceMetric(
|
|
13967
|
+
this.metricsInstruments,
|
|
13968
|
+
rounds,
|
|
13969
|
+
currentScore,
|
|
13970
|
+
improvement,
|
|
13971
|
+
stagnationRounds,
|
|
13972
|
+
optimizerType
|
|
13973
|
+
);
|
|
13974
|
+
}
|
|
13975
|
+
/**
|
|
13976
|
+
* Record early stopping metrics
|
|
13977
|
+
*/
|
|
13978
|
+
recordEarlyStoppingMetrics(reason, optimizerType) {
|
|
13979
|
+
if (!this.metricsInstruments) return;
|
|
13980
|
+
recordEarlyStoppingMetric(this.metricsInstruments, reason, optimizerType);
|
|
13981
|
+
}
|
|
13982
|
+
/**
|
|
13983
|
+
* Record teacher-student interaction metrics
|
|
13984
|
+
*/
|
|
13985
|
+
recordTeacherStudentMetrics(latency, scoreImprovement, optimizerType) {
|
|
13986
|
+
if (!this.metricsInstruments) return;
|
|
13987
|
+
recordTeacherStudentMetric(
|
|
13988
|
+
this.metricsInstruments,
|
|
13989
|
+
latency,
|
|
13990
|
+
scoreImprovement,
|
|
13991
|
+
optimizerType
|
|
13992
|
+
);
|
|
13993
|
+
}
|
|
13994
|
+
/**
|
|
13995
|
+
* Record checkpoint metrics
|
|
13996
|
+
*/
|
|
13997
|
+
recordCheckpointMetrics(operation, latency, success, optimizerType) {
|
|
13998
|
+
if (!this.metricsInstruments) return;
|
|
13999
|
+
recordCheckpointMetric(
|
|
14000
|
+
this.metricsInstruments,
|
|
14001
|
+
operation,
|
|
14002
|
+
latency,
|
|
14003
|
+
success,
|
|
14004
|
+
optimizerType
|
|
14005
|
+
);
|
|
14006
|
+
}
|
|
14007
|
+
/**
|
|
14008
|
+
* Record Pareto optimization metrics
|
|
14009
|
+
*/
|
|
14010
|
+
recordParetoMetrics(frontSize, solutionsGenerated, optimizerType, hypervolume) {
|
|
14011
|
+
if (!this.metricsInstruments) return;
|
|
14012
|
+
recordParetoMetric(
|
|
14013
|
+
this.metricsInstruments,
|
|
14014
|
+
frontSize,
|
|
14015
|
+
solutionsGenerated,
|
|
14016
|
+
optimizerType,
|
|
14017
|
+
hypervolume
|
|
14018
|
+
);
|
|
14019
|
+
}
|
|
14020
|
+
/**
|
|
14021
|
+
* Record performance metrics
|
|
14022
|
+
*/
|
|
14023
|
+
recordPerformanceMetrics(metricType, duration, optimizerType) {
|
|
14024
|
+
if (!this.metricsInstruments) return;
|
|
14025
|
+
recordOptimizerPerformanceMetric(
|
|
14026
|
+
this.metricsInstruments,
|
|
14027
|
+
metricType,
|
|
14028
|
+
duration,
|
|
14029
|
+
optimizerType
|
|
14030
|
+
);
|
|
14031
|
+
}
|
|
12035
14032
|
};
|
|
12036
14033
|
|
|
12037
14034
|
// db/base.ts
|
|
@@ -17573,10 +19570,15 @@ export {
|
|
|
17573
19570
|
axAITogetherDefaultConfig,
|
|
17574
19571
|
axBaseAIDefaultConfig,
|
|
17575
19572
|
axBaseAIDefaultCreativeConfig,
|
|
19573
|
+
axCheckMetricsHealth,
|
|
17576
19574
|
axCreateDefaultLogger,
|
|
17577
19575
|
axCreateDefaultTextLogger,
|
|
17578
19576
|
axCreateOptimizerLogger,
|
|
19577
|
+
axDefaultMetricsConfig,
|
|
17579
19578
|
axDefaultOptimizerLogger,
|
|
19579
|
+
axDefaultOptimizerMetricsConfig,
|
|
19580
|
+
axGetMetricsConfig,
|
|
19581
|
+
axGetOptimizerMetricsConfig,
|
|
17580
19582
|
axGlobals,
|
|
17581
19583
|
axModelInfoAnthropic,
|
|
17582
19584
|
axModelInfoCohere,
|
|
@@ -17592,6 +19594,8 @@ export {
|
|
|
17592
19594
|
axModelInfoTogether,
|
|
17593
19595
|
axSpanAttributes,
|
|
17594
19596
|
axSpanEvents,
|
|
19597
|
+
axUpdateMetricsConfig,
|
|
19598
|
+
axUpdateOptimizerMetricsConfig,
|
|
17595
19599
|
axValidateChatRequestMessage,
|
|
17596
19600
|
axValidateChatResponseResult,
|
|
17597
19601
|
f,
|