@juspay/neurolink 13.4.10 → 13.5.1
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/CHANGELOG.md +2 -3
- package/README.md +3 -2
- package/dist/adapters/video/videoAnalyzer.d.ts +1 -0
- package/dist/adapters/video/videoAnalyzer.js +4 -0
- package/dist/autoresearch/index.d.ts +1 -0
- package/dist/autoresearch/index.js +4 -0
- package/dist/autoresearch/worker.js +4 -0
- package/dist/browser/neurolink.min.js +466 -466
- package/dist/cli/commands/decide.js +25 -5
- package/dist/cli/commands/observability.js +11 -4
- package/dist/cli/commands/telemetry.js +36 -6
- package/dist/cli/utils/formatters.d.ts +17 -0
- package/dist/cli/utils/formatters.js +39 -0
- package/dist/constants/langfuse.d.ts +17 -1
- package/dist/constants/langfuse.js +23 -1
- package/dist/constants/telemetry.d.ts +6 -0
- package/dist/constants/telemetry.js +6 -0
- package/dist/core/baseProvider.js +2 -0
- package/dist/core/geminiLoopAdapter.js +19 -0
- package/dist/core/loopEngine.js +10 -7
- package/dist/core/modules/StreamHandler.js +5 -4
- package/dist/core/modules/TelemetryHandler.d.ts +5 -1
- package/dist/core/modules/TelemetryHandler.js +16 -0
- package/dist/core/modules/ToolsManager.js +3 -0
- package/dist/core/nativeGenerateLoop.js +1 -1
- package/dist/evaluation/index.d.ts +1 -0
- package/dist/evaluation/index.js +4 -0
- package/dist/evaluation/ragasEvaluator.js +1 -0
- package/dist/factories/providerDescriptors.d.ts +4 -3
- package/dist/factories/providerDescriptors.js +6 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/externalServerManager.js +6 -2
- package/dist/mcp/toolRegistry.js +3 -0
- package/dist/neurolink.d.ts +20 -10
- package/dist/neurolink.js +134 -65
- package/dist/observability/FEATURE-STATUS.md +0 -4
- package/dist/observability/exporterRegistry.d.ts +6 -1
- package/dist/observability/exporterRegistry.js +18 -0
- package/dist/observability/exporterSpanProcessor.d.ts +20 -6
- package/dist/observability/exporterSpanProcessor.js +166 -34
- package/dist/observability/exporters/baseExporter.d.ts +22 -3
- package/dist/observability/exporters/baseExporter.js +87 -5
- package/dist/observability/exporters/langfuseExporter.d.ts +29 -3
- package/dist/observability/exporters/langfuseExporter.js +251 -41
- package/dist/observability/langfuseMasking.d.ts +1 -1
- package/dist/observability/langfuseMasking.js +1 -1
- package/dist/observability/otlpEncoding.d.ts +18 -5
- package/dist/observability/otlpEncoding.js +69 -12
- package/dist/observability/utils/spanSerializer.d.ts +3 -2
- package/dist/observability/utils/spanSerializer.js +5 -3
- package/dist/processors/base/BaseFileProcessor.d.ts +1 -0
- package/dist/processors/base/BaseFileProcessor.js +4 -0
- package/dist/processors/index.d.ts +1 -0
- package/dist/processors/index.js +4 -0
- package/dist/processors/registry/ProcessorRegistry.d.ts +1 -0
- package/dist/processors/registry/ProcessorRegistry.js +5 -0
- package/dist/providers/amazonBedrock/client.js +7 -5
- package/dist/providers/amazonSagemaker.js +32 -12
- package/dist/providers/anthropic/client.js +1 -0
- package/dist/providers/anthropic/loopAdapter.js +7 -3
- package/dist/providers/catalog/provider-catalog.schema.json +64 -3
- package/dist/providers/catalog/schema.js +81 -1
- package/dist/providers/catalog/xor.json +30 -10
- package/dist/providers/configuredDecision.d.ts +8 -1
- package/dist/providers/configuredDecision.js +22 -0
- package/dist/providers/decide/dialects/openaiDecisions.js +8 -0
- package/dist/providers/decide/dialects/systemOne.js +28 -2
- package/dist/providers/decide/guards.d.ts +6 -0
- package/dist/providers/decide/guards.js +22 -0
- package/dist/providers/googleAiStudio/client.js +2 -0
- package/dist/providers/googleVertex/client.d.ts +6 -5
- package/dist/providers/googleVertex/client.js +46 -19
- package/dist/providers/openaiChatCompletionsBase.js +4 -4
- package/dist/providers/systemOneDecision.d.ts +30 -7
- package/dist/providers/systemOneDecision.js +71 -14
- package/dist/proxy/codexUsage.js +59 -2
- package/dist/proxy/proxyTracer.d.ts +25 -1
- package/dist/proxy/proxyTracer.js +146 -22
- package/dist/proxy/proxyTranslationEngine.js +4 -2
- package/dist/proxy/sseInterceptor.js +6 -4
- package/dist/rag/chunkers/BaseChunker.js +1 -0
- package/dist/rag/index.d.ts +1 -0
- package/dist/rag/index.js +4 -0
- package/dist/rag/ragIntegration.js +1 -0
- package/dist/rag/reranker/reranker.js +2 -0
- package/dist/rag/retrieval/vectorQueryTool.js +1 -0
- package/dist/server/routes/codexProxyRoutes.js +3 -1
- package/dist/server/utils/validation.d.ts +3 -3
- package/dist/services/server/ai/observability/instrumentation.d.ts +8 -7
- package/dist/services/server/ai/observability/instrumentation.js +217 -47
- package/dist/services/server/ai/observability/langfuseSetup.d.ts +19 -1
- package/dist/services/server/ai/observability/langfuseSetup.js +62 -4
- package/dist/services/server/ai/observability/otlpSetup.d.ts +12 -2
- package/dist/services/server/ai/observability/otlpSetup.js +55 -4
- package/dist/telemetry/aiMetrics.d.ts +56 -0
- package/dist/telemetry/aiMetrics.js +229 -0
- package/dist/telemetry/attributes.d.ts +24 -1
- package/dist/telemetry/attributes.js +94 -9
- package/dist/telemetry/chatMessages.d.ts +6 -0
- package/dist/telemetry/chatMessages.js +37 -0
- package/dist/telemetry/index.d.ts +1 -1
- package/dist/telemetry/index.js +1 -1
- package/dist/telemetry/observation.d.ts +5 -5
- package/dist/telemetry/observation.js +128 -39
- package/dist/telemetry/spanSanitizer.d.ts +2 -2
- package/dist/telemetry/spanSanitizer.js +76 -8
- package/dist/telemetry/telemetryStarter.d.ts +16 -0
- package/dist/telemetry/telemetryStarter.js +28 -0
- package/dist/telemetry/traceContext.d.ts +3 -3
- package/dist/telemetry/traceContext.js +3 -3
- package/dist/telemetry/tracers.d.ts +13 -1
- package/dist/telemetry/tracers.js +49 -10
- package/dist/telemetry/withSpan.d.ts +19 -3
- package/dist/telemetry/withSpan.js +149 -20
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/decision.d.ts +117 -10
- package/dist/types/exporter.d.ts +98 -3
- package/dist/types/livekit.d.ts +16 -1
- package/dist/types/loopEngine.d.ts +16 -1
- package/dist/types/observability.d.ts +38 -5
- package/dist/types/providerCatalog.d.ts +12 -1
- package/dist/types/providers.d.ts +2 -0
- package/dist/types/proxy.d.ts +2 -0
- package/dist/types/span.d.ts +26 -0
- package/dist/utils/decisionAnswers.d.ts +7 -1
- package/dist/utils/decisionAnswers.js +43 -2
- package/dist/utils/decisionLimits.d.ts +13 -1
- package/dist/utils/decisionLimits.js +52 -1
- package/dist/utils/decisionMedia.d.ts +4 -2
- package/dist/utils/decisionMedia.js +216 -14
- package/dist/utils/timeout.js +4 -2
- package/dist/voice/livekit/realtimeMcpTools.js +11 -2
- package/dist/voice/livekit/realtimeMemory.d.ts +20 -2
- package/dist/voice/livekit/realtimeMemory.js +139 -46
- package/dist/voice/livekit/realtimeVoiceAgent.js +20 -8
- package/dist/voice/livekit/turnRecorder.js +22 -9
- package/dist/workflow/core/ensembleExecutor.js +2 -0
- package/dist/workflow/core/judgeScorer.js +1 -0
- package/dist/workflow/core/responseConditioner.js +1 -0
- package/dist/workflow/core/workflowRunner.js +6 -1
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.js +4 -0
- package/docs-site/static/search-index.json +56 -48
- package/package.json +21 -2
|
@@ -23,7 +23,7 @@ import { NeuroLink } from "../../neurolink.js";
|
|
|
23
23
|
import { readDecisionChoice } from "../../utils/decisionAnswers.js";
|
|
24
24
|
import { calculateCost, hasPricing } from "../../utils/pricing.js";
|
|
25
25
|
import { logger } from "../../utils/logger.js";
|
|
26
|
-
const VALID_QUESTION_TYPES = new Set(["boolean", "choice", "score"]);
|
|
26
|
+
const VALID_QUESTION_TYPES = new Set(["boolean", "choice", "score", "value"]);
|
|
27
27
|
function isRecord(value) {
|
|
28
28
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
29
29
|
}
|
|
@@ -123,6 +123,10 @@ function formatAnswerLine(id, answers) {
|
|
|
123
123
|
}
|
|
124
124
|
case "score":
|
|
125
125
|
return `${id}: score ${formatNumber(answer.score)}, confidence ${formatNumber(answer.confidence)}`;
|
|
126
|
+
case "value":
|
|
127
|
+
return answer.value === null
|
|
128
|
+
? `${id}: no value found, confidence ${formatNumber(answer.confidence)}`
|
|
129
|
+
: `${id}: value ${JSON.stringify(answer.value)}, confidence ${formatNumber(answer.confidence)}`;
|
|
126
130
|
default:
|
|
127
131
|
return `${id}: (unrecognised answer type)`;
|
|
128
132
|
}
|
|
@@ -195,12 +199,17 @@ export const decideCommand = {
|
|
|
195
199
|
type: "string",
|
|
196
200
|
array: true,
|
|
197
201
|
nargs: 1,
|
|
198
|
-
describe: "Image for the model to read: a file path or a data: URL. Repeat for several (
|
|
202
|
+
describe: "Image for the model to read: a file path or a data: URL. Repeat for several (Perplexity and OpenAI Decisions take up to 8, Cloudflare Clef up to 4, XOR 1)",
|
|
199
203
|
})
|
|
200
204
|
.option("video", {
|
|
201
205
|
type: "string",
|
|
202
206
|
nargs: 1,
|
|
203
|
-
describe: "One video for the model to read: a file path or a data: URL",
|
|
207
|
+
describe: "One video for the model to read: a file path or a data: URL. No current decision provider reads video, so it is refused before any request",
|
|
208
|
+
})
|
|
209
|
+
.option("audio", {
|
|
210
|
+
type: "string",
|
|
211
|
+
nargs: 1,
|
|
212
|
+
describe: "One audio clip for the model to hear: a WAV, FLAC, Ogg or MP3 file path or a data: URL (XOR with its xor-omni model; the first 30 seconds are heard). State may then be omitted",
|
|
204
213
|
})
|
|
205
214
|
.option("timeout", {
|
|
206
215
|
type: "number",
|
|
@@ -221,7 +230,8 @@ export const decideCommand = {
|
|
|
221
230
|
})
|
|
222
231
|
.example('$0 decide "Refund request for a damaged item" --questions \'{"urgent":{"type":"boolean","instructions":"Is this urgent?"}}\'', "Ask a single yes/no question")
|
|
223
232
|
.example("$0 decide --state-file ticket.json --questions-file questions.json --format json", "Read state and questions from files, emit raw JSON")
|
|
224
|
-
.example('$0 decide "What color is this?" --provider xor --model xor-omni --image ./photo.png --questions \'{"color":{"type":"choice","instructions":"What color is the image?","criteria":{"red":"red","blue":"blue"}}}\'', "Ask about an image (XOR with its xor-omni model, Perplexity, Cloudflare Clef and OpenAI Decisions read images)")
|
|
233
|
+
.example('$0 decide "What color is this?" --provider xor --model xor-omni --image ./photo.png --questions \'{"color":{"type":"choice","instructions":"What color is the image?","criteria":{"red":"red","blue":"blue"}}}\'', "Ask about an image (XOR with its xor-omni model, Perplexity, Cloudflare Clef and OpenAI Decisions read images)")
|
|
234
|
+
.example('$0 decide "Invoice INV-2024-0892 for 18,275 rupees" --provider xor --model xor-omni --questions \'{"amount":{"type":"value","dtype":"int","instructions":"Invoice amount?"}}\'', "Extract a typed value (XOR)"),
|
|
225
235
|
handler: async (argv) => {
|
|
226
236
|
const outputFormat = argv.format ?? "text";
|
|
227
237
|
// --- Validate before any provider work ---------------------------------
|
|
@@ -256,8 +266,13 @@ export const decideCommand = {
|
|
|
256
266
|
logger.error(chalk.red("Error: pass at most one --video."));
|
|
257
267
|
process.exit(1);
|
|
258
268
|
}
|
|
269
|
+
const audios = [].concat(argv.audio ?? []);
|
|
270
|
+
if (audios.length > 1) {
|
|
271
|
+
logger.error(chalk.red("Error: pass at most one --audio."));
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
259
274
|
if (!isDecisionQuestionMap(parsedQuestions)) {
|
|
260
|
-
logger.error(chalk.red('Error: questions must be a non-empty object of { type: "boolean" | "choice" | "score", ... }.'));
|
|
275
|
+
logger.error(chalk.red('Error: questions must be a non-empty object of { type: "boolean" | "choice" | "score" | "value", ... }.'));
|
|
261
276
|
process.exit(1);
|
|
262
277
|
}
|
|
263
278
|
let state;
|
|
@@ -268,6 +283,10 @@ export const decideCommand = {
|
|
|
268
283
|
logger.error(chalk.red(`Error: could not read state file — ${error instanceof Error ? error.message : String(error)}`));
|
|
269
284
|
process.exit(1);
|
|
270
285
|
}
|
|
286
|
+
// An audio clip can be the whole input.
|
|
287
|
+
if (state === undefined && audios.length === 1) {
|
|
288
|
+
state = "";
|
|
289
|
+
}
|
|
271
290
|
if (state === undefined) {
|
|
272
291
|
logger.error(chalk.red("Error: provide state as a positional argument or via --state-file."));
|
|
273
292
|
process.exit(1);
|
|
@@ -284,6 +303,7 @@ export const decideCommand = {
|
|
|
284
303
|
timeoutMs: argv.timeout,
|
|
285
304
|
...(argv.image && argv.image.length > 0 ? { images: argv.image } : {}),
|
|
286
305
|
...(videos.length === 1 ? { video: videos[0] } : {}),
|
|
306
|
+
...(audios.length === 1 ? { audio: audios[0] } : {}),
|
|
287
307
|
});
|
|
288
308
|
spinner?.succeed("Decision complete");
|
|
289
309
|
if (outputFormat === "json") {
|
|
@@ -11,7 +11,8 @@ import chalk from "chalk";
|
|
|
11
11
|
import ora from "ora";
|
|
12
12
|
import { logger } from "../../utils/logger.js";
|
|
13
13
|
import { NeuroLink } from "../../neurolink.js";
|
|
14
|
-
import {
|
|
14
|
+
import { ensureTelemetry } from "../../services/server/ai/observability/instrumentation.js";
|
|
15
|
+
import { formatRow, formatCost, formatExporterLines, formatOtelStatus, } from "../utils/formatters.js";
|
|
15
16
|
import { redactUrlCredentials } from "../../utils/logSanitize.js";
|
|
16
17
|
/**
|
|
17
18
|
* Observability Command Factory
|
|
@@ -66,6 +67,9 @@ export class ObservabilityCommandFactory {
|
|
|
66
67
|
? null
|
|
67
68
|
: ora("Checking observability status...").start();
|
|
68
69
|
try {
|
|
70
|
+
// A one-shot process only starts telemetry with its first span, so
|
|
71
|
+
// start it here to report the exporters this process would run.
|
|
72
|
+
ensureTelemetry();
|
|
69
73
|
const neurolink = new NeuroLink();
|
|
70
74
|
const status = neurolink.getTelemetryStatus();
|
|
71
75
|
if (spinner) {
|
|
@@ -105,9 +109,7 @@ export class ObservabilityCommandFactory {
|
|
|
105
109
|
if (status.openTelemetry) {
|
|
106
110
|
logger.always("");
|
|
107
111
|
logger.always(chalk.bold("OpenTelemetry:"));
|
|
108
|
-
const otelStatus = status.openTelemetry
|
|
109
|
-
? chalk.green("Enabled")
|
|
110
|
-
: chalk.gray("Disabled");
|
|
112
|
+
const otelStatus = formatOtelStatus(status.openTelemetry, "Enabled", "Disabled");
|
|
111
113
|
logger.always(formatRow(" Status:", otelStatus));
|
|
112
114
|
if (status.openTelemetry.endpoint) {
|
|
113
115
|
logger.always(formatRow(" Endpoint:", redactUrlCredentials(status.openTelemetry.endpoint)));
|
|
@@ -117,6 +119,11 @@ export class ObservabilityCommandFactory {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
logger.always("");
|
|
122
|
+
logger.always(chalk.bold("Exporters:"));
|
|
123
|
+
for (const line of formatExporterLines(status.exporters)) {
|
|
124
|
+
logger.always(line);
|
|
125
|
+
}
|
|
126
|
+
logger.always("");
|
|
120
127
|
}
|
|
121
128
|
}
|
|
122
129
|
catch (error) {
|
|
@@ -11,10 +11,20 @@ import chalk from "chalk";
|
|
|
11
11
|
import ora from "ora";
|
|
12
12
|
import { logger } from "../../utils/logger.js";
|
|
13
13
|
import { NeuroLink } from "../../neurolink.js";
|
|
14
|
-
import { flushOpenTelemetry } from "../../services/server/ai/observability/instrumentation.js";
|
|
15
|
-
import {
|
|
14
|
+
import { ensureTelemetry, flushOpenTelemetry, } from "../../services/server/ai/observability/instrumentation.js";
|
|
15
|
+
import { getExporterRegistry } from "../../observability/exporterRegistry.js";
|
|
16
|
+
import { formatRow, formatCost, formatExporterLines, formatOtelStatus, } from "../utils/formatters.js";
|
|
16
17
|
import { redactUrlCredentials } from "../../utils/logSanitize.js";
|
|
17
18
|
import { prepareNativeTelemetry, validateNativeTelemetry, } from "../utils/nativeTelemetry.js";
|
|
19
|
+
function exporterTotals() {
|
|
20
|
+
return getExporterRegistry()
|
|
21
|
+
.getStatuses()
|
|
22
|
+
.reduce((sum, exporter) => ({
|
|
23
|
+
pending: sum.pending + exporter.pendingSpans,
|
|
24
|
+
delivered: sum.delivered + exporter.deliveredSpans,
|
|
25
|
+
failed: sum.failed + exporter.failedSpans,
|
|
26
|
+
}), { pending: 0, delivered: 0, failed: 0 });
|
|
27
|
+
}
|
|
18
28
|
/**
|
|
19
29
|
* Telemetry Command Factory
|
|
20
30
|
*/
|
|
@@ -180,6 +190,9 @@ export class TelemetryCommandFactory {
|
|
|
180
190
|
? null
|
|
181
191
|
: ora("Checking telemetry status...").start();
|
|
182
192
|
try {
|
|
193
|
+
// A one-shot process only starts telemetry with its first span, so
|
|
194
|
+
// start it here to report the exporters this process would run.
|
|
195
|
+
ensureTelemetry();
|
|
183
196
|
const neurolink = new NeuroLink();
|
|
184
197
|
const status = neurolink.getTelemetryStatus();
|
|
185
198
|
if (spinner) {
|
|
@@ -204,9 +217,7 @@ export class TelemetryCommandFactory {
|
|
|
204
217
|
if (status.openTelemetry) {
|
|
205
218
|
logger.always("");
|
|
206
219
|
logger.always(chalk.bold("OpenTelemetry:"));
|
|
207
|
-
const otelStatus = status.openTelemetry
|
|
208
|
-
? chalk.green("Active")
|
|
209
|
-
: chalk.gray("Inactive");
|
|
220
|
+
const otelStatus = formatOtelStatus(status.openTelemetry, "Active", "Inactive");
|
|
210
221
|
logger.always(formatRow(" Status:", otelStatus));
|
|
211
222
|
if (status.openTelemetry.endpoint) {
|
|
212
223
|
logger.always(formatRow(" Endpoint:", redactUrlCredentials(status.openTelemetry.endpoint)));
|
|
@@ -231,6 +242,11 @@ export class TelemetryCommandFactory {
|
|
|
231
242
|
}
|
|
232
243
|
}
|
|
233
244
|
logger.always("");
|
|
245
|
+
logger.always(chalk.bold("Exporters:"));
|
|
246
|
+
for (const line of formatExporterLines(status.exporters)) {
|
|
247
|
+
logger.always(line);
|
|
248
|
+
}
|
|
249
|
+
logger.always("");
|
|
234
250
|
}
|
|
235
251
|
}
|
|
236
252
|
catch (error) {
|
|
@@ -277,6 +293,7 @@ export class TelemetryCommandFactory {
|
|
|
277
293
|
? null
|
|
278
294
|
: ora("Flushing pending spans...").start();
|
|
279
295
|
try {
|
|
296
|
+
const before = exporterTotals();
|
|
280
297
|
// Create a timeout promise
|
|
281
298
|
let flushTimer;
|
|
282
299
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -293,13 +310,26 @@ export class TelemetryCommandFactory {
|
|
|
293
310
|
if (spinner) {
|
|
294
311
|
spinner.succeed("Flush completed");
|
|
295
312
|
}
|
|
313
|
+
const after = exporterTotals();
|
|
314
|
+
const flushed = after.delivered - before.delivered;
|
|
315
|
+
const dropped = after.failed - before.failed;
|
|
296
316
|
if (args.format === "json") {
|
|
297
|
-
logger.always(JSON.stringify({
|
|
317
|
+
logger.always(JSON.stringify({
|
|
318
|
+
success: true,
|
|
319
|
+
pendingBefore: before.pending,
|
|
320
|
+
pendingAfter: after.pending,
|
|
321
|
+
flushed,
|
|
322
|
+
dropped,
|
|
323
|
+
}, null, 2));
|
|
298
324
|
}
|
|
299
325
|
else {
|
|
300
326
|
logger.always("");
|
|
301
327
|
logger.always(chalk.bold.cyan("=== Flush Complete ==="));
|
|
302
328
|
logger.always("");
|
|
329
|
+
logger.always(formatRow("Spans before:", before.pending.toString()));
|
|
330
|
+
logger.always(formatRow("Spans after:", after.pending.toString()));
|
|
331
|
+
logger.always(formatRow("Flushed:", chalk.green(flushed.toString())));
|
|
332
|
+
logger.always(formatRow("Dropped:", dropped > 0 ? chalk.red(dropped.toString()) : "0"));
|
|
303
333
|
logger.always("");
|
|
304
334
|
}
|
|
305
335
|
}
|
|
@@ -3,10 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Common formatting functions used across CLI command modules.
|
|
5
5
|
*/
|
|
6
|
+
import type { ExporterStatus } from "../../types/index.js";
|
|
6
7
|
/**
|
|
7
8
|
* Format a table row with padding
|
|
8
9
|
*/
|
|
9
10
|
export declare function formatRow(label: string, value: string, width?: number): string;
|
|
11
|
+
/**
|
|
12
|
+
* Format the status rows of the registered exporters
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatExporterLines(exporters: ExporterStatus[]): string[];
|
|
15
|
+
/**
|
|
16
|
+
* @description Labels NeuroLink's OpenTelemetry export for the status commands. Beside a host TracerProvider NeuroLink exports nothing to the endpoint, so it is shown as ignored rather than active.
|
|
17
|
+
* @param otel {{ enabled: boolean; endpoint?: string; usingExternalProvider?: boolean }} - `getTelemetryStatus().openTelemetry`.
|
|
18
|
+
* @param on {string} - Label for an export NeuroLink runs.
|
|
19
|
+
* @param off {string} - Label for no export.
|
|
20
|
+
* @returns {string} The coloured label.
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatOtelStatus(otel: {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
endpoint?: string;
|
|
25
|
+
usingExternalProvider?: boolean;
|
|
26
|
+
}, on: string, off: string): string;
|
|
10
27
|
/**
|
|
11
28
|
* Format currency value
|
|
12
29
|
*/
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Common formatting functions used across CLI command modules.
|
|
5
5
|
*/
|
|
6
|
+
import chalk from "chalk";
|
|
6
7
|
/**
|
|
7
8
|
* Format a table row with padding
|
|
8
9
|
*/
|
|
@@ -10,6 +11,44 @@ export function formatRow(label, value, width = 30) {
|
|
|
10
11
|
const paddedLabel = label.padEnd(width);
|
|
11
12
|
return `${paddedLabel} ${value}`;
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Format the status rows of the registered exporters
|
|
16
|
+
*/
|
|
17
|
+
export function formatExporterLines(exporters) {
|
|
18
|
+
if (exporters.length === 0) {
|
|
19
|
+
return [" None registered"];
|
|
20
|
+
}
|
|
21
|
+
return exporters.flatMap((exporter) => {
|
|
22
|
+
const state = !exporter.enabled
|
|
23
|
+
? "Stopped"
|
|
24
|
+
: exporter.healthy
|
|
25
|
+
? "Active"
|
|
26
|
+
: "Failing";
|
|
27
|
+
const counts = `pending ${exporter.pendingSpans}, delivered ${exporter.deliveredSpans}, failed ${exporter.failedSpans}`;
|
|
28
|
+
return [
|
|
29
|
+
formatRow(` ${exporter.name}:`, `${state} (${counts})`),
|
|
30
|
+
...(exporter.lastExportTime
|
|
31
|
+
? [formatRow(" Last export:", exporter.lastExportTime)]
|
|
32
|
+
: []),
|
|
33
|
+
...(exporter.errors ?? []).map((error) => formatRow(" Error:", error)),
|
|
34
|
+
];
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @description Labels NeuroLink's OpenTelemetry export for the status commands. Beside a host TracerProvider NeuroLink exports nothing to the endpoint, so it is shown as ignored rather than active.
|
|
39
|
+
* @param otel {{ enabled: boolean; endpoint?: string; usingExternalProvider?: boolean }} - `getTelemetryStatus().openTelemetry`.
|
|
40
|
+
* @param on {string} - Label for an export NeuroLink runs.
|
|
41
|
+
* @param off {string} - Label for no export.
|
|
42
|
+
* @returns {string} The coloured label.
|
|
43
|
+
*/
|
|
44
|
+
export function formatOtelStatus(otel, on, off) {
|
|
45
|
+
if (otel.usingExternalProvider) {
|
|
46
|
+
return chalk.yellow(otel.endpoint
|
|
47
|
+
? "Ignored (a host TracerProvider is registered)"
|
|
48
|
+
: "Host TracerProvider");
|
|
49
|
+
}
|
|
50
|
+
return otel.enabled ? chalk.green(on) : chalk.gray(off);
|
|
51
|
+
}
|
|
13
52
|
/**
|
|
14
53
|
* Format currency value
|
|
15
54
|
*/
|
|
@@ -11,15 +11,31 @@ export declare const DEFAULT_FLUSH_AT = 15;
|
|
|
11
11
|
export declare const DEFAULT_FLUSH_INTERVAL_MS = 5000;
|
|
12
12
|
/** @description Milliseconds before an export request is aborted. */
|
|
13
13
|
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
14
|
+
/** @description Milliseconds a flush or shutdown waits for delivery before it abandons what is still in flight. */
|
|
15
|
+
export declare const DEFAULT_FLUSH_BUDGET_MS = 3000;
|
|
14
16
|
/** @description Maximum spans sent in one export request. */
|
|
15
17
|
export declare const MAX_SPANS_PER_REQUEST = 500;
|
|
18
|
+
/** @description Export requests to Langfuse in flight at once. Spans that end while every one is busy wait in the buffer. */
|
|
19
|
+
export declare const MAX_CONCURRENT_DELIVERIES = 4;
|
|
20
|
+
/** @description Spans that may wait for a delivery slot. Beyond it the oldest waiting spans are dropped and counted, so a Langfuse that stops answering cannot hold an unbounded backlog in memory. */
|
|
21
|
+
export declare const MAX_QUEUED_SPANS = 10000;
|
|
22
|
+
/** @description Milliseconds between warn-level logs about waiting spans dropped for lack of a delivery slot. */
|
|
23
|
+
export declare const QUEUE_DROP_WARN_INTERVAL_MS = 60000;
|
|
24
|
+
/** @description Longest `Retry-After` a 429 or 503 from Langfuse is waited out before the retry. */
|
|
25
|
+
export declare const MAX_EXPORT_RETRY_AFTER_MS = 60000;
|
|
16
26
|
/** @description Maximum serialized bytes sent in one export request. */
|
|
17
27
|
export declare const MAX_BYTES_PER_REQUEST = 3500000;
|
|
18
28
|
/** @description Placeholder that replaces a value fully removed by the user's mask. */
|
|
19
29
|
export declare const FULLY_MASKED = "<fully masked>";
|
|
20
|
-
/** @description Span attributes holding trace and observation input or output, which the mask
|
|
30
|
+
/** @description Span attributes holding trace and observation input or output, which the Langfuse exporter's mask and `redactIO` apply to. */
|
|
21
31
|
export declare const CONTENT_KEYS: Set<string>;
|
|
22
32
|
/** @description Attribute prefixes whose values are metadata entries. */
|
|
23
33
|
export declare const METADATA_PREFIXES: string[];
|
|
34
|
+
/** @description Observation types that hold no model, usage or cost in Langfuse. GenAI model and usage keys on them are left out of the Langfuse export, so a request's generation stays its only priced record. */
|
|
35
|
+
export declare const UNPRICED_OBSERVATION_TYPES: ReadonlySet<string>;
|
|
36
|
+
/** @description GenAI attributes Langfuse reads a model name from. */
|
|
37
|
+
export declare const MODEL_ATTRIBUTE_KEYS: ReadonlySet<string>;
|
|
38
|
+
/** @description Prefix of the GenAI attributes Langfuse reads usage and cost from. */
|
|
39
|
+
export declare const USAGE_ATTRIBUTE_PREFIX = "gen_ai.usage.";
|
|
24
40
|
/** @description OTLP numeric status code for each span status. */
|
|
25
41
|
export declare const OTLP_STATUS_CODES: Record<SpanStatus, number>;
|
|
@@ -11,13 +11,23 @@ export const DEFAULT_FLUSH_AT = 15;
|
|
|
11
11
|
export const DEFAULT_FLUSH_INTERVAL_MS = 5_000;
|
|
12
12
|
/** @description Milliseconds before an export request is aborted. */
|
|
13
13
|
export const DEFAULT_TIMEOUT_MS = 30_000;
|
|
14
|
+
/** @description Milliseconds a flush or shutdown waits for delivery before it abandons what is still in flight. */
|
|
15
|
+
export const DEFAULT_FLUSH_BUDGET_MS = 3_000;
|
|
14
16
|
/** @description Maximum spans sent in one export request. */
|
|
15
17
|
export const MAX_SPANS_PER_REQUEST = 500;
|
|
18
|
+
/** @description Export requests to Langfuse in flight at once. Spans that end while every one is busy wait in the buffer. */
|
|
19
|
+
export const MAX_CONCURRENT_DELIVERIES = 4;
|
|
20
|
+
/** @description Spans that may wait for a delivery slot. Beyond it the oldest waiting spans are dropped and counted, so a Langfuse that stops answering cannot hold an unbounded backlog in memory. */
|
|
21
|
+
export const MAX_QUEUED_SPANS = 10_000;
|
|
22
|
+
/** @description Milliseconds between warn-level logs about waiting spans dropped for lack of a delivery slot. */
|
|
23
|
+
export const QUEUE_DROP_WARN_INTERVAL_MS = 60_000;
|
|
24
|
+
/** @description Longest `Retry-After` a 429 or 503 from Langfuse is waited out before the retry. */
|
|
25
|
+
export const MAX_EXPORT_RETRY_AFTER_MS = 60_000;
|
|
16
26
|
/** @description Maximum serialized bytes sent in one export request. */
|
|
17
27
|
export const MAX_BYTES_PER_REQUEST = 3_500_000;
|
|
18
28
|
/** @description Placeholder that replaces a value fully removed by the user's mask. */
|
|
19
29
|
export const FULLY_MASKED = "<fully masked>";
|
|
20
|
-
/** @description Span attributes holding trace and observation input or output, which the mask
|
|
30
|
+
/** @description Span attributes holding trace and observation input or output, which the Langfuse exporter's mask and `redactIO` apply to. */
|
|
21
31
|
export const CONTENT_KEYS = new Set([
|
|
22
32
|
"langfuse.observation.input",
|
|
23
33
|
"langfuse.observation.output",
|
|
@@ -29,6 +39,18 @@ export const METADATA_PREFIXES = [
|
|
|
29
39
|
"langfuse.observation.metadata.",
|
|
30
40
|
"langfuse.trace.metadata.",
|
|
31
41
|
];
|
|
42
|
+
/** @description Observation types that hold no model, usage or cost in Langfuse. GenAI model and usage keys on them are left out of the Langfuse export, so a request's generation stays its only priced record. */
|
|
43
|
+
export const UNPRICED_OBSERVATION_TYPES = new Set([
|
|
44
|
+
"span",
|
|
45
|
+
"event",
|
|
46
|
+
]);
|
|
47
|
+
/** @description GenAI attributes Langfuse reads a model name from. */
|
|
48
|
+
export const MODEL_ATTRIBUTE_KEYS = new Set([
|
|
49
|
+
"gen_ai.request.model",
|
|
50
|
+
"gen_ai.response.model",
|
|
51
|
+
]);
|
|
52
|
+
/** @description Prefix of the GenAI attributes Langfuse reads usage and cost from. */
|
|
53
|
+
export const USAGE_ATTRIBUTE_PREFIX = "gen_ai.usage.";
|
|
32
54
|
/** @description OTLP numeric status code for each span status. */
|
|
33
55
|
export const OTLP_STATUS_CODES = {
|
|
34
56
|
[SpanStatus.UNSET]: 0,
|
|
@@ -18,3 +18,9 @@ export declare const TRACE_METADATA_CONTEXT_KEY = "neurolink.trace.metadata";
|
|
|
18
18
|
export declare const OTEL_LOG_PREFIX = "[OpenTelemetry]";
|
|
19
19
|
/** @description Most open and most ended spans the exporter span processor remembers for re-parenting; the oldest are forgotten first. */
|
|
20
20
|
export declare const MAX_REMEMBERED_SPANS = 5000;
|
|
21
|
+
/** @description Most redacted span attribute strings remembered so `observe` does not redact them a second time. */
|
|
22
|
+
export declare const MAX_REDACTED_ATTRIBUTES = 64;
|
|
23
|
+
/** @description Span attribute that keeps a wrapper span out of every exporter. */
|
|
24
|
+
export declare const INTERNAL_SPAN_ATTRIBUTE = "langfuse.internal";
|
|
25
|
+
/** @description Instrumentation scope of the proxy's tracer. Of the proxy's spans only the ones it marks as observations (the request root and its generation) reach the exporters, although its spans also carry `gen_ai.*` keys for collectors. */
|
|
26
|
+
export declare const PROXY_TRACER_SCOPE = "neurolink.proxy";
|
|
@@ -32,3 +32,9 @@ export const TRACE_METADATA_CONTEXT_KEY = "neurolink.trace.metadata";
|
|
|
32
32
|
export const OTEL_LOG_PREFIX = "[OpenTelemetry]";
|
|
33
33
|
/** @description Most open and most ended spans the exporter span processor remembers for re-parenting; the oldest are forgotten first. */
|
|
34
34
|
export const MAX_REMEMBERED_SPANS = 5_000;
|
|
35
|
+
/** @description Most redacted span attribute strings remembered so `observe` does not redact them a second time. */
|
|
36
|
+
export const MAX_REDACTED_ATTRIBUTES = 64;
|
|
37
|
+
/** @description Span attribute that keeps a wrapper span out of every exporter. */
|
|
38
|
+
export const INTERNAL_SPAN_ATTRIBUTE = "langfuse.internal";
|
|
39
|
+
/** @description Instrumentation scope of the proxy's tracer. Of the proxy's spans only the ones it marks as observations (the request root and its generation) reach the exporters, although its spans also carry `gen_ai.*` keys for collectors. */
|
|
40
|
+
export const PROXY_TRACER_SCOPE = "neurolink.proxy";
|
|
@@ -1760,6 +1760,7 @@ export class BaseProvider {
|
|
|
1760
1760
|
error,
|
|
1761
1761
|
latency,
|
|
1762
1762
|
};
|
|
1763
|
+
this.telemetryHandler.recordTTSFailure(ttsProvider, error, latency);
|
|
1763
1764
|
logger.error(`TTS synthesis failed in Mode 1 (direct input synthesis):`, ttsError);
|
|
1764
1765
|
}
|
|
1765
1766
|
return this.enhanceResult(baseResult, options, startTime);
|
|
@@ -2117,6 +2118,7 @@ export class BaseProvider {
|
|
|
2117
2118
|
catch (ttsError) {
|
|
2118
2119
|
const latency = Date.now() - ttsStartTime;
|
|
2119
2120
|
const error = this.getTTSErrorDetails(ttsError);
|
|
2121
|
+
this.telemetryHandler.recordTTSFailure(ttsProvider, error, latency);
|
|
2120
2122
|
logger.error(`TTS synthesis failed in Mode 2 (AI response synthesis):`, ttsError);
|
|
2121
2123
|
return {
|
|
2122
2124
|
...enhancedResult,
|
|
@@ -242,6 +242,25 @@ export function createGeminiLoopAdapter(config) {
|
|
|
242
242
|
});
|
|
243
243
|
return next;
|
|
244
244
|
},
|
|
245
|
+
// Gemini's prompt count already contains the cached tokens, and its
|
|
246
|
+
// candidate count leaves out the thinking tokens. The step's usage keeps
|
|
247
|
+
// that raw shape because the provider clients reconcile the turn totals
|
|
248
|
+
// from it once, and callers get those counts as the API reported them;
|
|
249
|
+
// only the generation observation is rebased, so a cached token is not
|
|
250
|
+
// billed at the input rate as well as the cache rate, a cached count above
|
|
251
|
+
// the prompt is not billed as extra tokens, and a thinking token is billed
|
|
252
|
+
// at the output rate.
|
|
253
|
+
observedUsage(usage) {
|
|
254
|
+
const cached = usage.cacheReadTokens === undefined
|
|
255
|
+
? undefined
|
|
256
|
+
: Math.min(usage.cacheReadTokens, usage.inputTokens);
|
|
257
|
+
return {
|
|
258
|
+
...usage,
|
|
259
|
+
inputTokens: Math.max(0, usage.inputTokens - (cached ?? 0)),
|
|
260
|
+
outputTokens: usage.outputTokens + (usage.reasoningTokens ?? 0),
|
|
261
|
+
...(cached !== undefined && { cacheReadTokens: cached }),
|
|
262
|
+
};
|
|
263
|
+
},
|
|
245
264
|
mapFinishReason(rawStopReason, hadToolCallsAtCap) {
|
|
246
265
|
const mapped = mapGeminiFinishReason(rawStopReason);
|
|
247
266
|
// "tool-calls" from this hook means the step cap cut the turn off with
|
package/dist/core/loopEngine.js
CHANGED
|
@@ -306,6 +306,7 @@ async function executeObservedStep(adapter, request, channel, signal, span) {
|
|
|
306
306
|
catch (err) {
|
|
307
307
|
throw err instanceof PostEmissionStepError ? err.cause : err;
|
|
308
308
|
}
|
|
309
|
+
const observed = adapter.observedUsage?.(result.usage) ?? result.usage;
|
|
309
310
|
observeGeneration(generationSpan, {
|
|
310
311
|
provider: request.generation?.provider,
|
|
311
312
|
model: request.generation?.model,
|
|
@@ -316,13 +317,15 @@ async function executeObservedStep(adapter, request, channel, signal, span) {
|
|
|
316
317
|
...(result.toolCalls.length > 0 ? { toolCalls: result.toolCalls } : {}),
|
|
317
318
|
},
|
|
318
319
|
usage: {
|
|
319
|
-
inputTokens:
|
|
320
|
-
outputTokens:
|
|
321
|
-
cacheReadTokens:
|
|
322
|
-
cacheCreationTokens:
|
|
323
|
-
reasoningTokens:
|
|
320
|
+
inputTokens: observed.inputTokens,
|
|
321
|
+
outputTokens: observed.outputTokens,
|
|
322
|
+
cacheReadTokens: observed.cacheReadTokens,
|
|
323
|
+
cacheCreationTokens: observed.cacheWriteTokens,
|
|
324
|
+
reasoningTokens: observed.reasoningTokens,
|
|
324
325
|
},
|
|
325
|
-
|
|
326
|
+
// A step cut short before the provider's terminal event has no stop
|
|
327
|
+
// reason; record "other", as the turn's own finishReason does.
|
|
328
|
+
finishReason: result.rawStopReason ?? (signal.aborted ? "other" : undefined),
|
|
326
329
|
aborted: signal.aborted,
|
|
327
330
|
completionStartTime: firstChunkAt,
|
|
328
331
|
});
|
|
@@ -370,7 +373,7 @@ export function runAgenticLoop(adapter, initialConversation, options) {
|
|
|
370
373
|
// ever writes to it, so the loop is the same loop it was.
|
|
371
374
|
let stepCap = adapter.maxSteps;
|
|
372
375
|
const turnStartedAt = Date.now();
|
|
373
|
-
const stepSpans = new StepSpans();
|
|
376
|
+
const stepSpans = new StepSpans(options.operation);
|
|
374
377
|
try {
|
|
375
378
|
for (let step = 0; step < stepCap; step++) {
|
|
376
379
|
if (internalAbort.signal.aborted) {
|
|
@@ -129,10 +129,11 @@ export class StreamHandler {
|
|
|
129
129
|
// captured upstream error (if any) so providerError /
|
|
130
130
|
// modelResponseRaw carry the real cause.
|
|
131
131
|
const sentinel = await buildNoOutputSentinel(error, result, getUnderlyingError?.());
|
|
132
|
-
// Curator P2-5 + P3-6: stamp the active OTel span
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
// stampNoOutputSpan so every wired
|
|
132
|
+
// Curator P2-5 + P3-6: stamp the active OTel span with the
|
|
133
|
+
// WARNING observation level and a status message carrying
|
|
134
|
+
// finishReason + token usage, which ExporterSpanProcessor exports
|
|
135
|
+
// with the span. Centralized in stampNoOutputSpan so every wired
|
|
136
|
+
// site stamps consistently.
|
|
136
137
|
stampNoOutputSpan(sentinel);
|
|
137
138
|
// S4 fix: yield a sentinel chunk so Pipeline B can detect the empty stream
|
|
138
139
|
// and set the span to WARNING status instead of OK
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* @module core/modules/TelemetryHandler
|
|
14
14
|
*/
|
|
15
15
|
import type { NeuroLink } from "../../neurolink.js";
|
|
16
|
-
import type { StreamOptions, AIProviderName, AnalyticsData, EnhancedGenerateResult, EvaluationData, MemoryToolCallRecord, MemoryToolResultRecord, RawUsageObject, TextGenerationOptions, TokenUsage } from "../../types/index.js";
|
|
16
|
+
import type { StreamOptions, AIProviderName, AnalyticsData, EnhancedGenerateResult, EvaluationData, MemoryToolCallRecord, MemoryToolResultRecord, RawUsageObject, TextGenerationOptions, TokenUsage, TTSMetadata } from "../../types/index.js";
|
|
17
17
|
/**
|
|
18
18
|
* TelemetryHandler class - Handles analytics and telemetry for AI providers
|
|
19
19
|
*/
|
|
@@ -34,6 +34,10 @@ export declare class TelemetryHandler {
|
|
|
34
34
|
* Record performance metrics for a generation
|
|
35
35
|
*/
|
|
36
36
|
recordPerformanceMetrics(usage: RawUsageObject | undefined, responseTime: number): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Record a TTS synthesis failure without affecting the generation result.
|
|
39
|
+
*/
|
|
40
|
+
recordTTSFailure(ttsProvider: string, error: NonNullable<TTSMetadata["error"]>, latency: number): void;
|
|
37
41
|
/**
|
|
38
42
|
* Estimate cost only from known per-model rates. Unknown pricing remains
|
|
39
43
|
* absent from cost metrics instead of using another model's default rate.
|
|
@@ -16,6 +16,7 @@ import { nanoid } from "nanoid";
|
|
|
16
16
|
import { extractTokenUsage } from "../../utils/tokenUtils.js";
|
|
17
17
|
import { logger } from "../../utils/logger.js";
|
|
18
18
|
import { recordProviderPerformanceFromMetrics } from "../evaluationProviders.js";
|
|
19
|
+
import { recordAIRequest, recordCustomHistogram, recordCustomMetric, } from "../../telemetry/aiMetrics.js";
|
|
19
20
|
import { calculateCost, hasPricing } from "../../utils/pricing.js";
|
|
20
21
|
/**
|
|
21
22
|
* TelemetryHandler class - Handles analytics and telemetry for AI providers
|
|
@@ -84,6 +85,7 @@ export class TelemetryHandler {
|
|
|
84
85
|
cost: actualCost,
|
|
85
86
|
success: true,
|
|
86
87
|
});
|
|
88
|
+
recordAIRequest(this.providerName, this.modelName, totalTokens, responseTime, actualCost !== undefined && actualCost > 0 ? actualCost : undefined);
|
|
87
89
|
logger.debug(`Performance recorded for ${this.providerName}`, {
|
|
88
90
|
responseTime: `${responseTime}ms`,
|
|
89
91
|
tokens: totalTokens,
|
|
@@ -94,6 +96,20 @@ export class TelemetryHandler {
|
|
|
94
96
|
logger.warn("⚠️ Performance recording failed:", perfError);
|
|
95
97
|
}
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Record a TTS synthesis failure without affecting the generation result.
|
|
101
|
+
*/
|
|
102
|
+
recordTTSFailure(ttsProvider, error, latency) {
|
|
103
|
+
const labels = {
|
|
104
|
+
provider: ttsProvider,
|
|
105
|
+
error_code: error.code,
|
|
106
|
+
...(error.retriable !== undefined
|
|
107
|
+
? { retriable: error.retriable.toString() }
|
|
108
|
+
: {}),
|
|
109
|
+
};
|
|
110
|
+
recordCustomMetric("tts_failures", 1, labels);
|
|
111
|
+
recordCustomHistogram("tts_failure_latency_ms", latency, labels);
|
|
112
|
+
}
|
|
97
113
|
/**
|
|
98
114
|
* Estimate cost only from known per-model rates. Unknown pricing remains
|
|
99
115
|
* absent from cost metrics instead of using another model's default rate.
|
|
@@ -860,6 +860,9 @@ export class ToolsManager {
|
|
|
860
860
|
attributes: {
|
|
861
861
|
"tool.name": toolName,
|
|
862
862
|
"tool.type": "custom",
|
|
863
|
+
// Pure wrapper around the `tool` observation of the same
|
|
864
|
+
// call: it stays an OpenTelemetry span but is not exported.
|
|
865
|
+
[ATTR.NL_INTERNAL]: true,
|
|
863
866
|
},
|
|
864
867
|
});
|
|
865
868
|
const startTime = Date.now();
|
|
@@ -447,7 +447,7 @@ function generateObservedStep(args, request) {
|
|
|
447
447
|
});
|
|
448
448
|
}
|
|
449
449
|
export async function runNativeGenerateLoop(args, toolExecutionSummaries) {
|
|
450
|
-
const stepSpans = new StepSpans();
|
|
450
|
+
const stepSpans = new StepSpans("generate");
|
|
451
451
|
try {
|
|
452
452
|
return await runGenerateSteps(args, toolExecutionSummaries, stepSpans);
|
|
453
453
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "../services/server/ai/observability/instrumentation.js";
|
|
1
2
|
import type { EvaluationData, GenerateResult, AutoEvaluationConfig, EvaluationConfig } from "../types/index.js";
|
|
2
3
|
import type { LanguageModelV3CallOptions } from "../types/index.js";
|
|
3
4
|
export * from "./errors/index.js";
|
package/dist/evaluation/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// Imported on its own, this entry starts tracing at its first span, as the
|
|
2
|
+
// main entry does. The import sits here rather than in the shared tracers so
|
|
3
|
+
// that the client entry stays free of the OpenTelemetry Node SDK.
|
|
4
|
+
import "../services/server/ai/observability/instrumentation.js";
|
|
1
5
|
import { ContextBuilder } from "./contextBuilder.js";
|
|
2
6
|
import { RAGASEvaluator } from "./ragasEvaluator.js";
|
|
3
7
|
import { mapToEvaluationData } from "./scoring.js";
|
|
@@ -45,12 +45,13 @@ export declare const DECISION_PROVIDERS: readonly ProviderDescriptor[];
|
|
|
45
45
|
*/
|
|
46
46
|
export declare function resolveDefaultDecisionProvider(credentials?: NeurolinkCredentials): string | undefined;
|
|
47
47
|
/**
|
|
48
|
-
* Names of the decision providers that accept images, or, with `video
|
|
49
|
-
* ones that accept
|
|
50
|
-
* the same request is worse than none.
|
|
48
|
+
* Names of the decision providers that accept images, or, with `video` or
|
|
49
|
+
* `audio`, the ones that accept that too: a hint that names a provider which
|
|
50
|
+
* would refuse the same request is worse than none.
|
|
51
51
|
*/
|
|
52
52
|
export declare function listMediaDecisionProviders(needs?: {
|
|
53
53
|
video?: boolean;
|
|
54
|
+
audio?: boolean;
|
|
54
55
|
}): string[];
|
|
55
56
|
/**
|
|
56
57
|
* The variables that would configure each decision provider, one clause per
|