@juspay/neurolink 12.59.0 → 13.0.0
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 +13 -2
- package/dist/auth/anthropicOAuth.js +3 -3
- package/dist/auth/middleware/AuthMiddleware.d.ts +1 -1
- package/dist/auth/sessionManager.js +4 -4
- package/dist/auth/tokenStore.js +4 -4
- package/dist/browser/neurolink.min.js +474 -473
- package/dist/cli/commands/observability.d.ts +1 -6
- package/dist/cli/commands/observability.js +0 -106
- package/dist/cli/commands/proxy.js +9 -18
- package/dist/cli/commands/telemetry.d.ts +3 -13
- package/dist/cli/commands/telemetry.js +7 -354
- package/dist/cli/loop/session.js +1 -1
- package/dist/client/httpClient.js +1 -1
- package/dist/client/sseClient.js +1 -1
- package/dist/client/streamingClient.js +2 -2
- package/dist/client/wsClient.js +1 -1
- package/dist/constants/langfuse.d.ts +25 -0
- package/dist/constants/langfuse.js +38 -0
- package/dist/constants/telemetry.d.ts +20 -0
- package/dist/constants/telemetry.js +34 -0
- package/dist/core/baseProvider.d.ts +2 -1
- package/dist/core/baseProvider.js +4 -11
- package/dist/core/conversationMemoryManager.js +5 -8
- package/dist/core/factory.js +1 -1
- package/dist/core/geminiLoopAdapter.d.ts +8 -1
- package/dist/core/geminiLoopAdapter.js +25 -1
- package/dist/core/loopEngine.js +69 -40
- package/dist/core/modules/MessageBuilder.js +2 -2
- package/dist/core/modules/StreamHandler.js +2 -2
- package/dist/core/modules/TelemetryHandler.d.ts +2 -18
- package/dist/core/modules/TelemetryHandler.js +1 -66
- package/dist/core/modules/ToolsManager.js +40 -31
- package/dist/core/nativeGenerateLoop.js +78 -8
- package/dist/core/redisConversationMemoryManager.js +8 -15
- package/dist/core/toolExecutionGuards.js +1 -13
- package/dist/index.d.ts +5 -12
- package/dist/index.js +5 -37
- package/dist/mcp/batching/requestBatcher.js +1 -1
- package/dist/mcp/externalServerManager.js +3 -21
- package/dist/mcp/toolDiscoveryService.js +4 -16
- package/dist/mcp/toolRegistry.js +2 -5
- package/dist/memory/memoryRetrievalTools.js +1 -1
- package/dist/neurolink.d.ts +16 -27
- package/dist/neurolink.js +788 -792
- package/dist/observability/exporterSpanProcessor.d.ts +50 -0
- package/dist/observability/exporterSpanProcessor.js +181 -0
- package/dist/observability/exporters/langfuseExporter.d.ts +13 -34
- package/dist/observability/exporters/langfuseExporter.js +101 -154
- package/dist/observability/index.d.ts +1 -0
- package/dist/observability/index.js +1 -0
- package/dist/observability/langfuseMasking.d.ts +8 -0
- package/dist/observability/langfuseMasking.js +47 -0
- package/dist/observability/otlpEncoding.d.ts +20 -0
- package/dist/observability/otlpEncoding.js +85 -0
- package/dist/providers/amazonBedrock/client.js +142 -176
- package/dist/providers/amazonBedrock/loopAdapter.js +14 -1
- package/dist/providers/amazonSagemaker.js +118 -80
- package/dist/providers/anthropic/client.js +3 -52
- package/dist/providers/anthropic/loopAdapter.js +24 -1
- package/dist/providers/anthropic/rateLimitCapture.js +9 -12
- package/dist/providers/googleAiStudio/client.d.ts +4 -5
- package/dist/providers/googleAiStudio/client.js +38 -40
- package/dist/providers/googleVertex/client.d.ts +2 -7
- package/dist/providers/googleVertex/client.js +282 -378
- package/dist/providers/googleVertex/constants.js +2 -2
- package/dist/providers/litellm/client.d.ts +2 -9
- package/dist/providers/litellm/client.js +1 -63
- package/dist/providers/openAI/client.d.ts +1 -8
- package/dist/providers/openAI/client.js +0 -65
- package/dist/providers/openaiChatCompletionsBase.d.ts +1 -0
- package/dist/providers/openaiChatCompletionsBase.js +61 -4
- package/dist/providers/replicate.js +22 -4
- package/dist/proxy/codexUsage.js +7 -0
- package/dist/proxy/proxyFetch.js +19 -25
- package/dist/proxy/proxyTracer.d.ts +14 -7
- package/dist/proxy/proxyTracer.js +129 -83
- package/dist/proxy/proxyTranslationEngine.js +0 -1
- package/dist/proxy/requestLogger.d.ts +1 -1
- package/dist/proxy/requestLogger.js +39 -45
- package/dist/server/middleware/common.js +1 -1
- package/dist/server/routes/agentRoutes.js +4 -4
- package/dist/server/routes/claudeProxyRoutes.js +99 -196
- package/dist/server/routes/codexProxyRoutes.js +621 -591
- package/dist/server/routes/healthRoutes.js +6 -6
- package/dist/server/routes/mcpRoutes.js +7 -7
- package/dist/server/routes/memoryRoutes.js +7 -7
- package/dist/server/routes/openApiRoutes.js +3 -3
- package/dist/server/routes/toolRoutes.js +5 -5
- package/dist/server/routes/transcribeRoutes.js +1 -1
- package/dist/server/utils/validation.d.ts +3 -3
- package/dist/services/server/ai/observability/instrumentation.d.ts +34 -201
- package/dist/services/server/ai/observability/instrumentation.js +220 -1267
- package/dist/services/server/ai/observability/langfuseSetup.d.ts +14 -0
- package/dist/services/server/ai/observability/langfuseSetup.js +55 -0
- package/dist/services/server/ai/observability/otlpSetup.d.ts +16 -0
- package/dist/services/server/ai/observability/otlpSetup.js +58 -0
- package/dist/session/globalSessionState.js +0 -11
- package/dist/telemetry/attributes.d.ts +23 -46
- package/dist/telemetry/attributes.js +76 -162
- package/dist/telemetry/chatMessages.d.ts +13 -0
- package/dist/telemetry/chatMessages.js +59 -0
- package/dist/telemetry/index.d.ts +5 -19
- package/dist/telemetry/index.js +5 -26
- package/dist/telemetry/observation.d.ts +37 -0
- package/dist/telemetry/observation.js +112 -0
- package/dist/telemetry/observationNames.d.ts +18 -0
- package/dist/telemetry/observationNames.js +24 -0
- package/dist/telemetry/spanSanitizer.d.ts +39 -0
- package/dist/telemetry/spanSanitizer.js +92 -0
- package/dist/telemetry/spanSerialization.d.ts +13 -0
- package/dist/telemetry/spanSerialization.js +46 -0
- package/dist/telemetry/tracers.d.ts +37 -18
- package/dist/telemetry/tracers.js +97 -19
- package/dist/telemetry/withSpan.d.ts +47 -25
- package/dist/telemetry/withSpan.js +158 -71
- package/dist/types/cli.d.ts +0 -11
- package/dist/types/decision.d.ts +3 -0
- package/dist/types/exporter.d.ts +54 -0
- package/dist/types/exporter.js +0 -4
- package/dist/types/generate.d.ts +4 -1
- package/dist/types/isolatedAgent.d.ts +5 -4
- package/dist/types/loopEngine.d.ts +18 -28
- package/dist/types/observability.d.ts +127 -160
- package/dist/types/providers.d.ts +15 -0
- package/dist/types/proxy.d.ts +41 -2
- package/dist/utils/anthropicTraceSanitizer.d.ts +2 -2
- package/dist/utils/anthropicTraceSanitizer.js +3 -1
- package/dist/utils/conversationMemory.js +4 -4
- package/dist/utils/fileDetector.js +1 -1
- package/dist/utils/messageBuilder.js +1 -1
- package/dist/utils/noOutputSentinel.d.ts +4 -16
- package/dist/utils/noOutputSentinel.js +12 -28
- package/dist/utils/providerRetry.js +4 -4
- package/dist/voice/livekit/brain.js +1 -1
- package/dist/voice/livekit/realtimeMemory.d.ts +1 -1
- package/dist/voice/livekit/realtimeMemory.js +66 -1
- package/dist/voice/livekit/realtimeVoiceAgent.js +1 -1
- package/docs-site/static/search-index.json +41 -63
- package/package.json +5 -4
- package/dist/telemetry/telemetryService.d.ts +0 -79
- package/dist/telemetry/telemetryService.js +0 -572
- package/dist/utils/observabilityHelpers.d.ts +0 -27
- package/dist/utils/observabilityHelpers.js +0 -47
|
@@ -1,7 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LangfuseOtelSpanAttributes } from "@langfuse/tracing";
|
|
2
|
+
import { context, SpanKind, SpanStatusCode, trace, } from "@opentelemetry/api";
|
|
3
|
+
import { isAbortError } from "../utils/errorHandling.js";
|
|
4
|
+
import { observe, observeGeneration } from "./observation.js";
|
|
5
|
+
import { generationName, stepSpanName } from "./observationNames.js";
|
|
6
|
+
import { tracers } from "./tracers.js";
|
|
7
|
+
function markFailure(span, error, expected = false) {
|
|
8
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
9
|
+
if (isAbortError(error)) {
|
|
10
|
+
span.setAttributes({
|
|
11
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: "WARNING",
|
|
12
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: message,
|
|
13
|
+
});
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message });
|
|
17
|
+
if (!expected) {
|
|
18
|
+
span.setAttributes({
|
|
19
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: "ERROR",
|
|
20
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: message,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (error instanceof Error) {
|
|
24
|
+
span.recordException(error);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
2
27
|
export async function withSpan(options, fn) {
|
|
3
|
-
const { name, tracer, kind = SpanKind.INTERNAL, attributes } = options;
|
|
4
|
-
|
|
28
|
+
const { name, tracer, kind = SpanKind.INTERNAL, attributes, detached, } = options;
|
|
29
|
+
const run = async (span) => {
|
|
5
30
|
if (attributes) {
|
|
6
31
|
for (const [key, value] of Object.entries(attributes)) {
|
|
7
32
|
if (value !== undefined) {
|
|
@@ -15,49 +40,31 @@ export async function withSpan(options, fn) {
|
|
|
15
40
|
return result;
|
|
16
41
|
}
|
|
17
42
|
catch (error) {
|
|
18
|
-
span.
|
|
19
|
-
code: SpanStatusCode.ERROR,
|
|
20
|
-
message: error instanceof Error ? error.message : String(error),
|
|
21
|
-
});
|
|
22
|
-
if (error instanceof Error) {
|
|
23
|
-
span.recordException(error);
|
|
24
|
-
}
|
|
43
|
+
markFailure(span, error, options.expectedFailure?.(error));
|
|
25
44
|
throw error;
|
|
26
45
|
}
|
|
27
46
|
finally {
|
|
28
47
|
span.end();
|
|
29
48
|
}
|
|
30
|
-
}
|
|
49
|
+
};
|
|
50
|
+
return detached
|
|
51
|
+
? run(tracer.startSpan(name, { kind }))
|
|
52
|
+
: tracer.startActiveSpan(name, { kind }, run);
|
|
31
53
|
}
|
|
32
54
|
export async function withClientSpan(options, fn) {
|
|
33
55
|
return withSpan({ ...options, kind: SpanKind.CLIENT }, fn);
|
|
34
56
|
}
|
|
35
57
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* Required for any operation whose result is a producer (`StreamResult`,
|
|
43
|
-
* `AsyncIterable`-returning function, etc.) — ending the span on `fn`
|
|
44
|
-
* resolution would capture only the setup phase and report zero tokens /
|
|
45
|
-
* meaningless duration.
|
|
46
|
-
*
|
|
47
|
-
* @param options Span options (name, tracer, attributes, kind).
|
|
48
|
-
* @param fn Callback that produces the result. Must NOT depend on
|
|
49
|
-
* the iterable being consumed before returning.
|
|
50
|
-
* @param getIterable Selector that picks the `AsyncIterable` out of the
|
|
51
|
-
* result for wrapping.
|
|
52
|
-
* @param setIterable Setter that returns a new result with the iterable
|
|
53
|
-
* replaced by the wrapped (span-lifetime-extending)
|
|
54
|
-
* iterable. Should be a pure function — clone the
|
|
55
|
-
* result rather than mutating in place.
|
|
56
|
-
*
|
|
58
|
+
* @description Wraps a streaming operation in a span that stays open until the consumer reaches end-of-stream, throws, or closes the iterable, so the span covers the whole stream rather than only its setup.
|
|
59
|
+
* @param options {SpanOptions} - Span name, tracer, kind and initial attributes.
|
|
60
|
+
* @param fn {(span: Span) => Promise<TResult>} - Produces the result; must not depend on the iterable being consumed before returning.
|
|
61
|
+
* @param getIterable {(result: TResult) => AsyncIterable<TChunk>} - Selects the iterable to wrap out of the result.
|
|
62
|
+
* @param setIterable {(result: TResult, wrapped: AsyncIterableIterator<TChunk>) => TResult} - Returns a new result carrying the wrapped iterable; must clone rather than mutate.
|
|
63
|
+
* @returns {Promise<TResult>} The result with its iterable replaced by the span-lifetime-extending one.
|
|
57
64
|
* @example
|
|
58
65
|
* ```ts
|
|
59
66
|
* return withStreamSpan(
|
|
60
|
-
* { name: "
|
|
67
|
+
* { name: "provider.stream", tracer, attributes: {...} },
|
|
61
68
|
* async () => this.executeStreamInner(options),
|
|
62
69
|
* (r) => r.stream,
|
|
63
70
|
* (r, wrapped) => ({ ...r, stream: wrapped }),
|
|
@@ -65,7 +72,7 @@ export async function withClientSpan(options, fn) {
|
|
|
65
72
|
* ```
|
|
66
73
|
*/
|
|
67
74
|
export async function withStreamSpan(options, fn, getIterable, setIterable) {
|
|
68
|
-
const { name, tracer, kind = SpanKind.CLIENT, attributes } = options;
|
|
75
|
+
const { name, tracer, kind = SpanKind.CLIENT, attributes, detached, } = options;
|
|
69
76
|
const span = tracer.startSpan(name, { kind });
|
|
70
77
|
if (attributes) {
|
|
71
78
|
for (const [key, value] of Object.entries(attributes)) {
|
|
@@ -74,25 +81,22 @@ export async function withStreamSpan(options, fn, getIterable, setIterable) {
|
|
|
74
81
|
}
|
|
75
82
|
}
|
|
76
83
|
}
|
|
84
|
+
const spanContext = detached
|
|
85
|
+
? context.active()
|
|
86
|
+
: trace.setSpan(context.active(), span);
|
|
77
87
|
let result;
|
|
78
88
|
try {
|
|
79
|
-
result = await fn(span);
|
|
89
|
+
result = await context.with(spanContext, () => fn(span));
|
|
80
90
|
}
|
|
81
91
|
catch (error) {
|
|
82
|
-
span
|
|
83
|
-
code: SpanStatusCode.ERROR,
|
|
84
|
-
message: error instanceof Error ? error.message : String(error),
|
|
85
|
-
});
|
|
86
|
-
if (error instanceof Error) {
|
|
87
|
-
span.recordException(error);
|
|
88
|
-
}
|
|
92
|
+
markFailure(span, error);
|
|
89
93
|
span.end();
|
|
90
94
|
throw error;
|
|
91
95
|
}
|
|
92
|
-
|
|
93
|
-
const original = getIterable(result);
|
|
96
|
+
const iterator = getIterable(result)[Symbol.asyncIterator]();
|
|
94
97
|
let ended = false;
|
|
95
|
-
|
|
98
|
+
let started = false;
|
|
99
|
+
function end(status) {
|
|
96
100
|
if (ended) {
|
|
97
101
|
return;
|
|
98
102
|
}
|
|
@@ -100,38 +104,121 @@ export async function withStreamSpan(options, fn, getIterable, setIterable) {
|
|
|
100
104
|
if (status) {
|
|
101
105
|
span.setStatus(status);
|
|
102
106
|
}
|
|
103
|
-
else {
|
|
104
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
105
|
-
}
|
|
106
107
|
span.end();
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
// returns `AsyncGenerator<{ content: string }>`).
|
|
112
|
-
const wrapped = (async function* () {
|
|
113
|
-
try {
|
|
114
|
-
for await (const chunk of original) {
|
|
115
|
-
yield chunk;
|
|
116
|
-
}
|
|
117
|
-
endOnce();
|
|
108
|
+
}
|
|
109
|
+
async function close() {
|
|
110
|
+
if (ended) {
|
|
111
|
+
return;
|
|
118
112
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
113
|
+
span.setAttributes({
|
|
114
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: "WARNING",
|
|
115
|
+
[LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE]: started
|
|
116
|
+
? "stream closed early"
|
|
117
|
+
: "stream closed before first chunk",
|
|
118
|
+
});
|
|
119
|
+
end();
|
|
120
|
+
await iterator.return?.();
|
|
121
|
+
}
|
|
122
|
+
const wrapped = {
|
|
123
|
+
async next() {
|
|
124
|
+
if (ended) {
|
|
125
|
+
return { done: true, value: undefined };
|
|
124
126
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
started = true;
|
|
128
|
+
try {
|
|
129
|
+
const step = await context.with(spanContext, () => iterator.next());
|
|
130
|
+
if (step.done) {
|
|
131
|
+
end({ code: SpanStatusCode.OK });
|
|
132
|
+
return { done: true, value: undefined };
|
|
133
|
+
}
|
|
134
|
+
return step;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
markFailure(span, err);
|
|
138
|
+
end();
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
async return() {
|
|
143
|
+
await close();
|
|
144
|
+
return { done: true, value: undefined };
|
|
145
|
+
},
|
|
146
|
+
async throw(error) {
|
|
147
|
+
await close();
|
|
148
|
+
throw error;
|
|
149
|
+
},
|
|
150
|
+
[Symbol.asyncIterator]() {
|
|
151
|
+
return wrapped;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
132
154
|
return setIterable(result, wrapped);
|
|
133
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* @description Runs one model request inside a Langfuse generation span, recording the request half before `fn` runs. `fn` records the response half with `observeGeneration`; errors mark the span ERROR.
|
|
158
|
+
* @param request {GenerationRecord} - Provider, model, parameters and input sent.
|
|
159
|
+
* @param fn {(span: Span) => Promise<T>} - Issues the request and returns its result.
|
|
160
|
+
* @returns {Promise<T>} Whatever `fn` resolves to.
|
|
161
|
+
*/
|
|
162
|
+
export async function withGeneration(request, fn) {
|
|
163
|
+
return withSpan({
|
|
164
|
+
name: generationName(request.operation),
|
|
165
|
+
tracer: tracers.generation,
|
|
166
|
+
kind: SpanKind.CLIENT,
|
|
167
|
+
}, async (span) => {
|
|
168
|
+
observeGeneration(span, request);
|
|
169
|
+
return fn(span);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
134
172
|
/** Convenience CLIENT-kind alias matching `withClientSpan`. */
|
|
135
173
|
export async function withClientStreamSpan(options, fn, getIterable, setIterable) {
|
|
136
174
|
return withStreamSpan({ ...options, kind: SpanKind.CLIENT }, fn, getIterable, setIterable);
|
|
137
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* @description Runs `fn` inside a `step` span, for a single model call that belongs to a step outside the shared loop, such as a forced finalization request.
|
|
178
|
+
* @param stepNumber {number} - One-based step number within the turn.
|
|
179
|
+
* @param fn {() => Promise<T>} - The step's work.
|
|
180
|
+
* @returns {Promise<T>} Whatever `fn` resolves to.
|
|
181
|
+
*/
|
|
182
|
+
export async function withStepSpan(stepNumber, fn) {
|
|
183
|
+
return withSpan({ name: stepSpanName(), tracer: tracers.sdk }, async (span) => {
|
|
184
|
+
observe(span, "span", { metadata: { step_index: stepNumber } });
|
|
185
|
+
return fn();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* @description Groups the observations of each agentic loop step under one `step` span. Call `begin` at the top of a step, run the step's model call and tool dispatch through `run`, and `end` when the loop is over; `begin` closes the previous step.
|
|
190
|
+
*/
|
|
191
|
+
export class StepSpans {
|
|
192
|
+
current;
|
|
193
|
+
/**
|
|
194
|
+
* @description Closes the previous step and opens `step` under the active span.
|
|
195
|
+
* @param stepNumber {number} - One-based step number within the turn.
|
|
196
|
+
* @returns {void} Nothing.
|
|
197
|
+
*/
|
|
198
|
+
begin(stepNumber) {
|
|
199
|
+
this.end();
|
|
200
|
+
this.current = tracers.sdk.startSpan(stepSpanName(), {
|
|
201
|
+
kind: SpanKind.INTERNAL,
|
|
202
|
+
});
|
|
203
|
+
observe(this.current, "span", { metadata: { step_index: stepNumber } });
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* @description Runs `fn` with the open step as the active span, so the observations it creates become the step's children.
|
|
207
|
+
* @param fn {() => T} - Work belonging to the current step.
|
|
208
|
+
* @returns {T} Whatever `fn` returns.
|
|
209
|
+
*/
|
|
210
|
+
run(fn) {
|
|
211
|
+
const step = this.current;
|
|
212
|
+
return step
|
|
213
|
+
? context.with(trace.setSpan(context.active(), step), fn)
|
|
214
|
+
: fn();
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* @description Closes the open step, if any.
|
|
218
|
+
* @returns {void} Nothing.
|
|
219
|
+
*/
|
|
220
|
+
end() {
|
|
221
|
+
this.current?.end();
|
|
222
|
+
this.current = undefined;
|
|
223
|
+
}
|
|
224
|
+
}
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1042,13 +1042,6 @@ export type TelemetryCommandArgs = {
|
|
|
1042
1042
|
};
|
|
1043
1043
|
/** Telemetry status sub-command args */
|
|
1044
1044
|
export type TelemetryStatusArgs = TelemetryCommandArgs;
|
|
1045
|
-
/** Telemetry configure sub-command args */
|
|
1046
|
-
export type TelemetryConfigureArgs = TelemetryCommandArgs & {
|
|
1047
|
-
exporter: string;
|
|
1048
|
-
config: string;
|
|
1049
|
-
};
|
|
1050
|
-
/** Telemetry list-exporters sub-command args */
|
|
1051
|
-
export type TelemetryListExportersArgs = TelemetryCommandArgs;
|
|
1052
1045
|
/** Telemetry flush sub-command args */
|
|
1053
1046
|
export type TelemetryFlushArgs = TelemetryCommandArgs & {
|
|
1054
1047
|
timeout?: number;
|
|
@@ -1077,8 +1070,6 @@ export type TelemetryNativeValidateArgs = {
|
|
|
1077
1070
|
directory: string;
|
|
1078
1071
|
collectorBin: string;
|
|
1079
1072
|
};
|
|
1080
|
-
/** Available exporter names */
|
|
1081
|
-
export type ExporterName = "langfuse" | "langsmith" | "otel" | "datadog" | "sentry" | "braintrust" | "arize" | "posthog" | "laminar";
|
|
1082
1073
|
/** Observability command arguments */
|
|
1083
1074
|
export type ObservabilityCommandArgs = {
|
|
1084
1075
|
format?: "text" | "json" | "table";
|
|
@@ -1090,8 +1081,6 @@ export type ObservabilityStatusArgs = ObservabilityCommandArgs;
|
|
|
1090
1081
|
export type ObservabilityMetricsArgs = ObservabilityCommandArgs & {
|
|
1091
1082
|
detailed?: boolean;
|
|
1092
1083
|
};
|
|
1093
|
-
/** Observability exporters sub-command args */
|
|
1094
|
-
export type ObservabilityExportersArgs = ObservabilityCommandArgs;
|
|
1095
1084
|
/** Observability costs sub-command args */
|
|
1096
1085
|
export type ObservabilityCostsArgs = ObservabilityCommandArgs & {
|
|
1097
1086
|
byModel?: boolean;
|
package/dist/types/decision.d.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* `src/lib/types/` (CLAUDE.md rule 9). Note `evaluate`/`Evaluation*` is a
|
|
19
19
|
* different, unrelated feature — scoring a generated response with RAGAS.
|
|
20
20
|
*/
|
|
21
|
+
import type { NeurolinkTraceContext } from "./observability.js";
|
|
21
22
|
import type { NeurolinkCredentials } from "./providers.js";
|
|
22
23
|
/**
|
|
23
24
|
* Anything a decision model accepts as free-form content. `state` may be a
|
|
@@ -336,6 +337,8 @@ export type DecisionOptions = DecisionRequest & {
|
|
|
336
337
|
provider?: string;
|
|
337
338
|
/** Per-call credential overrides, as `generate()` takes. */
|
|
338
339
|
credentials?: NeurolinkCredentials;
|
|
340
|
+
/** Per-call trace attributes (user, session, tags, trace name, metadata) for this decision's spans. */
|
|
341
|
+
context?: NeurolinkTraceContext;
|
|
339
342
|
};
|
|
340
343
|
/**
|
|
341
344
|
* The built-in consumers of the `decide` inference type — one name per place
|
package/dist/types/exporter.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { JsonValue } from "./common.js";
|
|
2
|
+
import type { SpanAttributes } from "./span.js";
|
|
1
3
|
/**
|
|
2
4
|
* Exporter configuration types
|
|
3
5
|
* Following NeuroLink's type conventions
|
|
@@ -71,6 +73,13 @@ export type LangfuseExporterConfig = ExporterConfig & {
|
|
|
71
73
|
* Defaults to false (input/output are exported).
|
|
72
74
|
*/
|
|
73
75
|
redactIO?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Applied to input, output and metadata before they are sent. When it
|
|
78
|
+
* throws, the value is replaced by `<fully masked>`.
|
|
79
|
+
*/
|
|
80
|
+
mask?: (params: {
|
|
81
|
+
data: JsonValue;
|
|
82
|
+
}) => JsonValue;
|
|
74
83
|
};
|
|
75
84
|
/**
|
|
76
85
|
* LangSmith exporter configuration
|
|
@@ -255,3 +264,48 @@ export type SamplingRule = {
|
|
|
255
264
|
/** Optional priority (higher = evaluated first) */
|
|
256
265
|
priority?: number;
|
|
257
266
|
};
|
|
267
|
+
/** @description A span attribute value as `SpanData` carries it before OTLP encoding. */
|
|
268
|
+
export type SpanAttributeValue = SpanAttributes[string];
|
|
269
|
+
/** @description An OTLP/JSON attribute value. */
|
|
270
|
+
export type OtlpAnyValue = {
|
|
271
|
+
boolValue: boolean;
|
|
272
|
+
} | {
|
|
273
|
+
intValue: string;
|
|
274
|
+
} | {
|
|
275
|
+
doubleValue: number;
|
|
276
|
+
} | {
|
|
277
|
+
stringValue: string;
|
|
278
|
+
} | {
|
|
279
|
+
arrayValue: {
|
|
280
|
+
values: OtlpAnyValue[];
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
/** @description An OTLP/JSON attribute. */
|
|
284
|
+
export type OtlpKeyValue = {
|
|
285
|
+
key: string;
|
|
286
|
+
value: OtlpAnyValue;
|
|
287
|
+
};
|
|
288
|
+
/** @description An OTLP/JSON span as Langfuse's ingestion endpoint reads it. */
|
|
289
|
+
export type OtlpSpan = {
|
|
290
|
+
traceId: string;
|
|
291
|
+
spanId: string;
|
|
292
|
+
parentSpanId?: string;
|
|
293
|
+
name: string;
|
|
294
|
+
kind: number;
|
|
295
|
+
startTimeUnixNano: string;
|
|
296
|
+
endTimeUnixNano: string;
|
|
297
|
+
attributes: OtlpKeyValue[];
|
|
298
|
+
events: {
|
|
299
|
+
name: string;
|
|
300
|
+
timeUnixNano: string;
|
|
301
|
+
attributes: OtlpKeyValue[];
|
|
302
|
+
}[];
|
|
303
|
+
status: {
|
|
304
|
+
code: number;
|
|
305
|
+
message?: string;
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
/** @description What the Langfuse exporter adds to, masks in and removes from span attributes before sending. */
|
|
309
|
+
export type LangfuseAttributePolicy = Pick<LangfuseExporterConfig, "environment" | "release" | "mask"> & {
|
|
310
|
+
redactIO: boolean;
|
|
311
|
+
};
|
package/dist/types/exporter.js
CHANGED
package/dist/types/generate.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { AnalyticsData, TokenUsage } from "./analytics.js";
|
|
|
6
6
|
import type { ClaudeLimitSnapshot } from "./subscription.js";
|
|
7
7
|
import type { JsonValue } from "./common.js";
|
|
8
8
|
import type { TerminalAgentModeOption, TerminalAgentModeVersion } from "./agentMode.js";
|
|
9
|
+
import type { NeurolinkTraceContext } from "./observability.js";
|
|
9
10
|
import type { Content, ImageWithAltText } from "./content.js";
|
|
10
11
|
import type { ChatMessage, ConversationMemoryConfig, StreamEventSequence, ToolReplayMode } from "./conversation.js";
|
|
11
12
|
import type { MemoryCallOptions } from "./memory.js";
|
|
@@ -647,7 +648,7 @@ export type GenerateOptions = {
|
|
|
647
648
|
} | undefined>;
|
|
648
649
|
enableEvaluation?: boolean;
|
|
649
650
|
enableAnalytics?: boolean;
|
|
650
|
-
context?: StandardRecord;
|
|
651
|
+
context?: StandardRecord & NeurolinkTraceContext;
|
|
651
652
|
evaluationDomain?: string;
|
|
652
653
|
toolUsageContext?: string;
|
|
653
654
|
/**
|
|
@@ -1847,6 +1848,8 @@ export type NativeGenerateLoopArgs = {
|
|
|
1847
1848
|
prepareStep?: NativeLoopPrepareStep;
|
|
1848
1849
|
/** Resolved model id, handed to `prepareStep` as its `model` argument. */
|
|
1849
1850
|
modelId: string;
|
|
1851
|
+
/** Provider name recorded on each step's generation and used to price it. */
|
|
1852
|
+
provider: string;
|
|
1850
1853
|
responseFormat?: Record<string, unknown>;
|
|
1851
1854
|
providerOptions?: Record<string, Record<string, unknown>>;
|
|
1852
1855
|
maxSteps: number;
|
|
@@ -31,10 +31,11 @@ export type WorkerLogEvent = {
|
|
|
31
31
|
* Options for `NeuroLink.createWorkerInstance()`.
|
|
32
32
|
*
|
|
33
33
|
* A worker instance is a sub-agent-grade NeuroLink: conversation memory off,
|
|
34
|
-
* orchestration off, observability inherited from the creating
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* orchestration off, observability config inherited from the creating
|
|
35
|
+
* instance, and an internal log bridge attached with a caller-supplied tag.
|
|
36
|
+
* Telemetry is shared through the process-wide tracer provider, which is
|
|
37
|
+
* auto-detected when the host registered its own, so worker spans join the
|
|
38
|
+
* host's traces without duplicate Langfuse exports.
|
|
38
39
|
*/
|
|
39
40
|
export type WorkerInstanceOptions = {
|
|
40
41
|
/** Tag stamped on every forwarded log event (default "worker"). */
|
|
@@ -2,6 +2,8 @@ import type Anthropic from "@anthropic-ai/sdk";
|
|
|
2
2
|
import type { Span } from "@opentelemetry/api";
|
|
3
3
|
import type { Tool } from "./tools.js";
|
|
4
4
|
import type { GenerateStopReason } from "./generate.js";
|
|
5
|
+
import type { UnknownRecord } from "./common.js";
|
|
6
|
+
import type { GenerationRecord } from "./observability.js";
|
|
5
7
|
import type { CollectedChunkResult, NativeFunctionCall, NativeToolDeclarationsResult } from "./providers.js";
|
|
6
8
|
import type { ExecutionControlDecision, ExecutionControlStepContext } from "./stream.js";
|
|
7
9
|
/**
|
|
@@ -50,6 +52,8 @@ export type AgenticLoopStepResult<TRaw = unknown> = {
|
|
|
50
52
|
usage: AgenticLoopUsage;
|
|
51
53
|
/** Provider's own raw stop/finish-reason string, e.g. "tool_use", "MAX_TOKENS" */
|
|
52
54
|
rawStopReason: string | undefined;
|
|
55
|
+
/** Model the response says served it, when the API reports one. */
|
|
56
|
+
model?: string;
|
|
53
57
|
/** Adapter-private accumulated response data needed by buildToolResultMessages
|
|
54
58
|
* (e.g. Anthropic's ordered content blocks, Gemini's rawResponseParts). */
|
|
55
59
|
raw: TRaw;
|
|
@@ -61,6 +65,8 @@ export type AgenticLoopToolCallResult = AgenticLoopToolCall & {
|
|
|
61
65
|
};
|
|
62
66
|
export type AgenticLoopStepRequest = {
|
|
63
67
|
raw: unknown;
|
|
68
|
+
/** The request half of this step's generation observation. */
|
|
69
|
+
generation?: GenerationRecord;
|
|
64
70
|
/**
|
|
65
71
|
* Tools that became callable while this step's request was being built —
|
|
66
72
|
* mid-turn discovery hydrating a name the model had already tried.
|
|
@@ -248,6 +254,8 @@ export type AnthropicLoopAdapterConfig<TMessage = Anthropic.Messages.MessagePara
|
|
|
248
254
|
client: {
|
|
249
255
|
messages: Pick<Anthropic["messages"], "create">;
|
|
250
256
|
};
|
|
257
|
+
/** Provider name recorded on each step's generation and used to price it. */
|
|
258
|
+
provider: string;
|
|
251
259
|
maxSteps: number;
|
|
252
260
|
/**
|
|
253
261
|
* Build one step's request. A closure so the per-turn work the caller
|
|
@@ -346,13 +354,6 @@ export type AnthropicLoopAdapterConfig<TMessage = Anthropic.Messages.MessagePara
|
|
|
346
354
|
* it, so this cannot quietly give a provider behaviour its hand-rolled loops
|
|
347
355
|
* never had.
|
|
348
356
|
*/
|
|
349
|
-
/** One model-requested tool call, as recorded on the tool's observability span. */
|
|
350
|
-
export type ToolSpanCall = {
|
|
351
|
-
/** Arguments the model passed to the tool. */
|
|
352
|
-
args?: Record<string, unknown>;
|
|
353
|
-
/** The model's id for this call, shared with the tool_use block that requested it. */
|
|
354
|
-
toolCallId?: string;
|
|
355
|
-
};
|
|
356
357
|
export type ToolExecutionGuards = {
|
|
357
358
|
/**
|
|
358
359
|
* Upper bound on a single execute(). Omit, or pass `null`, for no bound.
|
|
@@ -374,25 +375,6 @@ export type ToolExecutionGuards = {
|
|
|
374
375
|
* legitimately slow tool reads as a stalled turn without this.
|
|
375
376
|
*/
|
|
376
377
|
onProgress?: () => void;
|
|
377
|
-
/**
|
|
378
|
-
* Wrap one tool call in the provider's own observability.
|
|
379
|
-
*
|
|
380
|
-
* A function rather than a pair of start/end callbacks, because the caller
|
|
381
|
-
* needs the execution to happen INSIDE its span's context — spans opened by
|
|
382
|
-
* the tool itself must nest under the tool call, not dangle as siblings of
|
|
383
|
-
* the turn. Handing over the whole invocation is the only shape that lets a
|
|
384
|
-
* caller do `context.with(span, run)`.
|
|
385
|
-
*
|
|
386
|
-
* The caller awaits `run()` itself, so it sees the settled result and can
|
|
387
|
-
* mark a FAILURE THAT WAS RETURNED rather than thrown: MCP tools report
|
|
388
|
-
* errors in their payload, and an observation that only watches for
|
|
389
|
-
* exceptions records those calls as successful.
|
|
390
|
-
*
|
|
391
|
-
* `call` carries the arguments the model passed and the model's id for the
|
|
392
|
-
* call, so the observation can show what was asked and be paired with the
|
|
393
|
-
* request that asked it.
|
|
394
|
-
*/
|
|
395
|
-
withToolSpan?: <T>(name: string, run: () => Promise<T>, call?: ToolSpanCall) => Promise<T>;
|
|
396
378
|
};
|
|
397
379
|
/**
|
|
398
380
|
* @deprecated Renamed to `ToolExecutionGuards` — the guards were never
|
|
@@ -406,6 +388,12 @@ export type GeminiStepRaw = {
|
|
|
406
388
|
rawResponseParts: unknown[];
|
|
407
389
|
stepFunctionCalls: NativeFunctionCall[];
|
|
408
390
|
};
|
|
391
|
+
/** One Gemini step's request: the model, the conversation and the generation config. */
|
|
392
|
+
export type GeminiStepRequest = {
|
|
393
|
+
model: string;
|
|
394
|
+
contents: GeminiTurnContent[];
|
|
395
|
+
config?: UnknownRecord;
|
|
396
|
+
};
|
|
409
397
|
/** One turn entry in a Gemini conversation: a role plus its content parts. */
|
|
410
398
|
export type GeminiTurnContent = {
|
|
411
399
|
role: string;
|
|
@@ -419,9 +407,11 @@ export type GeminiTurnContent = {
|
|
|
419
407
|
export type GeminiLoopAdapterCoreConfig = {
|
|
420
408
|
/** Used in log lines and generated tool-call ids. */
|
|
421
409
|
providerLabel: string;
|
|
410
|
+
/** Provider name recorded on each step's generation and used to price it. */
|
|
411
|
+
provider: string;
|
|
422
412
|
maxSteps: number;
|
|
423
413
|
/** Build one step's request object (model, contents, config). */
|
|
424
|
-
buildRequest: (conversation: GeminiTurnContent[], step: number) =>
|
|
414
|
+
buildRequest: (conversation: GeminiTurnContent[], step: number) => GeminiStepRequest;
|
|
425
415
|
/** Issue the request. Kept injectable so each provider keeps its own client. */
|
|
426
416
|
sendStep: (request: unknown, signal: AbortSignal) => Promise<AsyncIterable<{
|
|
427
417
|
functionCalls?: NativeFunctionCall[];
|
|
@@ -541,7 +531,7 @@ export type AgenticLoopOptions = {
|
|
|
541
531
|
/**
|
|
542
532
|
* Span the per-step provider retry annotates, via
|
|
543
533
|
* `withProviderRetry(..., span, ...)` — it records
|
|
544
|
-
* `
|
|
534
|
+
* `provider.total_attempts` on every completed step, retried or not.
|
|
545
535
|
*
|
|
546
536
|
* Caller-supplied rather than read from the ambient context inside the
|
|
547
537
|
* engine. Reading it here would hand the attribute to every provider on the
|