neatlogs 1.0.8 → 1.0.10
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/dist/anthropic.cjs +163 -17
- package/dist/anthropic.cjs.map +1 -1
- package/dist/anthropic.mjs +173 -18
- package/dist/anthropic.mjs.map +1 -1
- package/dist/azure-openai.cjs +163 -17
- package/dist/azure-openai.cjs.map +1 -1
- package/dist/azure-openai.mjs +173 -18
- package/dist/azure-openai.mjs.map +1 -1
- package/dist/bedrock.cjs +167 -21
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.mjs +177 -22
- package/dist/bedrock.mjs.map +1 -1
- package/dist/index.cjs +860 -310
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +778 -225
- package/dist/index.mjs.map +1 -1
- package/dist/langchain.cjs +163 -23
- package/dist/langchain.cjs.map +1 -1
- package/dist/langchain.mjs +173 -24
- package/dist/langchain.mjs.map +1 -1
- package/dist/openai.cjs +163 -17
- package/dist/openai.cjs.map +1 -1
- package/dist/openai.mjs +173 -18
- package/dist/openai.mjs.map +1 -1
- package/dist/opencode-plugin.cjs +530 -5727
- package/dist/opencode-plugin.cjs.map +1 -1
- package/dist/opencode-plugin.d.ts +17 -16
- package/dist/opencode-plugin.mjs +530 -5740
- package/dist/opencode-plugin.mjs.map +1 -1
- package/dist/openrouter-agent.cjs +157 -11
- package/dist/openrouter-agent.cjs.map +1 -1
- package/dist/openrouter-agent.mjs +167 -12
- package/dist/openrouter-agent.mjs.map +1 -1
- package/dist/vertex-ai.cjs +171 -25
- package/dist/vertex-ai.cjs.map +1 -1
- package/dist/vertex-ai.mjs +181 -26
- package/dist/vertex-ai.mjs.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -5899,7 +5899,7 @@ async function removeTag(name, tag) {
|
|
|
5899
5899
|
}
|
|
5900
5900
|
|
|
5901
5901
|
// src/version.ts
|
|
5902
|
-
var __version__ = "1.0.
|
|
5902
|
+
var __version__ = "1.0.10";
|
|
5903
5903
|
|
|
5904
5904
|
// src/init.ts
|
|
5905
5905
|
var logger13 = getLogger();
|
|
@@ -6532,14 +6532,108 @@ function recordSpanError(span2, err) {
|
|
|
6532
6532
|
}
|
|
6533
6533
|
|
|
6534
6534
|
// src/openai.ts
|
|
6535
|
+
var import_api10 = require("@opentelemetry/api");
|
|
6536
|
+
|
|
6537
|
+
// src/core/auto-root.ts
|
|
6535
6538
|
var import_api9 = require("@opentelemetry/api");
|
|
6539
|
+
var ROOT_KINDS = /* @__PURE__ */ new Set(["workflow", "chain", "agent", "mcp_tool"]);
|
|
6540
|
+
function autoRootEnabled() {
|
|
6541
|
+
const val = (process.env.NEATLOGS_AUTO_ROOT ?? "").trim().toLowerCase();
|
|
6542
|
+
return !["false", "0", "no", "off"].includes(val);
|
|
6543
|
+
}
|
|
6544
|
+
function resolveRootWorkflowName() {
|
|
6545
|
+
try {
|
|
6546
|
+
const name = getSessionConfig()?.workflowName;
|
|
6547
|
+
if (typeof name === "string" && name.trim()) return name;
|
|
6548
|
+
} catch {
|
|
6549
|
+
}
|
|
6550
|
+
return "workflow";
|
|
6551
|
+
}
|
|
6552
|
+
function wrapSpanWithRoot(child, root) {
|
|
6553
|
+
let ended = false;
|
|
6554
|
+
return new Proxy(child, {
|
|
6555
|
+
get(target, prop, _receiver) {
|
|
6556
|
+
if (prop === "end") {
|
|
6557
|
+
return (...args) => {
|
|
6558
|
+
if (ended) return;
|
|
6559
|
+
ended = true;
|
|
6560
|
+
try {
|
|
6561
|
+
target.end(...args);
|
|
6562
|
+
} finally {
|
|
6563
|
+
try {
|
|
6564
|
+
root.end();
|
|
6565
|
+
} catch {
|
|
6566
|
+
}
|
|
6567
|
+
}
|
|
6568
|
+
};
|
|
6569
|
+
}
|
|
6570
|
+
const value = Reflect.get(target, prop, target);
|
|
6571
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
6572
|
+
}
|
|
6573
|
+
});
|
|
6574
|
+
}
|
|
6575
|
+
function maybeOpenAutoRoot(tracer, kind, baseCtx) {
|
|
6576
|
+
const k = String(kind ?? "").toLowerCase();
|
|
6577
|
+
const existing = import_api9.trace.getSpan(baseCtx);
|
|
6578
|
+
if (!autoRootEnabled() || ROOT_KINDS.has(k) || existing !== void 0 && existing.isRecording()) {
|
|
6579
|
+
return { root: void 0, ctx: baseCtx };
|
|
6580
|
+
}
|
|
6581
|
+
const root = tracer.startSpan(
|
|
6582
|
+
resolveRootWorkflowName(),
|
|
6583
|
+
{ attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
|
|
6584
|
+
baseCtx
|
|
6585
|
+
);
|
|
6586
|
+
return { root, ctx: import_api9.trace.setSpan(baseCtx, root) };
|
|
6587
|
+
}
|
|
6588
|
+
function endAutoRoot(root) {
|
|
6589
|
+
if (!root) return;
|
|
6590
|
+
try {
|
|
6591
|
+
root.end();
|
|
6592
|
+
} catch {
|
|
6593
|
+
}
|
|
6594
|
+
}
|
|
6595
|
+
var AutoRootTracer = class {
|
|
6596
|
+
constructor(_tracer) {
|
|
6597
|
+
this._tracer = _tracer;
|
|
6598
|
+
}
|
|
6599
|
+
_tracer;
|
|
6600
|
+
startSpan(name, options, context3) {
|
|
6601
|
+
const kind = String(
|
|
6602
|
+
options?.attributes?.["neatlogs.span.kind"] ?? ""
|
|
6603
|
+
).toLowerCase();
|
|
6604
|
+
const ctx = context3 ?? import_api9.context.active();
|
|
6605
|
+
const parent = import_api9.trace.getSpan(ctx);
|
|
6606
|
+
const needsRoot = autoRootEnabled() && !ROOT_KINDS.has(kind) && !(parent !== void 0 && parent.isRecording());
|
|
6607
|
+
if (!needsRoot) {
|
|
6608
|
+
return this._tracer.startSpan(name, options, context3);
|
|
6609
|
+
}
|
|
6610
|
+
const root = this._tracer.startSpan(
|
|
6611
|
+
resolveRootWorkflowName(),
|
|
6612
|
+
{ attributes: { "neatlogs.span.kind": "workflow", "neatlogs.auto_root": true } },
|
|
6613
|
+
ctx
|
|
6614
|
+
);
|
|
6615
|
+
const childCtx = import_api9.trace.setSpan(ctx, root);
|
|
6616
|
+
const child = this._tracer.startSpan(name, options, childCtx);
|
|
6617
|
+
return wrapSpanWithRoot(child, root);
|
|
6618
|
+
}
|
|
6619
|
+
// startActiveSpan is used by traceTool (callback-scoped, always under an
|
|
6620
|
+
// active span in practice) — pass straight through, no auto-root.
|
|
6621
|
+
startActiveSpan = ((...args) => this._tracer.startActiveSpan(
|
|
6622
|
+
...args
|
|
6623
|
+
));
|
|
6624
|
+
};
|
|
6625
|
+
function getProviderTracer(name) {
|
|
6626
|
+
return new AutoRootTracer(import_api9.trace.getTracer(name));
|
|
6627
|
+
}
|
|
6628
|
+
|
|
6629
|
+
// src/openai.ts
|
|
6536
6630
|
var TRACER_NAME3 = "neatlogs.openai";
|
|
6537
6631
|
function wrapOpenAI(client) {
|
|
6538
6632
|
return wrapNamespace(client, []);
|
|
6539
6633
|
}
|
|
6540
6634
|
function traceTool(name, fn) {
|
|
6541
6635
|
return async function tracedTool(args) {
|
|
6542
|
-
const tracer =
|
|
6636
|
+
const tracer = import_api10.trace.getTracer(TRACER_NAME3);
|
|
6543
6637
|
return tracer.startActiveSpan(
|
|
6544
6638
|
`tool.${name}`,
|
|
6545
6639
|
{
|
|
@@ -6549,12 +6643,12 @@ function traceTool(name, fn) {
|
|
|
6549
6643
|
"input.value": safeStringify3(args)
|
|
6550
6644
|
}
|
|
6551
6645
|
},
|
|
6552
|
-
|
|
6646
|
+
import_api10.context.active(),
|
|
6553
6647
|
async (span2) => {
|
|
6554
6648
|
try {
|
|
6555
6649
|
const result = await fn(args);
|
|
6556
6650
|
span2.setAttribute("output.value", safeStringify3(result));
|
|
6557
|
-
span2.setStatus({ code:
|
|
6651
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.OK });
|
|
6558
6652
|
return result;
|
|
6559
6653
|
} catch (err) {
|
|
6560
6654
|
recordError(span2, err);
|
|
@@ -6593,7 +6687,7 @@ function isNamespace(path4) {
|
|
|
6593
6687
|
}
|
|
6594
6688
|
function tracedChatCompletionsCreate(original) {
|
|
6595
6689
|
return function(opts, ...rest) {
|
|
6596
|
-
const tracer =
|
|
6690
|
+
const tracer = getProviderTracer(TRACER_NAME3);
|
|
6597
6691
|
const model = opts?.model ?? "";
|
|
6598
6692
|
const messages = opts?.messages ?? [];
|
|
6599
6693
|
const isStream = opts?.stream === true;
|
|
@@ -6605,7 +6699,7 @@ function tracedChatCompletionsCreate(original) {
|
|
|
6605
6699
|
"neatlogs.llm.model_name": model,
|
|
6606
6700
|
"neatlogs.llm.is_streaming": isStream
|
|
6607
6701
|
}
|
|
6608
|
-
},
|
|
6702
|
+
}, import_api10.context.active());
|
|
6609
6703
|
for (let i = 0; i < messages.length; i++) {
|
|
6610
6704
|
const msg = messages[i];
|
|
6611
6705
|
span2.setAttribute(`neatlogs.llm.input_messages.${i}.role`, msg.role ?? "");
|
|
@@ -6634,8 +6728,8 @@ function tracedChatCompletionsCreate(original) {
|
|
|
6634
6728
|
opts.stream_options = { ...streamOpts, include_usage: true };
|
|
6635
6729
|
}
|
|
6636
6730
|
}
|
|
6637
|
-
const ctx =
|
|
6638
|
-
const promise =
|
|
6731
|
+
const ctx = import_api10.trace.setSpan(import_api10.context.active(), span2);
|
|
6732
|
+
const promise = import_api10.context.with(ctx, () => original(opts, ...rest));
|
|
6639
6733
|
return promise.then(
|
|
6640
6734
|
(response) => {
|
|
6641
6735
|
if (isStream) {
|
|
@@ -6653,7 +6747,7 @@ function tracedChatCompletionsCreate(original) {
|
|
|
6653
6747
|
}
|
|
6654
6748
|
function tracedResponsesCreate(original) {
|
|
6655
6749
|
return function(opts, ...rest) {
|
|
6656
|
-
const tracer =
|
|
6750
|
+
const tracer = getProviderTracer(TRACER_NAME3);
|
|
6657
6751
|
const model = opts?.model ?? "";
|
|
6658
6752
|
const span2 = tracer.startSpan("openai.responses.create", {
|
|
6659
6753
|
attributes: {
|
|
@@ -6663,9 +6757,9 @@ function tracedResponsesCreate(original) {
|
|
|
6663
6757
|
"neatlogs.llm.model_name": model,
|
|
6664
6758
|
"input.value": safeStringify3(opts?.input ?? "")
|
|
6665
6759
|
}
|
|
6666
|
-
},
|
|
6667
|
-
const ctx =
|
|
6668
|
-
const promise =
|
|
6760
|
+
}, import_api10.context.active());
|
|
6761
|
+
const ctx = import_api10.trace.setSpan(import_api10.context.active(), span2);
|
|
6762
|
+
const promise = import_api10.context.with(ctx, () => original(opts, ...rest));
|
|
6669
6763
|
return promise.then(
|
|
6670
6764
|
(response) => {
|
|
6671
6765
|
if (response?.output_text) {
|
|
@@ -6677,7 +6771,7 @@ function tracedResponsesCreate(original) {
|
|
|
6677
6771
|
if (response.usage.input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", response.usage.input_tokens);
|
|
6678
6772
|
if (response.usage.output_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", response.usage.output_tokens);
|
|
6679
6773
|
}
|
|
6680
|
-
span2.setStatus({ code:
|
|
6774
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.OK });
|
|
6681
6775
|
span2.end();
|
|
6682
6776
|
return response;
|
|
6683
6777
|
},
|
|
@@ -6692,7 +6786,7 @@ function wrapAsyncIterableStream(stream, span2) {
|
|
|
6692
6786
|
const chunks = [];
|
|
6693
6787
|
const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);
|
|
6694
6788
|
if (!originalAsyncIterator) {
|
|
6695
|
-
span2.setStatus({ code:
|
|
6789
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.OK });
|
|
6696
6790
|
span2.end();
|
|
6697
6791
|
return stream;
|
|
6698
6792
|
}
|
|
@@ -6778,7 +6872,7 @@ function finalizeStreamChunks(span2, chunks) {
|
|
|
6778
6872
|
span2.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
|
|
6779
6873
|
}
|
|
6780
6874
|
}
|
|
6781
|
-
span2.setStatus({ code:
|
|
6875
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.OK });
|
|
6782
6876
|
span2.end();
|
|
6783
6877
|
}
|
|
6784
6878
|
function finalizeChatResponse(span2, response) {
|
|
@@ -6815,7 +6909,7 @@ function finalizeChatResponse(span2, response) {
|
|
|
6815
6909
|
}
|
|
6816
6910
|
}
|
|
6817
6911
|
if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
|
|
6818
|
-
span2.setStatus({ code:
|
|
6912
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.OK });
|
|
6819
6913
|
span2.end();
|
|
6820
6914
|
}
|
|
6821
6915
|
function setInvocationParams(span2, opts) {
|
|
@@ -6835,23 +6929,23 @@ function safeStringify3(value) {
|
|
|
6835
6929
|
}
|
|
6836
6930
|
function recordError(span2, err) {
|
|
6837
6931
|
if (err instanceof Error) {
|
|
6838
|
-
span2.setStatus({ code:
|
|
6932
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.ERROR, message: err.message });
|
|
6839
6933
|
span2.recordException(err);
|
|
6840
6934
|
} else {
|
|
6841
|
-
span2.setStatus({ code:
|
|
6935
|
+
span2.setStatus({ code: import_api10.SpanStatusCode.ERROR, message: String(err) });
|
|
6842
6936
|
}
|
|
6843
6937
|
span2.end();
|
|
6844
6938
|
}
|
|
6845
6939
|
|
|
6846
6940
|
// src/anthropic.ts
|
|
6847
|
-
var
|
|
6941
|
+
var import_api11 = require("@opentelemetry/api");
|
|
6848
6942
|
var TRACER_NAME4 = "neatlogs.anthropic";
|
|
6849
6943
|
function wrapAnthropic(client) {
|
|
6850
6944
|
return wrapNamespace2(client, []);
|
|
6851
6945
|
}
|
|
6852
6946
|
function traceTool2(name, fn) {
|
|
6853
6947
|
return async function tracedTool(input) {
|
|
6854
|
-
const tracer =
|
|
6948
|
+
const tracer = getProviderTracer(TRACER_NAME4);
|
|
6855
6949
|
return tracer.startActiveSpan(
|
|
6856
6950
|
`tool.${name}`,
|
|
6857
6951
|
{
|
|
@@ -6861,12 +6955,12 @@ function traceTool2(name, fn) {
|
|
|
6861
6955
|
"input.value": safeStringify4(input)
|
|
6862
6956
|
}
|
|
6863
6957
|
},
|
|
6864
|
-
|
|
6958
|
+
import_api11.context.active(),
|
|
6865
6959
|
async (span2) => {
|
|
6866
6960
|
try {
|
|
6867
6961
|
const result = await fn(input);
|
|
6868
6962
|
span2.setAttribute("output.value", safeStringify4(result));
|
|
6869
|
-
span2.setStatus({ code:
|
|
6963
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.OK });
|
|
6870
6964
|
return result;
|
|
6871
6965
|
} catch (err) {
|
|
6872
6966
|
recordError2(span2, err);
|
|
@@ -6905,7 +6999,7 @@ function isNamespace2(path4) {
|
|
|
6905
6999
|
}
|
|
6906
7000
|
function tracedMessagesCreate(original) {
|
|
6907
7001
|
return function(opts, ...rest) {
|
|
6908
|
-
const tracer =
|
|
7002
|
+
const tracer = getProviderTracer(TRACER_NAME4);
|
|
6909
7003
|
const model = opts?.model ?? "";
|
|
6910
7004
|
const messages = opts?.messages ?? [];
|
|
6911
7005
|
const isStream = opts?.stream === true;
|
|
@@ -6917,12 +7011,12 @@ function tracedMessagesCreate(original) {
|
|
|
6917
7011
|
"neatlogs.llm.model_name": model,
|
|
6918
7012
|
"neatlogs.llm.is_streaming": isStream
|
|
6919
7013
|
}
|
|
6920
|
-
},
|
|
7014
|
+
}, import_api11.context.active());
|
|
6921
7015
|
setInputMessages(span2, opts?.system, messages);
|
|
6922
7016
|
setTools(span2, opts?.tools);
|
|
6923
7017
|
setInvocationParams2(span2, opts);
|
|
6924
|
-
const ctx =
|
|
6925
|
-
const promise =
|
|
7018
|
+
const ctx = import_api11.trace.setSpan(import_api11.context.active(), span2);
|
|
7019
|
+
const promise = import_api11.context.with(ctx, () => original(opts, ...rest));
|
|
6926
7020
|
return promise.then(
|
|
6927
7021
|
(response) => {
|
|
6928
7022
|
if (isStream) {
|
|
@@ -6940,7 +7034,7 @@ function tracedMessagesCreate(original) {
|
|
|
6940
7034
|
}
|
|
6941
7035
|
function tracedMessagesStream(original) {
|
|
6942
7036
|
return function(opts, ...rest) {
|
|
6943
|
-
const tracer =
|
|
7037
|
+
const tracer = getProviderTracer(TRACER_NAME4);
|
|
6944
7038
|
const model = opts?.model ?? "";
|
|
6945
7039
|
const messages = opts?.messages ?? [];
|
|
6946
7040
|
const span2 = tracer.startSpan("anthropic.messages.stream", {
|
|
@@ -6951,12 +7045,12 @@ function tracedMessagesStream(original) {
|
|
|
6951
7045
|
"neatlogs.llm.model_name": model,
|
|
6952
7046
|
"neatlogs.llm.is_streaming": true
|
|
6953
7047
|
}
|
|
6954
|
-
},
|
|
7048
|
+
}, import_api11.context.active());
|
|
6955
7049
|
setInputMessages(span2, opts?.system, messages);
|
|
6956
7050
|
setTools(span2, opts?.tools);
|
|
6957
7051
|
setInvocationParams2(span2, opts);
|
|
6958
|
-
const ctx =
|
|
6959
|
-
const messageStream =
|
|
7052
|
+
const ctx = import_api11.trace.setSpan(import_api11.context.active(), span2);
|
|
7053
|
+
const messageStream = import_api11.context.with(ctx, () => original(opts, ...rest));
|
|
6960
7054
|
return wrapMessageStream(messageStream, span2);
|
|
6961
7055
|
};
|
|
6962
7056
|
}
|
|
@@ -6964,7 +7058,7 @@ function wrapStreamIterable(stream, span2) {
|
|
|
6964
7058
|
const events = [];
|
|
6965
7059
|
const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);
|
|
6966
7060
|
if (!originalAsyncIterator) {
|
|
6967
|
-
span2.setStatus({ code:
|
|
7061
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.OK });
|
|
6968
7062
|
span2.end();
|
|
6969
7063
|
return stream;
|
|
6970
7064
|
}
|
|
@@ -7013,7 +7107,7 @@ function wrapMessageStream(messageStream, span2) {
|
|
|
7013
7107
|
if (finalMsg) {
|
|
7014
7108
|
finalizeMessageResponse(span2, finalMsg);
|
|
7015
7109
|
} else {
|
|
7016
|
-
span2.setStatus({ code:
|
|
7110
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.OK });
|
|
7017
7111
|
span2.end();
|
|
7018
7112
|
}
|
|
7019
7113
|
});
|
|
@@ -7091,7 +7185,7 @@ function finalizeStreamEvents(span2, events) {
|
|
|
7091
7185
|
if (model) span2.setAttribute("neatlogs.llm.model_name", model);
|
|
7092
7186
|
if (stopReason) span2.setAttribute("neatlogs.llm.stop_reason", stopReason);
|
|
7093
7187
|
setUsageAttrs(span2, usage);
|
|
7094
|
-
span2.setStatus({ code:
|
|
7188
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.OK });
|
|
7095
7189
|
span2.end();
|
|
7096
7190
|
}
|
|
7097
7191
|
function finalizeMessageResponse(span2, response) {
|
|
@@ -7125,7 +7219,7 @@ function finalizeMessageResponse(span2, response) {
|
|
|
7125
7219
|
setUsageAttrs(span2, response?.usage);
|
|
7126
7220
|
if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
|
|
7127
7221
|
if (response?.stop_reason) span2.setAttribute("neatlogs.llm.stop_reason", response.stop_reason);
|
|
7128
|
-
span2.setStatus({ code:
|
|
7222
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.OK });
|
|
7129
7223
|
span2.end();
|
|
7130
7224
|
}
|
|
7131
7225
|
function setInputMessages(span2, system, messages) {
|
|
@@ -7178,16 +7272,16 @@ function safeStringify4(value) {
|
|
|
7178
7272
|
}
|
|
7179
7273
|
function recordError2(span2, err) {
|
|
7180
7274
|
if (err instanceof Error) {
|
|
7181
|
-
span2.setStatus({ code:
|
|
7275
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: err.message });
|
|
7182
7276
|
span2.recordException(err);
|
|
7183
7277
|
} else {
|
|
7184
|
-
span2.setStatus({ code:
|
|
7278
|
+
span2.setStatus({ code: import_api11.SpanStatusCode.ERROR, message: String(err) });
|
|
7185
7279
|
}
|
|
7186
7280
|
span2.end();
|
|
7187
7281
|
}
|
|
7188
7282
|
|
|
7189
7283
|
// src/azure-openai.ts
|
|
7190
|
-
var
|
|
7284
|
+
var import_api12 = require("@opentelemetry/api");
|
|
7191
7285
|
var TRACER_NAME5 = "neatlogs.azure_openai";
|
|
7192
7286
|
var PROVIDER = "azure";
|
|
7193
7287
|
var SYSTEM = "azure";
|
|
@@ -7196,7 +7290,7 @@ function wrapAzureOpenAI(client) {
|
|
|
7196
7290
|
}
|
|
7197
7291
|
function traceTool3(name, fn) {
|
|
7198
7292
|
return async function tracedTool(args) {
|
|
7199
|
-
const tracer =
|
|
7293
|
+
const tracer = getProviderTracer(TRACER_NAME5);
|
|
7200
7294
|
return tracer.startActiveSpan(
|
|
7201
7295
|
`tool.${name}`,
|
|
7202
7296
|
{
|
|
@@ -7206,12 +7300,12 @@ function traceTool3(name, fn) {
|
|
|
7206
7300
|
"input.value": safeStringify5(args)
|
|
7207
7301
|
}
|
|
7208
7302
|
},
|
|
7209
|
-
|
|
7303
|
+
import_api12.context.active(),
|
|
7210
7304
|
async (span2) => {
|
|
7211
7305
|
try {
|
|
7212
7306
|
const result = await fn(args);
|
|
7213
7307
|
span2.setAttribute("output.value", safeStringify5(result));
|
|
7214
|
-
span2.setStatus({ code:
|
|
7308
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.OK });
|
|
7215
7309
|
return result;
|
|
7216
7310
|
} catch (err) {
|
|
7217
7311
|
recordError3(span2, err);
|
|
@@ -7250,7 +7344,7 @@ function isNamespace3(path4) {
|
|
|
7250
7344
|
}
|
|
7251
7345
|
function tracedChatCompletionsCreate2(original) {
|
|
7252
7346
|
return function(opts, ...rest) {
|
|
7253
|
-
const tracer =
|
|
7347
|
+
const tracer = getProviderTracer(TRACER_NAME5);
|
|
7254
7348
|
const model = opts?.model ?? "";
|
|
7255
7349
|
const messages = opts?.messages ?? [];
|
|
7256
7350
|
const isStream = opts?.stream === true;
|
|
@@ -7262,7 +7356,7 @@ function tracedChatCompletionsCreate2(original) {
|
|
|
7262
7356
|
"neatlogs.llm.model_name": model,
|
|
7263
7357
|
"neatlogs.llm.is_streaming": isStream
|
|
7264
7358
|
}
|
|
7265
|
-
},
|
|
7359
|
+
}, import_api12.context.active());
|
|
7266
7360
|
for (let i = 0; i < messages.length; i++) {
|
|
7267
7361
|
const msg = messages[i];
|
|
7268
7362
|
span2.setAttribute(`neatlogs.llm.input_messages.${i}.role`, msg.role ?? "");
|
|
@@ -7291,8 +7385,8 @@ function tracedChatCompletionsCreate2(original) {
|
|
|
7291
7385
|
opts.stream_options = { ...streamOpts, include_usage: true };
|
|
7292
7386
|
}
|
|
7293
7387
|
}
|
|
7294
|
-
const ctx =
|
|
7295
|
-
const promise =
|
|
7388
|
+
const ctx = import_api12.trace.setSpan(import_api12.context.active(), span2);
|
|
7389
|
+
const promise = import_api12.context.with(ctx, () => original(opts, ...rest));
|
|
7296
7390
|
return promise.then(
|
|
7297
7391
|
(response) => {
|
|
7298
7392
|
if (isStream) {
|
|
@@ -7310,7 +7404,7 @@ function tracedChatCompletionsCreate2(original) {
|
|
|
7310
7404
|
}
|
|
7311
7405
|
function tracedResponsesCreate2(original) {
|
|
7312
7406
|
return function(opts, ...rest) {
|
|
7313
|
-
const tracer =
|
|
7407
|
+
const tracer = getProviderTracer(TRACER_NAME5);
|
|
7314
7408
|
const model = opts?.model ?? "";
|
|
7315
7409
|
const span2 = tracer.startSpan("azure_openai.responses.create", {
|
|
7316
7410
|
attributes: {
|
|
@@ -7320,9 +7414,9 @@ function tracedResponsesCreate2(original) {
|
|
|
7320
7414
|
"neatlogs.llm.model_name": model,
|
|
7321
7415
|
"input.value": safeStringify5(opts?.input ?? "")
|
|
7322
7416
|
}
|
|
7323
|
-
},
|
|
7324
|
-
const ctx =
|
|
7325
|
-
const promise =
|
|
7417
|
+
}, import_api12.context.active());
|
|
7418
|
+
const ctx = import_api12.trace.setSpan(import_api12.context.active(), span2);
|
|
7419
|
+
const promise = import_api12.context.with(ctx, () => original(opts, ...rest));
|
|
7326
7420
|
return promise.then(
|
|
7327
7421
|
(response) => {
|
|
7328
7422
|
if (response?.output_text) {
|
|
@@ -7334,7 +7428,7 @@ function tracedResponsesCreate2(original) {
|
|
|
7334
7428
|
if (response.usage.input_tokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", response.usage.input_tokens);
|
|
7335
7429
|
if (response.usage.output_tokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", response.usage.output_tokens);
|
|
7336
7430
|
}
|
|
7337
|
-
span2.setStatus({ code:
|
|
7431
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.OK });
|
|
7338
7432
|
span2.end();
|
|
7339
7433
|
return response;
|
|
7340
7434
|
},
|
|
@@ -7349,7 +7443,7 @@ function wrapAsyncIterableStream2(stream, span2) {
|
|
|
7349
7443
|
const chunks = [];
|
|
7350
7444
|
const originalAsyncIterator = stream?.[Symbol.asyncIterator]?.bind(stream);
|
|
7351
7445
|
if (!originalAsyncIterator) {
|
|
7352
|
-
span2.setStatus({ code:
|
|
7446
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.OK });
|
|
7353
7447
|
span2.end();
|
|
7354
7448
|
return stream;
|
|
7355
7449
|
}
|
|
@@ -7435,7 +7529,7 @@ function finalizeStreamChunks2(span2, chunks) {
|
|
|
7435
7529
|
span2.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
|
|
7436
7530
|
}
|
|
7437
7531
|
}
|
|
7438
|
-
span2.setStatus({ code:
|
|
7532
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.OK });
|
|
7439
7533
|
span2.end();
|
|
7440
7534
|
}
|
|
7441
7535
|
function finalizeChatResponse2(span2, response) {
|
|
@@ -7472,7 +7566,7 @@ function finalizeChatResponse2(span2, response) {
|
|
|
7472
7566
|
}
|
|
7473
7567
|
}
|
|
7474
7568
|
if (response?.model) span2.setAttribute("neatlogs.llm.model_name", response.model);
|
|
7475
|
-
span2.setStatus({ code:
|
|
7569
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.OK });
|
|
7476
7570
|
span2.end();
|
|
7477
7571
|
}
|
|
7478
7572
|
function setInvocationParams3(span2, opts) {
|
|
@@ -7492,16 +7586,16 @@ function safeStringify5(value) {
|
|
|
7492
7586
|
}
|
|
7493
7587
|
function recordError3(span2, err) {
|
|
7494
7588
|
if (err instanceof Error) {
|
|
7495
|
-
span2.setStatus({ code:
|
|
7589
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.ERROR, message: err.message });
|
|
7496
7590
|
span2.recordException(err);
|
|
7497
7591
|
} else {
|
|
7498
|
-
span2.setStatus({ code:
|
|
7592
|
+
span2.setStatus({ code: import_api12.SpanStatusCode.ERROR, message: String(err) });
|
|
7499
7593
|
}
|
|
7500
7594
|
span2.end();
|
|
7501
7595
|
}
|
|
7502
7596
|
|
|
7503
7597
|
// src/vertex-ai.ts
|
|
7504
|
-
var
|
|
7598
|
+
var import_api13 = require("@opentelemetry/api");
|
|
7505
7599
|
var TRACER_NAME6 = "neatlogs.vertex_ai";
|
|
7506
7600
|
var PROVIDER2 = "vertex_ai";
|
|
7507
7601
|
var SYSTEM2 = "vertexai";
|
|
@@ -7510,7 +7604,7 @@ function wrapVertexAI(client) {
|
|
|
7510
7604
|
}
|
|
7511
7605
|
function traceTool4(name, fn) {
|
|
7512
7606
|
return async function tracedTool(args) {
|
|
7513
|
-
const tracer =
|
|
7607
|
+
const tracer = getProviderTracer(TRACER_NAME6);
|
|
7514
7608
|
return tracer.startActiveSpan(
|
|
7515
7609
|
`tool.${name}`,
|
|
7516
7610
|
{
|
|
@@ -7520,12 +7614,12 @@ function traceTool4(name, fn) {
|
|
|
7520
7614
|
"input.value": safeStringify6(args)
|
|
7521
7615
|
}
|
|
7522
7616
|
},
|
|
7523
|
-
|
|
7617
|
+
import_api13.context.active(),
|
|
7524
7618
|
async (span2) => {
|
|
7525
7619
|
try {
|
|
7526
7620
|
const result = await fn(args);
|
|
7527
7621
|
span2.setAttribute("output.value", safeStringify6(result));
|
|
7528
|
-
span2.setStatus({ code:
|
|
7622
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.OK });
|
|
7529
7623
|
return result;
|
|
7530
7624
|
} catch (err) {
|
|
7531
7625
|
recordError4(span2, err);
|
|
@@ -7586,7 +7680,7 @@ function wrapVertexAIChat(chat) {
|
|
|
7586
7680
|
return chat;
|
|
7587
7681
|
}
|
|
7588
7682
|
function tracedChatSend(original, chat, params, rest, isStream) {
|
|
7589
|
-
const tracer =
|
|
7683
|
+
const tracer = getProviderTracer(TRACER_NAME6);
|
|
7590
7684
|
const model = chat?.model ?? chat?.modelVersion ?? "";
|
|
7591
7685
|
const span2 = tracer.startSpan("vertex_ai.chat.send_message", {
|
|
7592
7686
|
attributes: {
|
|
@@ -7596,15 +7690,15 @@ function tracedChatSend(original, chat, params, rest, isStream) {
|
|
|
7596
7690
|
"neatlogs.llm.model_name": model,
|
|
7597
7691
|
"neatlogs.llm.is_streaming": isStream
|
|
7598
7692
|
}
|
|
7599
|
-
},
|
|
7693
|
+
}, import_api13.context.active());
|
|
7600
7694
|
const message = params?.message ?? params;
|
|
7601
7695
|
span2.setAttribute("neatlogs.llm.input_messages.0.role", "user");
|
|
7602
7696
|
span2.setAttribute(
|
|
7603
7697
|
"neatlogs.llm.input_messages.0.content",
|
|
7604
7698
|
typeof message === "string" ? message : safeStringify6(message)
|
|
7605
7699
|
);
|
|
7606
|
-
const ctx =
|
|
7607
|
-
const result =
|
|
7700
|
+
const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
|
|
7701
|
+
const result = import_api13.context.with(ctx, () => original(params, ...rest));
|
|
7608
7702
|
return Promise.resolve(result).then(
|
|
7609
7703
|
(response) => {
|
|
7610
7704
|
if (isStream) return wrapStream(response, span2);
|
|
@@ -7619,7 +7713,7 @@ function tracedChatSend(original, chat, params, rest, isStream) {
|
|
|
7619
7713
|
}
|
|
7620
7714
|
function tracedEmbedContent(original) {
|
|
7621
7715
|
return function(opts, ...rest) {
|
|
7622
|
-
const tracer =
|
|
7716
|
+
const tracer = getProviderTracer(TRACER_NAME6);
|
|
7623
7717
|
const span2 = tracer.startSpan("vertex_ai.models.embed_content", {
|
|
7624
7718
|
attributes: {
|
|
7625
7719
|
"neatlogs.span.kind": "EMBEDDING",
|
|
@@ -7627,9 +7721,9 @@ function tracedEmbedContent(original) {
|
|
|
7627
7721
|
"neatlogs.embedding.model_name": opts?.model ?? "",
|
|
7628
7722
|
"neatlogs.embedding.text": safeStringify6(opts?.contents ?? "")
|
|
7629
7723
|
}
|
|
7630
|
-
},
|
|
7631
|
-
const ctx =
|
|
7632
|
-
const result =
|
|
7724
|
+
}, import_api13.context.active());
|
|
7725
|
+
const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
|
|
7726
|
+
const result = import_api13.context.with(ctx, () => original(opts, ...rest));
|
|
7633
7727
|
return Promise.resolve(result).then(
|
|
7634
7728
|
(response) => {
|
|
7635
7729
|
const embeddings = response?.embeddings;
|
|
@@ -7638,7 +7732,7 @@ function tracedEmbedContent(original) {
|
|
|
7638
7732
|
const vals = embeddings[0]?.values;
|
|
7639
7733
|
if (Array.isArray(vals)) span2.setAttribute("neatlogs.embedding.dimensions", vals.length);
|
|
7640
7734
|
}
|
|
7641
|
-
span2.setStatus({ code:
|
|
7735
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.OK });
|
|
7642
7736
|
span2.end();
|
|
7643
7737
|
return response;
|
|
7644
7738
|
},
|
|
@@ -7651,7 +7745,7 @@ function tracedEmbedContent(original) {
|
|
|
7651
7745
|
}
|
|
7652
7746
|
function tracedCountTokens(original) {
|
|
7653
7747
|
return function(opts, ...rest) {
|
|
7654
|
-
const tracer =
|
|
7748
|
+
const tracer = getProviderTracer(TRACER_NAME6);
|
|
7655
7749
|
const span2 = tracer.startSpan("vertex_ai.models.count_tokens", {
|
|
7656
7750
|
attributes: {
|
|
7657
7751
|
"neatlogs.span.kind": "LLM",
|
|
@@ -7659,13 +7753,13 @@ function tracedCountTokens(original) {
|
|
|
7659
7753
|
"neatlogs.llm.task": "count_tokens",
|
|
7660
7754
|
"neatlogs.llm.model_name": opts?.model ?? ""
|
|
7661
7755
|
}
|
|
7662
|
-
},
|
|
7663
|
-
const ctx =
|
|
7664
|
-
const result =
|
|
7756
|
+
}, import_api13.context.active());
|
|
7757
|
+
const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
|
|
7758
|
+
const result = import_api13.context.with(ctx, () => original(opts, ...rest));
|
|
7665
7759
|
return Promise.resolve(result).then(
|
|
7666
7760
|
(response) => {
|
|
7667
7761
|
if (response?.totalTokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", response.totalTokens);
|
|
7668
|
-
span2.setStatus({ code:
|
|
7762
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.OK });
|
|
7669
7763
|
span2.end();
|
|
7670
7764
|
return response;
|
|
7671
7765
|
},
|
|
@@ -7678,7 +7772,7 @@ function tracedCountTokens(original) {
|
|
|
7678
7772
|
}
|
|
7679
7773
|
function tracedGenerateContent(original, isStream) {
|
|
7680
7774
|
return function(opts, ...rest) {
|
|
7681
|
-
const tracer =
|
|
7775
|
+
const tracer = getProviderTracer(TRACER_NAME6);
|
|
7682
7776
|
const model = opts?.model ?? "";
|
|
7683
7777
|
const span2 = tracer.startSpan("vertex_ai.models.generate_content", {
|
|
7684
7778
|
attributes: {
|
|
@@ -7688,10 +7782,10 @@ function tracedGenerateContent(original, isStream) {
|
|
|
7688
7782
|
"neatlogs.llm.model_name": model,
|
|
7689
7783
|
"neatlogs.llm.is_streaming": isStream
|
|
7690
7784
|
}
|
|
7691
|
-
},
|
|
7785
|
+
}, import_api13.context.active());
|
|
7692
7786
|
setInputAttributes(span2, opts);
|
|
7693
|
-
const ctx =
|
|
7694
|
-
const result =
|
|
7787
|
+
const ctx = import_api13.trace.setSpan(import_api13.context.active(), span2);
|
|
7788
|
+
const result = import_api13.context.with(ctx, () => original(opts, ...rest));
|
|
7695
7789
|
return Promise.resolve(result).then(
|
|
7696
7790
|
(response) => {
|
|
7697
7791
|
if (isStream) {
|
|
@@ -7838,7 +7932,7 @@ function finalizeStreamChunks3(span2, chunks) {
|
|
|
7838
7932
|
}
|
|
7839
7933
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
7840
7934
|
setUsage(span2, usage);
|
|
7841
|
-
span2.setStatus({ code:
|
|
7935
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.OK });
|
|
7842
7936
|
span2.end();
|
|
7843
7937
|
}
|
|
7844
7938
|
function finalizeResponse(span2, response) {
|
|
@@ -7864,7 +7958,7 @@ function finalizeResponse(span2, response) {
|
|
|
7864
7958
|
span2.setAttribute("neatlogs.llm.output_messages.0.content", textParts.join(""));
|
|
7865
7959
|
}
|
|
7866
7960
|
setUsage(span2, response?.usageMetadata);
|
|
7867
|
-
span2.setStatus({ code:
|
|
7961
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.OK });
|
|
7868
7962
|
span2.end();
|
|
7869
7963
|
}
|
|
7870
7964
|
function setUsage(span2, usage) {
|
|
@@ -7884,21 +7978,21 @@ function safeStringify6(value) {
|
|
|
7884
7978
|
}
|
|
7885
7979
|
function recordError4(span2, err) {
|
|
7886
7980
|
if (err instanceof Error) {
|
|
7887
|
-
span2.setStatus({ code:
|
|
7981
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.ERROR, message: err.message });
|
|
7888
7982
|
span2.recordException(err);
|
|
7889
7983
|
} else {
|
|
7890
|
-
span2.setStatus({ code:
|
|
7984
|
+
span2.setStatus({ code: import_api13.SpanStatusCode.ERROR, message: String(err) });
|
|
7891
7985
|
}
|
|
7892
7986
|
span2.end();
|
|
7893
7987
|
}
|
|
7894
7988
|
|
|
7895
7989
|
// src/bedrock.ts
|
|
7896
|
-
var
|
|
7990
|
+
var import_api14 = require("@opentelemetry/api");
|
|
7897
7991
|
var TRACER_NAME7 = "neatlogs.bedrock";
|
|
7898
7992
|
var PROVIDER3 = "bedrock";
|
|
7899
7993
|
function traceTool5(name, fn) {
|
|
7900
7994
|
return async function tracedTool(args) {
|
|
7901
|
-
const tracer =
|
|
7995
|
+
const tracer = getProviderTracer(TRACER_NAME7);
|
|
7902
7996
|
return tracer.startActiveSpan(
|
|
7903
7997
|
`tool.${name}`,
|
|
7904
7998
|
{
|
|
@@ -7908,12 +8002,12 @@ function traceTool5(name, fn) {
|
|
|
7908
8002
|
"input.value": safeStringify7(args)
|
|
7909
8003
|
}
|
|
7910
8004
|
},
|
|
7911
|
-
|
|
8005
|
+
import_api14.context.active(),
|
|
7912
8006
|
async (span2) => {
|
|
7913
8007
|
try {
|
|
7914
8008
|
const result = await fn(args);
|
|
7915
8009
|
span2.setAttribute("output.value", safeStringify7(result));
|
|
7916
|
-
span2.setStatus({ code:
|
|
8010
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
7917
8011
|
return result;
|
|
7918
8012
|
} catch (err) {
|
|
7919
8013
|
recordError5(span2, err);
|
|
@@ -7959,7 +8053,7 @@ function vendorFromModel(modelId) {
|
|
|
7959
8053
|
return vendor || "bedrock";
|
|
7960
8054
|
}
|
|
7961
8055
|
function startSpan(name, modelId, isStream) {
|
|
7962
|
-
return
|
|
8056
|
+
return getProviderTracer(TRACER_NAME7).startSpan(name, {
|
|
7963
8057
|
attributes: {
|
|
7964
8058
|
"neatlogs.span.kind": "LLM",
|
|
7965
8059
|
"neatlogs.llm.provider": PROVIDER3,
|
|
@@ -7967,7 +8061,7 @@ function startSpan(name, modelId, isStream) {
|
|
|
7967
8061
|
"neatlogs.llm.model_name": String(modelId ?? ""),
|
|
7968
8062
|
"neatlogs.llm.is_streaming": isStream
|
|
7969
8063
|
}
|
|
7970
|
-
},
|
|
8064
|
+
}, import_api14.context.active());
|
|
7971
8065
|
}
|
|
7972
8066
|
function tracedConverse(originalSend, command, input, rest, isStream) {
|
|
7973
8067
|
const span2 = startSpan(
|
|
@@ -7976,8 +8070,8 @@ function tracedConverse(originalSend, command, input, rest, isStream) {
|
|
|
7976
8070
|
isStream
|
|
7977
8071
|
);
|
|
7978
8072
|
setConverseInput(span2, input);
|
|
7979
|
-
const ctx =
|
|
7980
|
-
const promise =
|
|
8073
|
+
const ctx = import_api14.trace.setSpan(import_api14.context.active(), span2);
|
|
8074
|
+
const promise = import_api14.context.with(ctx, () => originalSend(command, ...rest));
|
|
7981
8075
|
return promise.then(
|
|
7982
8076
|
(response) => {
|
|
7983
8077
|
if (isStream) {
|
|
@@ -8057,7 +8151,7 @@ function finalizeConverse(span2, response) {
|
|
|
8057
8151
|
}
|
|
8058
8152
|
if (response?.stopReason) span2.setAttribute("neatlogs.llm.finish_reason", String(response.stopReason));
|
|
8059
8153
|
setConverseUsage(span2, response?.usage);
|
|
8060
|
-
span2.setStatus({ code:
|
|
8154
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8061
8155
|
span2.end();
|
|
8062
8156
|
}
|
|
8063
8157
|
function setConverseUsage(span2, usage) {
|
|
@@ -8071,7 +8165,7 @@ function setConverseUsage(span2, usage) {
|
|
|
8071
8165
|
function wrapConverseStream(response, span2) {
|
|
8072
8166
|
const stream = response?.stream;
|
|
8073
8167
|
if (!stream || typeof stream[Symbol.asyncIterator] !== "function") {
|
|
8074
|
-
span2.setStatus({ code:
|
|
8168
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8075
8169
|
span2.end();
|
|
8076
8170
|
return response;
|
|
8077
8171
|
}
|
|
@@ -8139,7 +8233,7 @@ function finalizeConverseStream(span2, textParts, toolCalls, finishReason, usage
|
|
|
8139
8233
|
}
|
|
8140
8234
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8141
8235
|
setConverseUsage(span2, usage);
|
|
8142
|
-
span2.setStatus({ code:
|
|
8236
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8143
8237
|
span2.end();
|
|
8144
8238
|
}
|
|
8145
8239
|
function isEmbeddingModel(modelId) {
|
|
@@ -8151,13 +8245,13 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8151
8245
|
const bodyIn = decodeBody(input?.body);
|
|
8152
8246
|
let span2;
|
|
8153
8247
|
if (isEmbedding) {
|
|
8154
|
-
span2 =
|
|
8248
|
+
span2 = getProviderTracer(TRACER_NAME7).startSpan("bedrock.invoke_model", {
|
|
8155
8249
|
attributes: {
|
|
8156
8250
|
"neatlogs.span.kind": "EMBEDDING",
|
|
8157
8251
|
"neatlogs.llm.provider": PROVIDER3,
|
|
8158
8252
|
"neatlogs.embedding.model_name": String(input?.modelId ?? "")
|
|
8159
8253
|
}
|
|
8160
|
-
},
|
|
8254
|
+
}, import_api14.context.active());
|
|
8161
8255
|
const text = bodyIn?.inputText ?? bodyIn?.texts ?? bodyIn?.input_text;
|
|
8162
8256
|
if (text) {
|
|
8163
8257
|
span2.setAttribute("neatlogs.embedding.text", typeof text === "string" ? text : safeStringify7(text));
|
|
@@ -8170,8 +8264,8 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8170
8264
|
);
|
|
8171
8265
|
setInvokeInput(span2, vendor, bodyIn);
|
|
8172
8266
|
}
|
|
8173
|
-
const ctx =
|
|
8174
|
-
const promise =
|
|
8267
|
+
const ctx = import_api14.trace.setSpan(import_api14.context.active(), span2);
|
|
8268
|
+
const promise = import_api14.context.with(ctx, () => originalSend(command, ...rest));
|
|
8175
8269
|
return promise.then(
|
|
8176
8270
|
(response) => {
|
|
8177
8271
|
if (isStream) {
|
|
@@ -8184,7 +8278,7 @@ function tracedInvokeModel(originalSend, command, input, rest, isStream) {
|
|
|
8184
8278
|
finalizeInvoke(span2, vendor, decodeBody(response?.body));
|
|
8185
8279
|
}
|
|
8186
8280
|
} catch {
|
|
8187
|
-
span2.setStatus({ code:
|
|
8281
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8188
8282
|
span2.end();
|
|
8189
8283
|
}
|
|
8190
8284
|
return response;
|
|
@@ -8209,7 +8303,7 @@ function finalizeInvokeEmbedding(span2, body) {
|
|
|
8209
8303
|
span2.setAttribute("neatlogs.llm.token_count.prompt", body.inputTextTokenCount);
|
|
8210
8304
|
span2.setAttribute("neatlogs.embedding.token_count", body.inputTextTokenCount);
|
|
8211
8305
|
}
|
|
8212
|
-
span2.setStatus({ code:
|
|
8306
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8213
8307
|
span2.end();
|
|
8214
8308
|
}
|
|
8215
8309
|
function decodeBody(body) {
|
|
@@ -8317,13 +8411,13 @@ function finalizeInvoke(span2, vendor, body) {
|
|
|
8317
8411
|
span2.setAttribute("neatlogs.llm.token_count.total", promptTokens + completionTokens);
|
|
8318
8412
|
}
|
|
8319
8413
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8320
|
-
span2.setStatus({ code:
|
|
8414
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8321
8415
|
span2.end();
|
|
8322
8416
|
}
|
|
8323
8417
|
function wrapInvokeStream(response, span2, vendor) {
|
|
8324
8418
|
const body = response?.body;
|
|
8325
8419
|
if (!body || typeof body[Symbol.asyncIterator] !== "function") {
|
|
8326
|
-
span2.setStatus({ code:
|
|
8420
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8327
8421
|
span2.end();
|
|
8328
8422
|
return response;
|
|
8329
8423
|
}
|
|
@@ -8341,7 +8435,7 @@ function wrapInvokeStream(response, span2, vendor) {
|
|
|
8341
8435
|
if (promptTokens != null) span2.setAttribute("neatlogs.llm.token_count.prompt", promptTokens);
|
|
8342
8436
|
if (completionTokens != null) span2.setAttribute("neatlogs.llm.token_count.completion", completionTokens);
|
|
8343
8437
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
8344
|
-
span2.setStatus({ code:
|
|
8438
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.OK });
|
|
8345
8439
|
span2.end();
|
|
8346
8440
|
};
|
|
8347
8441
|
const wrappedBody = {
|
|
@@ -8394,16 +8488,16 @@ function safeStringify7(value) {
|
|
|
8394
8488
|
}
|
|
8395
8489
|
function recordError5(span2, err) {
|
|
8396
8490
|
if (err instanceof Error) {
|
|
8397
|
-
span2.setStatus({ code:
|
|
8491
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.ERROR, message: err.message });
|
|
8398
8492
|
span2.recordException(err);
|
|
8399
8493
|
} else {
|
|
8400
|
-
span2.setStatus({ code:
|
|
8494
|
+
span2.setStatus({ code: import_api14.SpanStatusCode.ERROR, message: String(err) });
|
|
8401
8495
|
}
|
|
8402
8496
|
span2.end();
|
|
8403
8497
|
}
|
|
8404
8498
|
|
|
8405
8499
|
// src/langchain.ts
|
|
8406
|
-
var
|
|
8500
|
+
var import_api15 = require("@opentelemetry/api");
|
|
8407
8501
|
var TRACER_NAME8 = "neatlogs.langchain";
|
|
8408
8502
|
function langchainHandler(opts) {
|
|
8409
8503
|
return new NeatlogsCallbackHandler(opts);
|
|
@@ -8411,16 +8505,42 @@ function langchainHandler(opts) {
|
|
|
8411
8505
|
var NeatlogsCallbackHandler = class {
|
|
8412
8506
|
name = "neatlogs";
|
|
8413
8507
|
_spans = /* @__PURE__ */ new Map();
|
|
8508
|
+
// Auto-root spans keyed by the run-id of the child that triggered them.
|
|
8509
|
+
_autoRoots = /* @__PURE__ */ new Map();
|
|
8414
8510
|
_workflowName;
|
|
8415
8511
|
constructor(opts) {
|
|
8416
8512
|
this._workflowName = opts?.workflowName;
|
|
8417
8513
|
}
|
|
8514
|
+
// --- Self-rooting ----------------------------------------------------------
|
|
8515
|
+
//
|
|
8516
|
+
// A LangChain run can begin with ANY callback. When it begins with a non-root
|
|
8517
|
+
// kind (a bare `llm.invoke()` fires handleChatModelStart/handleLLMStart with no
|
|
8518
|
+
// chain above it; a standalone tool/retriever similarly), the span we create is
|
|
8519
|
+
// parentless and non-root -> the backend can't anchor the trace and it never
|
|
8520
|
+
// renders. Open a WORKFLOW root transparently in that case so just adding the
|
|
8521
|
+
// handler yields a complete trace. A top-level CHAIN is already root-eligible.
|
|
8522
|
+
_startCtx(parentRunId, runId, kind) {
|
|
8523
|
+
const parentSpan = parentRunId ? this._spans.get(parentRunId) : void 0;
|
|
8524
|
+
if (parentSpan) {
|
|
8525
|
+
return import_api15.trace.setSpan(import_api15.context.active(), parentSpan);
|
|
8526
|
+
}
|
|
8527
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8528
|
+
const { root, ctx } = maybeOpenAutoRoot(tracer, kind, import_api15.context.active());
|
|
8529
|
+
if (root) this._autoRoots.set(runId, root);
|
|
8530
|
+
return ctx;
|
|
8531
|
+
}
|
|
8532
|
+
_endAutoRoot(runId) {
|
|
8533
|
+
const root = this._autoRoots.get(runId);
|
|
8534
|
+
if (root) {
|
|
8535
|
+
endAutoRoot(root);
|
|
8536
|
+
this._autoRoots.delete(runId);
|
|
8537
|
+
}
|
|
8538
|
+
}
|
|
8418
8539
|
// --- Chain/Graph callbacks ---
|
|
8419
8540
|
async handleChainStart(serialized, inputs, runId, parentRunId, tags, metadata) {
|
|
8420
|
-
const tracer =
|
|
8541
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8421
8542
|
const name = serialized?.name ?? serialized?.id?.at(-1) ?? "chain";
|
|
8422
|
-
const
|
|
8423
|
-
const parentCtx = parentSpan ? import_api14.trace.setSpan(import_api14.context.active(), parentSpan) : import_api14.context.active();
|
|
8543
|
+
const parentCtx = this._startCtx(parentRunId, runId, "chain");
|
|
8424
8544
|
const attrs = {
|
|
8425
8545
|
"neatlogs.span.kind": "CHAIN",
|
|
8426
8546
|
"neatlogs.chain.name": name
|
|
@@ -8435,24 +8555,25 @@ var NeatlogsCallbackHandler = class {
|
|
|
8435
8555
|
const span2 = this._spans.get(runId);
|
|
8436
8556
|
if (!span2) return;
|
|
8437
8557
|
if (outputs) span2.setAttribute("output.value", safeStringify8(outputs));
|
|
8438
|
-
span2.setStatus({ code:
|
|
8558
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
8439
8559
|
span2.end();
|
|
8440
8560
|
this._spans.delete(runId);
|
|
8561
|
+
this._endAutoRoot(runId);
|
|
8441
8562
|
}
|
|
8442
8563
|
async handleChainError(error, runId) {
|
|
8443
8564
|
const span2 = this._spans.get(runId);
|
|
8444
8565
|
if (!span2) return;
|
|
8445
|
-
span2.setStatus({ code:
|
|
8566
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: error.message });
|
|
8446
8567
|
span2.recordException(error);
|
|
8447
8568
|
span2.end();
|
|
8448
8569
|
this._spans.delete(runId);
|
|
8570
|
+
this._endAutoRoot(runId);
|
|
8449
8571
|
}
|
|
8450
8572
|
// --- LLM callbacks ---
|
|
8451
8573
|
async handleLLMStart(serialized, prompts, runId, parentRunId, extraParams) {
|
|
8452
|
-
const tracer =
|
|
8574
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8453
8575
|
const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
|
|
8454
|
-
const
|
|
8455
|
-
const parentCtx = parentSpan ? import_api14.trace.setSpan(import_api14.context.active(), parentSpan) : import_api14.context.active();
|
|
8576
|
+
const parentCtx = this._startCtx(parentRunId, runId, "llm");
|
|
8456
8577
|
const attrs = {
|
|
8457
8578
|
"neatlogs.span.kind": "LLM",
|
|
8458
8579
|
"neatlogs.llm.provider": detectProvider(model),
|
|
@@ -8472,10 +8593,9 @@ var NeatlogsCallbackHandler = class {
|
|
|
8472
8593
|
this._spans.set(runId, span2);
|
|
8473
8594
|
}
|
|
8474
8595
|
async handleChatModelStart(serialized, messages, runId, parentRunId, extraParams) {
|
|
8475
|
-
const tracer =
|
|
8596
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8476
8597
|
const model = serialized?.kwargs?.model_name ?? serialized?.kwargs?.model ?? serialized?.name ?? "";
|
|
8477
|
-
const
|
|
8478
|
-
const parentCtx = parentSpan ? import_api14.trace.setSpan(import_api14.context.active(), parentSpan) : import_api14.context.active();
|
|
8598
|
+
const parentCtx = this._startCtx(parentRunId, runId, "llm");
|
|
8479
8599
|
const attrs = {
|
|
8480
8600
|
"neatlogs.span.kind": "LLM",
|
|
8481
8601
|
"neatlogs.llm.provider": detectProvider(model),
|
|
@@ -8533,26 +8653,27 @@ var NeatlogsCallbackHandler = class {
|
|
|
8533
8653
|
span2.setAttribute("neatlogs.llm.token_count.total", usage.totalTokens ?? usage.total_tokens);
|
|
8534
8654
|
}
|
|
8535
8655
|
}
|
|
8536
|
-
span2.setStatus({ code:
|
|
8656
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
8537
8657
|
span2.end();
|
|
8538
8658
|
this._spans.delete(runId);
|
|
8659
|
+
this._endAutoRoot(runId);
|
|
8539
8660
|
}
|
|
8540
8661
|
async handleLLMNewToken(_token, _idx, _runId) {
|
|
8541
8662
|
}
|
|
8542
8663
|
async handleLLMError(error, runId) {
|
|
8543
8664
|
const span2 = this._spans.get(runId);
|
|
8544
8665
|
if (!span2) return;
|
|
8545
|
-
span2.setStatus({ code:
|
|
8666
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: error.message });
|
|
8546
8667
|
span2.recordException(error);
|
|
8547
8668
|
span2.end();
|
|
8548
8669
|
this._spans.delete(runId);
|
|
8670
|
+
this._endAutoRoot(runId);
|
|
8549
8671
|
}
|
|
8550
8672
|
// --- Tool callbacks ---
|
|
8551
8673
|
async handleToolStart(serialized, input, runId, parentRunId, _tags, _metadata, runName, toolCallId) {
|
|
8552
|
-
const tracer =
|
|
8674
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8553
8675
|
const name = serialized?.name || runName || (Array.isArray(serialized?.id) ? serialized.id[serialized.id.length - 1] : void 0) || "tool";
|
|
8554
|
-
const
|
|
8555
|
-
const parentCtx = parentSpan ? import_api14.trace.setSpan(import_api14.context.active(), parentSpan) : import_api14.context.active();
|
|
8676
|
+
const parentCtx = this._startCtx(parentRunId, runId, "tool");
|
|
8556
8677
|
const attrs = {
|
|
8557
8678
|
"neatlogs.span.kind": "TOOL",
|
|
8558
8679
|
"neatlogs.tool.name": name,
|
|
@@ -8566,24 +8687,25 @@ var NeatlogsCallbackHandler = class {
|
|
|
8566
8687
|
const span2 = this._spans.get(runId);
|
|
8567
8688
|
if (!span2) return;
|
|
8568
8689
|
span2.setAttribute("output.value", String(output));
|
|
8569
|
-
span2.setStatus({ code:
|
|
8690
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
8570
8691
|
span2.end();
|
|
8571
8692
|
this._spans.delete(runId);
|
|
8693
|
+
this._endAutoRoot(runId);
|
|
8572
8694
|
}
|
|
8573
8695
|
async handleToolError(error, runId) {
|
|
8574
8696
|
const span2 = this._spans.get(runId);
|
|
8575
8697
|
if (!span2) return;
|
|
8576
|
-
span2.setStatus({ code:
|
|
8698
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: error.message });
|
|
8577
8699
|
span2.recordException(error);
|
|
8578
8700
|
span2.end();
|
|
8579
8701
|
this._spans.delete(runId);
|
|
8702
|
+
this._endAutoRoot(runId);
|
|
8580
8703
|
}
|
|
8581
8704
|
// --- Retriever callbacks ---
|
|
8582
8705
|
async handleRetrieverStart(serialized, query, runId, parentRunId) {
|
|
8583
|
-
const tracer =
|
|
8706
|
+
const tracer = import_api15.trace.getTracer(TRACER_NAME8);
|
|
8584
8707
|
const name = serialized?.name ?? "retriever";
|
|
8585
|
-
const
|
|
8586
|
-
const parentCtx = parentSpan ? import_api14.trace.setSpan(import_api14.context.active(), parentSpan) : import_api14.context.active();
|
|
8708
|
+
const parentCtx = this._startCtx(parentRunId, runId, "retriever");
|
|
8587
8709
|
const attrs = {
|
|
8588
8710
|
"neatlogs.span.kind": "RETRIEVER",
|
|
8589
8711
|
"neatlogs.retriever.name": name,
|
|
@@ -8604,17 +8726,19 @@ var NeatlogsCallbackHandler = class {
|
|
|
8604
8726
|
}
|
|
8605
8727
|
}
|
|
8606
8728
|
}
|
|
8607
|
-
span2.setStatus({ code:
|
|
8729
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.OK });
|
|
8608
8730
|
span2.end();
|
|
8609
8731
|
this._spans.delete(runId);
|
|
8732
|
+
this._endAutoRoot(runId);
|
|
8610
8733
|
}
|
|
8611
8734
|
async handleRetrieverError(error, runId) {
|
|
8612
8735
|
const span2 = this._spans.get(runId);
|
|
8613
8736
|
if (!span2) return;
|
|
8614
|
-
span2.setStatus({ code:
|
|
8737
|
+
span2.setStatus({ code: import_api15.SpanStatusCode.ERROR, message: error.message });
|
|
8615
8738
|
span2.recordException(error);
|
|
8616
8739
|
span2.end();
|
|
8617
8740
|
this._spans.delete(runId);
|
|
8741
|
+
this._endAutoRoot(runId);
|
|
8618
8742
|
}
|
|
8619
8743
|
};
|
|
8620
8744
|
function detectProvider(model) {
|
|
@@ -8783,7 +8907,7 @@ function safeStringify9(value) {
|
|
|
8783
8907
|
}
|
|
8784
8908
|
|
|
8785
8909
|
// src/openai-agents.ts
|
|
8786
|
-
var
|
|
8910
|
+
var import_api16 = require("@opentelemetry/api");
|
|
8787
8911
|
var TRACER_NAME9 = "neatlogs.openai_agents";
|
|
8788
8912
|
function openaiAgentsProcessor() {
|
|
8789
8913
|
return new NeatlogsTraceProcessor();
|
|
@@ -8793,13 +8917,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8793
8917
|
_startTimes = /* @__PURE__ */ new Map();
|
|
8794
8918
|
// The @openai/agents SDK passes a Trace object: { traceId, name, groupId, metadata }.
|
|
8795
8919
|
onTraceStart(traceData) {
|
|
8796
|
-
const tracer =
|
|
8920
|
+
const tracer = import_api16.trace.getTracer(TRACER_NAME9);
|
|
8797
8921
|
const attrs = { "neatlogs.span.kind": "WORKFLOW" };
|
|
8798
8922
|
const workflowName = traceData?.name ?? traceData?.workflow_name;
|
|
8799
8923
|
if (workflowName) attrs["neatlogs.workflow.name"] = workflowName;
|
|
8800
8924
|
const traceId = traceData?.traceId ?? traceData?.trace_id;
|
|
8801
8925
|
if (traceId) attrs["neatlogs.agent.trace_id"] = String(traceId);
|
|
8802
|
-
const span2 = tracer.startSpan("openai_agents.trace", { attributes: attrs },
|
|
8926
|
+
const span2 = tracer.startSpan("openai_agents.trace", { attributes: attrs }, import_api16.context.active());
|
|
8803
8927
|
const key = String(traceId ?? `trace_${Date.now()}`);
|
|
8804
8928
|
this._spans.set(key, span2);
|
|
8805
8929
|
this._startTimes.set(key, Date.now());
|
|
@@ -8812,7 +8936,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8812
8936
|
if (startTime) {
|
|
8813
8937
|
span2.setAttribute("neatlogs.metrics.duration_ms", Date.now() - startTime);
|
|
8814
8938
|
}
|
|
8815
|
-
span2.setStatus({ code:
|
|
8939
|
+
span2.setStatus({ code: import_api16.SpanStatusCode.OK });
|
|
8816
8940
|
span2.end();
|
|
8817
8941
|
this._spans.delete(key);
|
|
8818
8942
|
this._startTimes.delete(key);
|
|
@@ -8820,13 +8944,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8820
8944
|
// The SDK passes a Span object: { type, spanId, traceId, parentId?, spanData: {...} }.
|
|
8821
8945
|
// The meaningful payload (type, name, input, output, usage, ...) lives in `spanData`.
|
|
8822
8946
|
onSpanStart(span2) {
|
|
8823
|
-
const tracer =
|
|
8947
|
+
const tracer = import_api16.trace.getTracer(TRACER_NAME9);
|
|
8824
8948
|
const data = span2?.spanData ?? span2 ?? {};
|
|
8825
8949
|
const spanType = data?.type ?? data?.span_type ?? span2?.type ?? "";
|
|
8826
8950
|
const spanId = String(span2?.spanId ?? span2?.span_id ?? data?.span_id ?? `span_${Date.now()}`);
|
|
8827
8951
|
const parentKey = String(span2?.parentId ?? span2?.traceId ?? span2?.trace_id ?? "");
|
|
8828
8952
|
const parentSpan = this._spans.get(parentKey);
|
|
8829
|
-
const parentCtx = parentSpan ?
|
|
8953
|
+
const parentCtx = parentSpan ? import_api16.trace.setSpan(import_api16.context.active(), parentSpan) : import_api16.context.active();
|
|
8830
8954
|
let otelSpan;
|
|
8831
8955
|
if (spanType === "agent" || spanType === "agent_run") {
|
|
8832
8956
|
const agentName = data?.name ?? data?.agent_name ?? "agent";
|
|
@@ -8935,13 +9059,13 @@ var NeatlogsTraceProcessor = class {
|
|
|
8935
9059
|
const error = data?.error ?? span2?.error;
|
|
8936
9060
|
if (error) {
|
|
8937
9061
|
if (error instanceof Error) {
|
|
8938
|
-
otelSpan.setStatus({ code:
|
|
9062
|
+
otelSpan.setStatus({ code: import_api16.SpanStatusCode.ERROR, message: error.message });
|
|
8939
9063
|
otelSpan.recordException(error);
|
|
8940
9064
|
} else {
|
|
8941
|
-
otelSpan.setStatus({ code:
|
|
9065
|
+
otelSpan.setStatus({ code: import_api16.SpanStatusCode.ERROR, message: String(error) });
|
|
8942
9066
|
}
|
|
8943
9067
|
} else {
|
|
8944
|
-
otelSpan.setStatus({ code:
|
|
9068
|
+
otelSpan.setStatus({ code: import_api16.SpanStatusCode.OK });
|
|
8945
9069
|
}
|
|
8946
9070
|
if (startTime) {
|
|
8947
9071
|
otelSpan.setAttribute("neatlogs.llm.metrics.duration_ms", Date.now() - startTime);
|
|
@@ -8952,7 +9076,7 @@ var NeatlogsTraceProcessor = class {
|
|
|
8952
9076
|
}
|
|
8953
9077
|
shutdown() {
|
|
8954
9078
|
for (const [, span2] of this._spans) {
|
|
8955
|
-
span2.setStatus({ code:
|
|
9079
|
+
span2.setStatus({ code: import_api16.SpanStatusCode.ERROR, message: "Processor shutdown before span completed" });
|
|
8956
9080
|
span2.end();
|
|
8957
9081
|
}
|
|
8958
9082
|
this._spans.clear();
|
|
@@ -8970,7 +9094,7 @@ function safeStringify10(value) {
|
|
|
8970
9094
|
}
|
|
8971
9095
|
|
|
8972
9096
|
// src/mastra-wrap.ts
|
|
8973
|
-
var
|
|
9097
|
+
var import_api17 = require("@opentelemetry/api");
|
|
8974
9098
|
var TRACER_NAME10 = "neatlogs.mastra";
|
|
8975
9099
|
var PATCH_FLAG2 = "_neatlogs_patched";
|
|
8976
9100
|
function wrapMastra(entity) {
|
|
@@ -9037,11 +9161,11 @@ function patchAgentMethod(agent, method, streaming) {
|
|
|
9037
9161
|
}
|
|
9038
9162
|
if (streaming) attrs["neatlogs.llm.is_streaming"] = true;
|
|
9039
9163
|
if (streaming) {
|
|
9040
|
-
const tracer =
|
|
9041
|
-
const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs },
|
|
9042
|
-
const ctx =
|
|
9164
|
+
const tracer = import_api17.trace.getTracer(TRACER_NAME10);
|
|
9165
|
+
const span2 = tracer.startSpan(`mastra.agent.${agentName}`, { attributes: attrs }, import_api17.context.active());
|
|
9166
|
+
const ctx = import_api17.trace.setSpan(import_api17.context.active(), span2);
|
|
9043
9167
|
try {
|
|
9044
|
-
const result = await
|
|
9168
|
+
const result = await import_api17.context.with(ctx, () => orig(input, opts));
|
|
9045
9169
|
return wrapStreamingOutput(result, span2, ctx);
|
|
9046
9170
|
} catch (err) {
|
|
9047
9171
|
recordError6(span2, err);
|
|
@@ -9245,7 +9369,7 @@ function wrapRootMastra(mastra) {
|
|
|
9245
9369
|
}
|
|
9246
9370
|
function wrapStreamingOutput(output, span2, ctx) {
|
|
9247
9371
|
if (!output) {
|
|
9248
|
-
span2.setStatus({ code:
|
|
9372
|
+
span2.setStatus({ code: import_api17.SpanStatusCode.OK });
|
|
9249
9373
|
span2.end();
|
|
9250
9374
|
return output;
|
|
9251
9375
|
}
|
|
@@ -9254,7 +9378,7 @@ function wrapStreamingOutput(output, span2, ctx) {
|
|
|
9254
9378
|
if (ended) return;
|
|
9255
9379
|
ended = true;
|
|
9256
9380
|
if (err) recordError6(span2, err);
|
|
9257
|
-
else span2.setStatus({ code:
|
|
9381
|
+
else span2.setStatus({ code: import_api17.SpanStatusCode.OK });
|
|
9258
9382
|
span2.end();
|
|
9259
9383
|
};
|
|
9260
9384
|
if (output.text && typeof output.text.then === "function") {
|
|
@@ -9345,7 +9469,7 @@ function rebindStreamContext(output, ctx) {
|
|
|
9345
9469
|
const origIterator = value[Symbol.asyncIterator].bind(value);
|
|
9346
9470
|
return {
|
|
9347
9471
|
[Symbol.asyncIterator]() {
|
|
9348
|
-
return
|
|
9472
|
+
return import_api17.context.with(ctx, () => origIterator());
|
|
9349
9473
|
}
|
|
9350
9474
|
};
|
|
9351
9475
|
}
|
|
@@ -9455,13 +9579,13 @@ function recordUsage(span2, usage) {
|
|
|
9455
9579
|
}
|
|
9456
9580
|
}
|
|
9457
9581
|
function withActiveSpan(name, attrs, fn) {
|
|
9458
|
-
const tracer =
|
|
9459
|
-
const span2 = tracer.startSpan(name, { attributes: attrs },
|
|
9460
|
-
const ctx =
|
|
9461
|
-
return
|
|
9582
|
+
const tracer = import_api17.trace.getTracer(TRACER_NAME10);
|
|
9583
|
+
const span2 = tracer.startSpan(name, { attributes: attrs }, import_api17.context.active());
|
|
9584
|
+
const ctx = import_api17.trace.setSpan(import_api17.context.active(), span2);
|
|
9585
|
+
return import_api17.context.with(ctx, async () => {
|
|
9462
9586
|
try {
|
|
9463
9587
|
const result = await fn(span2);
|
|
9464
|
-
span2.setStatus({ code:
|
|
9588
|
+
span2.setStatus({ code: import_api17.SpanStatusCode.OK });
|
|
9465
9589
|
return result;
|
|
9466
9590
|
} catch (err) {
|
|
9467
9591
|
recordError6(span2, err);
|
|
@@ -9496,15 +9620,15 @@ function safeStringify11(value) {
|
|
|
9496
9620
|
}
|
|
9497
9621
|
function recordError6(span2, err) {
|
|
9498
9622
|
if (err instanceof Error) {
|
|
9499
|
-
span2.setStatus({ code:
|
|
9623
|
+
span2.setStatus({ code: import_api17.SpanStatusCode.ERROR, message: err.message });
|
|
9500
9624
|
span2.recordException(err);
|
|
9501
9625
|
} else {
|
|
9502
|
-
span2.setStatus({ code:
|
|
9626
|
+
span2.setStatus({ code: import_api17.SpanStatusCode.ERROR, message: String(err) });
|
|
9503
9627
|
}
|
|
9504
9628
|
}
|
|
9505
9629
|
|
|
9506
9630
|
// src/pi-agent.ts
|
|
9507
|
-
var
|
|
9631
|
+
var import_api18 = require("@opentelemetry/api");
|
|
9508
9632
|
var TRACER_NAME11 = "neatlogs.pi-agent";
|
|
9509
9633
|
var PATCH_FLAG3 = "_neatlogs_patched";
|
|
9510
9634
|
function piAgentHooks(agent) {
|
|
@@ -9512,7 +9636,7 @@ function piAgentHooks(agent) {
|
|
|
9512
9636
|
const a = agent;
|
|
9513
9637
|
if (typeof a.subscribe !== "function") return agent;
|
|
9514
9638
|
const state = { toolSpans: /* @__PURE__ */ new Map(), inputMessages: [] };
|
|
9515
|
-
const tracer =
|
|
9639
|
+
const tracer = import_api18.trace.getTracer(TRACER_NAME11);
|
|
9516
9640
|
a.subscribe((event) => {
|
|
9517
9641
|
try {
|
|
9518
9642
|
handleEvent(tracer, state, event);
|
|
@@ -9528,10 +9652,10 @@ function handleEvent(tracer, state, event) {
|
|
|
9528
9652
|
const span2 = tracer.startSpan(
|
|
9529
9653
|
"pi_agent.run",
|
|
9530
9654
|
{ attributes: { "neatlogs.span.kind": "AGENT" } },
|
|
9531
|
-
|
|
9655
|
+
import_api18.context.active()
|
|
9532
9656
|
);
|
|
9533
9657
|
state.agentSpan = span2;
|
|
9534
|
-
state.agentCtx =
|
|
9658
|
+
state.agentCtx = import_api18.trace.setSpan(import_api18.context.active(), span2);
|
|
9535
9659
|
state.inputMessages = [];
|
|
9536
9660
|
break;
|
|
9537
9661
|
}
|
|
@@ -9550,7 +9674,7 @@ function handleEvent(tracer, state, event) {
|
|
|
9550
9674
|
break;
|
|
9551
9675
|
}
|
|
9552
9676
|
case "tool_execution_start": {
|
|
9553
|
-
const parent = state.agentCtx ??
|
|
9677
|
+
const parent = state.agentCtx ?? import_api18.context.active();
|
|
9554
9678
|
const span2 = tracer.startSpan(
|
|
9555
9679
|
`pi_agent.tool.${event.toolName ?? "tool"}`,
|
|
9556
9680
|
{
|
|
@@ -9572,10 +9696,10 @@ function handleEvent(tracer, state, event) {
|
|
|
9572
9696
|
span2.setAttribute("output.value", safeStringify12(event.result));
|
|
9573
9697
|
}
|
|
9574
9698
|
if (event.isError) {
|
|
9575
|
-
span2.setStatus({ code:
|
|
9699
|
+
span2.setStatus({ code: import_api18.SpanStatusCode.ERROR });
|
|
9576
9700
|
span2.setAttribute("neatlogs.tool.is_error", true);
|
|
9577
9701
|
} else {
|
|
9578
|
-
span2.setStatus({ code:
|
|
9702
|
+
span2.setStatus({ code: import_api18.SpanStatusCode.OK });
|
|
9579
9703
|
}
|
|
9580
9704
|
span2.end();
|
|
9581
9705
|
if (event.toolCallId) state.toolSpans.delete(event.toolCallId);
|
|
@@ -9594,7 +9718,7 @@ function handleEvent(tracer, state, event) {
|
|
|
9594
9718
|
if (firstUser) state.agentSpan.setAttribute("input.value", firstUser.content);
|
|
9595
9719
|
const finalText = lastAssistantText(event.messages);
|
|
9596
9720
|
if (finalText) state.agentSpan.setAttribute("output.value", finalText);
|
|
9597
|
-
state.agentSpan.setStatus({ code:
|
|
9721
|
+
state.agentSpan.setStatus({ code: import_api18.SpanStatusCode.OK });
|
|
9598
9722
|
state.agentSpan.end();
|
|
9599
9723
|
state.agentSpan = void 0;
|
|
9600
9724
|
state.agentCtx = void 0;
|
|
@@ -9646,13 +9770,13 @@ function emitLlmSpan(tracer, state, msg) {
|
|
|
9646
9770
|
if (usage.cacheRead) attrs["neatlogs.llm.token_count.cache_read"] = usage.cacheRead;
|
|
9647
9771
|
if (usage.cacheWrite) attrs["neatlogs.llm.token_count.cache_write"] = usage.cacheWrite;
|
|
9648
9772
|
}
|
|
9649
|
-
const parent = state.agentCtx ??
|
|
9773
|
+
const parent = state.agentCtx ?? import_api18.context.active();
|
|
9650
9774
|
const span2 = tracer.startSpan(
|
|
9651
9775
|
`pi_agent.llm.${msg.model || "model"}`,
|
|
9652
9776
|
{ attributes: attrs },
|
|
9653
9777
|
parent
|
|
9654
9778
|
);
|
|
9655
|
-
span2.setStatus({ code:
|
|
9779
|
+
span2.setStatus({ code: import_api18.SpanStatusCode.OK });
|
|
9656
9780
|
span2.end();
|
|
9657
9781
|
}
|
|
9658
9782
|
function splitAssistantContent(content) {
|
|
@@ -9713,7 +9837,7 @@ function safeStringify12(value) {
|
|
|
9713
9837
|
}
|
|
9714
9838
|
|
|
9715
9839
|
// src/claude-agent-sdk.ts
|
|
9716
|
-
var
|
|
9840
|
+
var import_api19 = require("@opentelemetry/api");
|
|
9717
9841
|
var TRACER_NAME12 = "neatlogs.claude_agent_sdk";
|
|
9718
9842
|
var ROOT_SCOPE = "__root__";
|
|
9719
9843
|
function wrapClaudeAgentSDK(sdk, options = {}) {
|
|
@@ -9734,13 +9858,13 @@ function wrapClaudeAgentSDK(sdk, options = {}) {
|
|
|
9734
9858
|
}
|
|
9735
9859
|
function wrapQuery(original, options) {
|
|
9736
9860
|
return function(params, ...rest) {
|
|
9737
|
-
const tracer =
|
|
9861
|
+
const tracer = import_api19.trace.getTracer(TRACER_NAME12);
|
|
9738
9862
|
const workflowName = options.workflowName ?? "claude_agent.query";
|
|
9739
9863
|
const promptRef = { text: "" };
|
|
9740
9864
|
const agentSpan = tracer.startSpan(
|
|
9741
9865
|
"claude_agent.query",
|
|
9742
9866
|
{ attributes: { "neatlogs.span.kind": "AGENT", "neatlogs.workflow.name": workflowName } },
|
|
9743
|
-
|
|
9867
|
+
import_api19.context.active()
|
|
9744
9868
|
);
|
|
9745
9869
|
const promptText = extractPromptText(params?.prompt);
|
|
9746
9870
|
if (promptText) {
|
|
@@ -9749,8 +9873,8 @@ function wrapQuery(original, options) {
|
|
|
9749
9873
|
} else if (params && isAsyncIterable(params.prompt)) {
|
|
9750
9874
|
params = { ...params, prompt: tapPromptStream(params.prompt, promptRef) };
|
|
9751
9875
|
}
|
|
9752
|
-
const agentCtx =
|
|
9753
|
-
const queryObj =
|
|
9876
|
+
const agentCtx = import_api19.trace.setSpan(import_api19.context.active(), agentSpan);
|
|
9877
|
+
const queryObj = import_api19.context.with(agentCtx, () => original(params, ...rest));
|
|
9754
9878
|
return instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRef);
|
|
9755
9879
|
};
|
|
9756
9880
|
}
|
|
@@ -9769,7 +9893,7 @@ async function* tapPromptStream(prompt, ref) {
|
|
|
9769
9893
|
function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRef) {
|
|
9770
9894
|
const originalAsyncIterator = queryObj?.[Symbol.asyncIterator]?.bind(queryObj);
|
|
9771
9895
|
if (!originalAsyncIterator) {
|
|
9772
|
-
agentSpan.setStatus({ code:
|
|
9896
|
+
agentSpan.setStatus({ code: import_api19.SpanStatusCode.OK });
|
|
9773
9897
|
agentSpan.end();
|
|
9774
9898
|
return queryObj;
|
|
9775
9899
|
}
|
|
@@ -9806,7 +9930,7 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9806
9930
|
if (status === "error") {
|
|
9807
9931
|
recordError7(agentSpan, err);
|
|
9808
9932
|
} else {
|
|
9809
|
-
agentSpan.setStatus({ code:
|
|
9933
|
+
agentSpan.setStatus({ code: import_api19.SpanStatusCode.OK });
|
|
9810
9934
|
agentSpan.end();
|
|
9811
9935
|
}
|
|
9812
9936
|
};
|
|
@@ -9817,7 +9941,7 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9817
9941
|
return {
|
|
9818
9942
|
async next() {
|
|
9819
9943
|
try {
|
|
9820
|
-
const result = await
|
|
9944
|
+
const result = await import_api19.context.with(agentCtx, () => iterator.next());
|
|
9821
9945
|
if (result.done) {
|
|
9822
9946
|
finalizeAgent("ok");
|
|
9823
9947
|
return result;
|
|
@@ -9848,7 +9972,7 @@ function instrumentQueryIterable(queryObj, agentSpan, agentCtx, tracer, promptRe
|
|
|
9848
9972
|
function closeScope(scope, status) {
|
|
9849
9973
|
try {
|
|
9850
9974
|
if (scope.finalText) scope.span.setAttribute("output.value", scope.finalText);
|
|
9851
|
-
scope.span.setStatus({ code: status === "ok" ?
|
|
9975
|
+
scope.span.setStatus({ code: status === "ok" ? import_api19.SpanStatusCode.OK : import_api19.SpanStatusCode.ERROR });
|
|
9852
9976
|
scope.span.end();
|
|
9853
9977
|
} catch {
|
|
9854
9978
|
}
|
|
@@ -9863,7 +9987,7 @@ function getScope(tracer, state, msg) {
|
|
|
9863
9987
|
flushAssistantTurn(tracer, root, state);
|
|
9864
9988
|
}
|
|
9865
9989
|
const parentToolSpan = state.toolSpans.get(parentId);
|
|
9866
|
-
const parentCtx = parentToolSpan ?
|
|
9990
|
+
const parentCtx = parentToolSpan ? import_api19.trace.setSpan(import_api19.context.active(), parentToolSpan) : state.scopes.get(ROOT_SCOPE).ctx;
|
|
9867
9991
|
const subType = msg?.subagent_type ? String(msg.subagent_type) : "subagent";
|
|
9868
9992
|
const attrs = {
|
|
9869
9993
|
"neatlogs.span.kind": "AGENT",
|
|
@@ -9873,7 +9997,7 @@ function getScope(tracer, state, msg) {
|
|
|
9873
9997
|
const span2 = tracer.startSpan(`claude_agent.subagent.${subType}`, { attributes: attrs }, parentCtx);
|
|
9874
9998
|
const scope = {
|
|
9875
9999
|
span: span2,
|
|
9876
|
-
ctx:
|
|
10000
|
+
ctx: import_api19.trace.setSpan(import_api19.context.active(), span2),
|
|
9877
10001
|
inputMessages: msg?.task_description ? [{ role: "user", content: String(msg.task_description) }] : [],
|
|
9878
10002
|
assistantBuffer: null,
|
|
9879
10003
|
finalText: "",
|
|
@@ -9997,7 +10121,7 @@ function flushAssistantTurn(tracer, scope, state) {
|
|
|
9997
10121
|
if (buf.stopReason) attrs["neatlogs.llm.finish_reason"] = String(buf.stopReason);
|
|
9998
10122
|
const span2 = tracer.startSpan(`claude_agent.llm.${model || "model"}`, { attributes: attrs }, scope.ctx);
|
|
9999
10123
|
if (buf.usage) setUsage2(span2, buf.usage);
|
|
10000
|
-
span2.setStatus({ code:
|
|
10124
|
+
span2.setStatus({ code: import_api19.SpanStatusCode.OK });
|
|
10001
10125
|
span2.end();
|
|
10002
10126
|
if (outText) scope.finalText = outText;
|
|
10003
10127
|
const turnParts = [];
|
|
@@ -10032,10 +10156,10 @@ function closeToolSpansFromUser(state, scope, msg) {
|
|
|
10032
10156
|
if (!span2) continue;
|
|
10033
10157
|
span2.setAttribute("output.value", outText);
|
|
10034
10158
|
if (block.is_error) {
|
|
10035
|
-
span2.setStatus({ code:
|
|
10159
|
+
span2.setStatus({ code: import_api19.SpanStatusCode.ERROR });
|
|
10036
10160
|
span2.setAttribute("neatlogs.tool.is_error", true);
|
|
10037
10161
|
} else {
|
|
10038
|
-
span2.setStatus({ code:
|
|
10162
|
+
span2.setStatus({ code: import_api19.SpanStatusCode.OK });
|
|
10039
10163
|
}
|
|
10040
10164
|
span2.end();
|
|
10041
10165
|
state.toolSpans.delete(id);
|
|
@@ -10082,16 +10206,16 @@ function safeStringify13(value) {
|
|
|
10082
10206
|
}
|
|
10083
10207
|
function recordError7(span2, err) {
|
|
10084
10208
|
if (err instanceof Error) {
|
|
10085
|
-
span2.setStatus({ code:
|
|
10209
|
+
span2.setStatus({ code: import_api19.SpanStatusCode.ERROR, message: err.message });
|
|
10086
10210
|
span2.recordException(err);
|
|
10087
10211
|
} else {
|
|
10088
|
-
span2.setStatus({ code:
|
|
10212
|
+
span2.setStatus({ code: import_api19.SpanStatusCode.ERROR, message: String(err) });
|
|
10089
10213
|
}
|
|
10090
10214
|
span2.end();
|
|
10091
10215
|
}
|
|
10092
10216
|
|
|
10093
10217
|
// src/openrouter-agent.ts
|
|
10094
|
-
var
|
|
10218
|
+
var import_api20 = require("@opentelemetry/api");
|
|
10095
10219
|
var TRACER_NAME13 = "neatlogs.openrouter_agent";
|
|
10096
10220
|
var PROVIDER4 = "openrouter";
|
|
10097
10221
|
function wrapOpenRouterAgent(client) {
|
|
@@ -10110,21 +10234,21 @@ function wrapOpenRouterAgent(client) {
|
|
|
10110
10234
|
function wrapCallModel(callModel) {
|
|
10111
10235
|
return function(clientArg, opts, ...rest) {
|
|
10112
10236
|
const span2 = startLlmSpan(opts);
|
|
10113
|
-
const ctx =
|
|
10114
|
-
const result =
|
|
10237
|
+
const ctx = import_api20.trace.setSpan(import_api20.context.active(), span2);
|
|
10238
|
+
const result = import_api20.context.with(ctx, () => callModel.call(this, clientArg, opts, ...rest));
|
|
10115
10239
|
return instrumentModelResult(result, span2);
|
|
10116
10240
|
};
|
|
10117
10241
|
}
|
|
10118
10242
|
function tracedCallModel(original) {
|
|
10119
10243
|
return function(opts, ...rest) {
|
|
10120
10244
|
const span2 = startLlmSpan(opts);
|
|
10121
|
-
const ctx =
|
|
10122
|
-
const result =
|
|
10245
|
+
const ctx = import_api20.trace.setSpan(import_api20.context.active(), span2);
|
|
10246
|
+
const result = import_api20.context.with(ctx, () => original(opts, ...rest));
|
|
10123
10247
|
return instrumentModelResult(result, span2);
|
|
10124
10248
|
};
|
|
10125
10249
|
}
|
|
10126
10250
|
function startLlmSpan(opts) {
|
|
10127
|
-
const tracer =
|
|
10251
|
+
const tracer = getProviderTracer(TRACER_NAME13);
|
|
10128
10252
|
const model = opts?.model ?? "";
|
|
10129
10253
|
const span2 = tracer.startSpan("openrouter.call_model", {
|
|
10130
10254
|
attributes: {
|
|
@@ -10133,7 +10257,7 @@ function startLlmSpan(opts) {
|
|
|
10133
10257
|
"neatlogs.llm.system": PROVIDER4,
|
|
10134
10258
|
"neatlogs.llm.model_name": model
|
|
10135
10259
|
}
|
|
10136
|
-
},
|
|
10260
|
+
}, import_api20.context.active());
|
|
10137
10261
|
const messages = Array.isArray(opts?.messages) ? opts.messages : Array.isArray(opts?.input) ? opts.input : [];
|
|
10138
10262
|
if (messages.length) {
|
|
10139
10263
|
messages.forEach((msg, i) => {
|
|
@@ -10185,7 +10309,7 @@ function startLlmSpan(opts) {
|
|
|
10185
10309
|
}
|
|
10186
10310
|
function instrumentModelResult(result, span2) {
|
|
10187
10311
|
if (!result || typeof result !== "object" && typeof result !== "function") {
|
|
10188
|
-
span2.setStatus({ code:
|
|
10312
|
+
span2.setStatus({ code: import_api20.SpanStatusCode.OK });
|
|
10189
10313
|
span2.end();
|
|
10190
10314
|
return result;
|
|
10191
10315
|
}
|
|
@@ -10196,7 +10320,7 @@ function instrumentModelResult(result, span2) {
|
|
|
10196
10320
|
try {
|
|
10197
10321
|
finalizeLlm(span2, resolved);
|
|
10198
10322
|
} catch {
|
|
10199
|
-
span2.setStatus({ code:
|
|
10323
|
+
span2.setStatus({ code: import_api20.SpanStatusCode.OK });
|
|
10200
10324
|
span2.end();
|
|
10201
10325
|
}
|
|
10202
10326
|
};
|
|
@@ -10299,7 +10423,7 @@ function finalizeLlm(span2, result) {
|
|
|
10299
10423
|
const finishReason = result?.finishReason ?? result?.finish_reason ?? result?.choices?.[0]?.finish_reason;
|
|
10300
10424
|
if (finishReason) span2.setAttribute("neatlogs.llm.finish_reason", String(finishReason));
|
|
10301
10425
|
setOpenResponsesUsage(span2, result);
|
|
10302
|
-
span2.setStatus({ code:
|
|
10426
|
+
span2.setStatus({ code: import_api20.SpanStatusCode.OK });
|
|
10303
10427
|
span2.end();
|
|
10304
10428
|
}
|
|
10305
10429
|
function extractOpenResponsesText(result) {
|
|
@@ -10325,197 +10449,623 @@ function safeStringify14(value) {
|
|
|
10325
10449
|
}
|
|
10326
10450
|
function recordError8(span2, err) {
|
|
10327
10451
|
if (err instanceof Error) {
|
|
10328
|
-
span2.setStatus({ code:
|
|
10452
|
+
span2.setStatus({ code: import_api20.SpanStatusCode.ERROR, message: err.message });
|
|
10329
10453
|
span2.recordException(err);
|
|
10330
10454
|
} else {
|
|
10331
|
-
span2.setStatus({ code:
|
|
10455
|
+
span2.setStatus({ code: import_api20.SpanStatusCode.ERROR, message: String(err) });
|
|
10332
10456
|
}
|
|
10333
10457
|
span2.end();
|
|
10334
10458
|
}
|
|
10335
10459
|
|
|
10336
|
-
// src/opencode-
|
|
10337
|
-
var
|
|
10338
|
-
var
|
|
10339
|
-
var
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
|
|
10353
|
-
|
|
10354
|
-
|
|
10355
|
-
|
|
10460
|
+
// src/opencode-trace-shipper.ts
|
|
10461
|
+
var import_protobufjs = __toESM(require("protobufjs"));
|
|
10462
|
+
var PACKAGE_NAME = "neatlogs.opencode";
|
|
10463
|
+
var OTLP_PROTO_JSON = {
|
|
10464
|
+
nested: {
|
|
10465
|
+
opentelemetry: {
|
|
10466
|
+
nested: {
|
|
10467
|
+
proto: {
|
|
10468
|
+
nested: {
|
|
10469
|
+
common: {
|
|
10470
|
+
nested: {
|
|
10471
|
+
v1: {
|
|
10472
|
+
nested: {
|
|
10473
|
+
AnyValue: {
|
|
10474
|
+
oneofs: {
|
|
10475
|
+
value: {
|
|
10476
|
+
oneof: [
|
|
10477
|
+
"stringValue",
|
|
10478
|
+
"boolValue",
|
|
10479
|
+
"intValue",
|
|
10480
|
+
"doubleValue",
|
|
10481
|
+
"arrayValue",
|
|
10482
|
+
"kvlistValue",
|
|
10483
|
+
"bytesValue"
|
|
10484
|
+
]
|
|
10485
|
+
}
|
|
10486
|
+
},
|
|
10487
|
+
fields: {
|
|
10488
|
+
stringValue: { type: "string", id: 1 },
|
|
10489
|
+
boolValue: { type: "bool", id: 2 },
|
|
10490
|
+
intValue: { type: "int64", id: 3 },
|
|
10491
|
+
doubleValue: { type: "double", id: 4 },
|
|
10492
|
+
arrayValue: { type: "ArrayValue", id: 5 },
|
|
10493
|
+
kvlistValue: { type: "KeyValueList", id: 6 },
|
|
10494
|
+
bytesValue: { type: "bytes", id: 7 }
|
|
10495
|
+
}
|
|
10496
|
+
},
|
|
10497
|
+
ArrayValue: { fields: { values: { rule: "repeated", type: "AnyValue", id: 1 } } },
|
|
10498
|
+
KeyValueList: { fields: { values: { rule: "repeated", type: "KeyValue", id: 1 } } },
|
|
10499
|
+
KeyValue: {
|
|
10500
|
+
fields: { key: { type: "string", id: 1 }, value: { type: "AnyValue", id: 2 } }
|
|
10501
|
+
},
|
|
10502
|
+
InstrumentationScope: {
|
|
10503
|
+
fields: { name: { type: "string", id: 1 }, version: { type: "string", id: 2 } }
|
|
10504
|
+
}
|
|
10505
|
+
}
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
10508
|
+
},
|
|
10509
|
+
resource: {
|
|
10510
|
+
nested: {
|
|
10511
|
+
v1: {
|
|
10512
|
+
nested: {
|
|
10513
|
+
Resource: {
|
|
10514
|
+
fields: {
|
|
10515
|
+
attributes: {
|
|
10516
|
+
rule: "repeated",
|
|
10517
|
+
type: "opentelemetry.proto.common.v1.KeyValue",
|
|
10518
|
+
id: 1
|
|
10519
|
+
}
|
|
10520
|
+
}
|
|
10521
|
+
}
|
|
10522
|
+
}
|
|
10523
|
+
}
|
|
10524
|
+
}
|
|
10525
|
+
},
|
|
10526
|
+
trace: {
|
|
10527
|
+
nested: {
|
|
10528
|
+
v1: {
|
|
10529
|
+
nested: {
|
|
10530
|
+
ResourceSpans: {
|
|
10531
|
+
fields: {
|
|
10532
|
+
resource: { type: "opentelemetry.proto.resource.v1.Resource", id: 1 },
|
|
10533
|
+
scopeSpans: { rule: "repeated", type: "ScopeSpans", id: 2 }
|
|
10534
|
+
}
|
|
10535
|
+
},
|
|
10536
|
+
ScopeSpans: {
|
|
10537
|
+
fields: {
|
|
10538
|
+
scope: { type: "opentelemetry.proto.common.v1.InstrumentationScope", id: 1 },
|
|
10539
|
+
spans: { rule: "repeated", type: "Span", id: 2 }
|
|
10540
|
+
}
|
|
10541
|
+
},
|
|
10542
|
+
Span: {
|
|
10543
|
+
fields: {
|
|
10544
|
+
traceId: { type: "bytes", id: 1 },
|
|
10545
|
+
spanId: { type: "bytes", id: 2 },
|
|
10546
|
+
traceState: { type: "string", id: 3 },
|
|
10547
|
+
parentSpanId: { type: "bytes", id: 4 },
|
|
10548
|
+
name: { type: "string", id: 5 },
|
|
10549
|
+
kind: { type: "SpanKind", id: 6 },
|
|
10550
|
+
startTimeUnixNano: { type: "fixed64", id: 7 },
|
|
10551
|
+
endTimeUnixNano: { type: "fixed64", id: 8 },
|
|
10552
|
+
attributes: {
|
|
10553
|
+
rule: "repeated",
|
|
10554
|
+
type: "opentelemetry.proto.common.v1.KeyValue",
|
|
10555
|
+
id: 9
|
|
10556
|
+
},
|
|
10557
|
+
droppedAttributesCount: { type: "uint32", id: 10 },
|
|
10558
|
+
status: { type: "Status", id: 15 }
|
|
10559
|
+
}
|
|
10560
|
+
},
|
|
10561
|
+
Status: {
|
|
10562
|
+
fields: { message: { type: "string", id: 2 }, code: { type: "StatusCode", id: 3 } }
|
|
10563
|
+
},
|
|
10564
|
+
StatusCode: {
|
|
10565
|
+
values: { STATUS_CODE_UNSET: 0, STATUS_CODE_OK: 1, STATUS_CODE_ERROR: 2 }
|
|
10566
|
+
},
|
|
10567
|
+
SpanKind: {
|
|
10568
|
+
values: {
|
|
10569
|
+
SPAN_KIND_UNSPECIFIED: 0,
|
|
10570
|
+
SPAN_KIND_INTERNAL: 1,
|
|
10571
|
+
SPAN_KIND_SERVER: 2,
|
|
10572
|
+
SPAN_KIND_CLIENT: 3,
|
|
10573
|
+
SPAN_KIND_PRODUCER: 4,
|
|
10574
|
+
SPAN_KIND_CONSUMER: 5
|
|
10575
|
+
}
|
|
10576
|
+
}
|
|
10577
|
+
}
|
|
10578
|
+
}
|
|
10579
|
+
}
|
|
10580
|
+
},
|
|
10581
|
+
collector: {
|
|
10582
|
+
nested: {
|
|
10583
|
+
trace: {
|
|
10584
|
+
nested: {
|
|
10585
|
+
v1: {
|
|
10586
|
+
nested: {
|
|
10587
|
+
ExportTraceServiceRequest: {
|
|
10588
|
+
fields: {
|
|
10589
|
+
resourceSpans: {
|
|
10590
|
+
rule: "repeated",
|
|
10591
|
+
type: "opentelemetry.proto.trace.v1.ResourceSpans",
|
|
10592
|
+
id: 1
|
|
10593
|
+
}
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
}
|
|
10597
|
+
}
|
|
10598
|
+
}
|
|
10599
|
+
}
|
|
10600
|
+
}
|
|
10601
|
+
}
|
|
10602
|
+
}
|
|
10603
|
+
}
|
|
10604
|
+
}
|
|
10605
|
+
}
|
|
10606
|
+
}
|
|
10607
|
+
};
|
|
10608
|
+
var protoRoot = import_protobufjs.default.Root.fromJSON(OTLP_PROTO_JSON);
|
|
10609
|
+
var ExportTraceServiceRequest = protoRoot.lookupType(
|
|
10610
|
+
"opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest"
|
|
10611
|
+
);
|
|
10612
|
+
var SpanStatusCode16 = { UNSET: 0, OK: 1, ERROR: 2 };
|
|
10613
|
+
function randomBytes3(length) {
|
|
10614
|
+
const out = new Uint8Array(length);
|
|
10615
|
+
const crypto2 = globalThis.crypto;
|
|
10616
|
+
if (crypto2 && typeof crypto2.getRandomValues === "function") {
|
|
10617
|
+
crypto2.getRandomValues(out);
|
|
10618
|
+
return out;
|
|
10619
|
+
}
|
|
10620
|
+
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
10621
|
+
return out;
|
|
10622
|
+
}
|
|
10623
|
+
function generateTraceId() {
|
|
10624
|
+
return randomBytes3(16);
|
|
10625
|
+
}
|
|
10626
|
+
function generateSpanId() {
|
|
10627
|
+
return randomBytes3(8);
|
|
10628
|
+
}
|
|
10629
|
+
function nowNanoString() {
|
|
10630
|
+
return (BigInt(Date.now()) * 1000000n).toString();
|
|
10631
|
+
}
|
|
10632
|
+
function msToNanoString(ms) {
|
|
10633
|
+
return (BigInt(Math.floor(ms)) * 1000000n).toString();
|
|
10634
|
+
}
|
|
10635
|
+
function attrStr(key, value) {
|
|
10636
|
+
if (value === void 0 || value === null) return void 0;
|
|
10637
|
+
return { key, value: { stringValue: String(value) } };
|
|
10638
|
+
}
|
|
10639
|
+
function attrInt(key, value) {
|
|
10640
|
+
if (value === void 0 || value === null || !Number.isFinite(value)) return void 0;
|
|
10641
|
+
return { key, value: { intValue: String(Math.trunc(value)) } };
|
|
10642
|
+
}
|
|
10643
|
+
function attrDouble(key, value) {
|
|
10644
|
+
if (value === void 0 || value === null || !Number.isFinite(value)) return void 0;
|
|
10645
|
+
return { key, value: { doubleValue: value } };
|
|
10646
|
+
}
|
|
10647
|
+
var TraceShipper = class {
|
|
10648
|
+
apiKey;
|
|
10649
|
+
endpoint;
|
|
10650
|
+
debug;
|
|
10651
|
+
maxRetries;
|
|
10652
|
+
workflowName;
|
|
10653
|
+
queue = [];
|
|
10654
|
+
prefix = "[neatlogs/opencode]";
|
|
10655
|
+
constructor(opts) {
|
|
10656
|
+
this.apiKey = opts.apiKey;
|
|
10657
|
+
this.endpoint = opts.endpoint.endsWith("/") ? opts.endpoint.slice(0, -1) : opts.endpoint;
|
|
10658
|
+
this.debug = !!opts.debug;
|
|
10659
|
+
this.maxRetries = opts.maxRetries ?? 3;
|
|
10660
|
+
this.workflowName = opts.workflowName || "";
|
|
10661
|
+
}
|
|
10662
|
+
enqueue(span2) {
|
|
10663
|
+
this.queue.push(span2);
|
|
10664
|
+
}
|
|
10665
|
+
get pending() {
|
|
10666
|
+
return this.queue.length;
|
|
10356
10667
|
}
|
|
10668
|
+
/**
|
|
10669
|
+
* Ship all queued spans in a single awaited POST. Resolves only once the HTTP
|
|
10670
|
+
* response is received (or all retries are exhausted) — so a short-lived host
|
|
10671
|
+
* can safely exit immediately after awaiting this.
|
|
10672
|
+
*/
|
|
10673
|
+
async flush() {
|
|
10674
|
+
if (this.queue.length === 0) return;
|
|
10675
|
+
if (!this.apiKey) {
|
|
10676
|
+
this.queue = [];
|
|
10677
|
+
return;
|
|
10678
|
+
}
|
|
10679
|
+
const spans = this.queue.splice(0);
|
|
10680
|
+
const payload = this.buildProtobuf(spans);
|
|
10681
|
+
const url = `${this.endpoint}/v1/traces`;
|
|
10682
|
+
if (this.debug) console.log(`${this.prefix} Shipping ${spans.length} spans to ${url}`);
|
|
10683
|
+
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
|
|
10684
|
+
try {
|
|
10685
|
+
const resp = await fetch(url, {
|
|
10686
|
+
method: "POST",
|
|
10687
|
+
headers: {
|
|
10688
|
+
"Content-Type": "application/x-protobuf",
|
|
10689
|
+
"x-api-key": this.apiKey
|
|
10690
|
+
},
|
|
10691
|
+
body: payload
|
|
10692
|
+
});
|
|
10693
|
+
if (resp.ok) {
|
|
10694
|
+
if (this.debug) console.log(`${this.prefix} Shipped ${spans.length} spans`);
|
|
10695
|
+
return;
|
|
10696
|
+
}
|
|
10697
|
+
if (resp.status === 401) {
|
|
10698
|
+
console.warn(`${this.prefix} Invalid API key (401) \u2014 dropping ${spans.length} spans`);
|
|
10699
|
+
return;
|
|
10700
|
+
}
|
|
10701
|
+
if (resp.status < 500 && resp.status !== 429) {
|
|
10702
|
+
if (this.debug) console.warn(`${this.prefix} HTTP ${resp.status} \u2014 dropping spans`);
|
|
10703
|
+
return;
|
|
10704
|
+
}
|
|
10705
|
+
} catch (err) {
|
|
10706
|
+
if (this.debug) {
|
|
10707
|
+
console.warn(
|
|
10708
|
+
`${this.prefix} Attempt ${attempt}/${this.maxRetries}: ${err.message}`
|
|
10709
|
+
);
|
|
10710
|
+
}
|
|
10711
|
+
}
|
|
10712
|
+
if (attempt < this.maxRetries) {
|
|
10713
|
+
await new Promise((r) => setTimeout(r, 500 * 2 ** (attempt - 1)));
|
|
10714
|
+
}
|
|
10715
|
+
}
|
|
10716
|
+
console.warn(`${this.prefix} Failed to ship ${spans.length} spans after ${this.maxRetries} attempts`);
|
|
10717
|
+
}
|
|
10718
|
+
buildProtobuf(spans) {
|
|
10719
|
+
const protoSpans = spans.map((span2) => ({
|
|
10720
|
+
traceId: span2.traceId,
|
|
10721
|
+
spanId: span2.spanId,
|
|
10722
|
+
parentSpanId: span2.parentSpanId || void 0,
|
|
10723
|
+
name: span2.name,
|
|
10724
|
+
kind: span2.kind,
|
|
10725
|
+
startTimeUnixNano: nanoToLong(span2.startTimeUnixNano),
|
|
10726
|
+
endTimeUnixNano: nanoToLong(span2.endTimeUnixNano),
|
|
10727
|
+
attributes: span2.attributes.map((a) => ({
|
|
10728
|
+
key: a.key,
|
|
10729
|
+
value: a.value.intValue !== void 0 ? { intValue: nanoToLong(a.value.intValue) } : a.value
|
|
10730
|
+
})),
|
|
10731
|
+
status: span2.status ? { code: span2.status.code, message: span2.status.message } : void 0
|
|
10732
|
+
}));
|
|
10733
|
+
const resourceAttributes = [
|
|
10734
|
+
{ key: "service.name", value: { stringValue: "neatlogs.opencode" } },
|
|
10735
|
+
{ key: "service.version", value: { stringValue: __version__ } }
|
|
10736
|
+
];
|
|
10737
|
+
if (this.workflowName) {
|
|
10738
|
+
resourceAttributes.push({
|
|
10739
|
+
key: "neatlogs.workflow_name",
|
|
10740
|
+
value: { stringValue: this.workflowName }
|
|
10741
|
+
});
|
|
10742
|
+
}
|
|
10743
|
+
const message = {
|
|
10744
|
+
resourceSpans: [
|
|
10745
|
+
{
|
|
10746
|
+
resource: { attributes: resourceAttributes },
|
|
10747
|
+
scopeSpans: [
|
|
10748
|
+
{
|
|
10749
|
+
scope: { name: PACKAGE_NAME, version: __version__ },
|
|
10750
|
+
spans: protoSpans
|
|
10751
|
+
}
|
|
10752
|
+
]
|
|
10753
|
+
}
|
|
10754
|
+
]
|
|
10755
|
+
};
|
|
10756
|
+
const errMsg = ExportTraceServiceRequest.verify(message);
|
|
10757
|
+
if (errMsg && this.debug) console.warn(`${this.prefix} Proto verify: ${errMsg}`);
|
|
10758
|
+
return ExportTraceServiceRequest.encode(ExportTraceServiceRequest.fromObject(message)).finish();
|
|
10759
|
+
}
|
|
10760
|
+
};
|
|
10761
|
+
function nanoToLong(nanoStr) {
|
|
10762
|
+
const big = BigInt(nanoStr);
|
|
10763
|
+
const low = Number(big & 0xffffffffn);
|
|
10764
|
+
const high = Number(big >> 32n & 0xffffffffn);
|
|
10765
|
+
return { low, high, unsigned: true };
|
|
10357
10766
|
}
|
|
10767
|
+
|
|
10768
|
+
// src/opencode-plugin.ts
|
|
10769
|
+
var DEFAULT_ENDPOINT = "https://staging-cloud.neatlogs.com";
|
|
10358
10770
|
var NeatlogsOpencodePlugin = async (_ctx) => {
|
|
10359
|
-
|
|
10360
|
-
const
|
|
10361
|
-
const
|
|
10771
|
+
const apiKey = (process.env.NEATLOGS_API_KEY ?? "").trim();
|
|
10772
|
+
const endpoint = (process.env.NEATLOGS_ENDPOINT ?? DEFAULT_ENDPOINT).trim();
|
|
10773
|
+
const workflowName = process.env.NEATLOGS_WORKFLOW_NAME || "opencode";
|
|
10362
10774
|
const captureSystemPrompt = String(process.env.NEATLOGS_CAPTURE_SYSTEM_PROMPT || "").toLowerCase() === "true";
|
|
10775
|
+
const debug = String(process.env.NEATLOGS_DEBUG || "").toLowerCase() === "true";
|
|
10776
|
+
const shipper = new TraceShipper({ apiKey, endpoint, workflowName, debug });
|
|
10777
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
10363
10778
|
function stateFor(sessionID) {
|
|
10364
10779
|
let s = sessions.get(sessionID);
|
|
10365
10780
|
if (!s) {
|
|
10366
|
-
s = {
|
|
10781
|
+
s = {
|
|
10782
|
+
traceId: generateTraceId(),
|
|
10783
|
+
toolStarts: /* @__PURE__ */ new Map(),
|
|
10784
|
+
outputParts: /* @__PURE__ */ new Map(),
|
|
10785
|
+
toolCalls: /* @__PURE__ */ new Map(),
|
|
10786
|
+
processed: /* @__PURE__ */ new Set(),
|
|
10787
|
+
currentInput: "",
|
|
10788
|
+
lastAssistantText: ""
|
|
10789
|
+
};
|
|
10367
10790
|
sessions.set(sessionID, s);
|
|
10368
10791
|
}
|
|
10369
10792
|
return s;
|
|
10370
10793
|
}
|
|
10794
|
+
function startRoot(st, sessionID) {
|
|
10795
|
+
if (st.rootSpan) return;
|
|
10796
|
+
st.rootSpan = {
|
|
10797
|
+
spanId: generateSpanId(),
|
|
10798
|
+
name: "opencode.session",
|
|
10799
|
+
startNano: nowNanoString(),
|
|
10800
|
+
attributes: [
|
|
10801
|
+
{ key: "neatlogs.span.kind", value: { stringValue: "AGENT" } },
|
|
10802
|
+
{ key: "neatlogs.agent.framework", value: { stringValue: "opencode" } },
|
|
10803
|
+
{ key: "neatlogs.conversation.id", value: { stringValue: sessionID } }
|
|
10804
|
+
]
|
|
10805
|
+
};
|
|
10806
|
+
}
|
|
10807
|
+
async function closeAndFlush(st, sessionID) {
|
|
10808
|
+
if (st.rootSpan) {
|
|
10809
|
+
const attrs = st.rootSpan.attributes.slice();
|
|
10810
|
+
setIO(attrs, "AGENT", st.currentInput || void 0, st.lastAssistantText || void 0);
|
|
10811
|
+
shipper.enqueue({
|
|
10812
|
+
traceId: st.traceId,
|
|
10813
|
+
spanId: st.rootSpan.spanId,
|
|
10814
|
+
name: st.rootSpan.name,
|
|
10815
|
+
kind: 1,
|
|
10816
|
+
startTimeUnixNano: st.rootSpan.startNano,
|
|
10817
|
+
endTimeUnixNano: nowNanoString(),
|
|
10818
|
+
attributes: attrs,
|
|
10819
|
+
status: { code: SpanStatusCode16.OK }
|
|
10820
|
+
});
|
|
10821
|
+
const m = nowNanoString();
|
|
10822
|
+
shipper.enqueue({
|
|
10823
|
+
traceId: st.traceId,
|
|
10824
|
+
spanId: generateSpanId(),
|
|
10825
|
+
parentSpanId: st.rootSpan.spanId,
|
|
10826
|
+
name: "neatlogs.trace.complete",
|
|
10827
|
+
kind: 1,
|
|
10828
|
+
startTimeUnixNano: m,
|
|
10829
|
+
endTimeUnixNano: m,
|
|
10830
|
+
attributes: [
|
|
10831
|
+
{ key: "neatlogs.trace.complete", value: { boolValue: true } },
|
|
10832
|
+
{ key: "neatlogs.internal", value: { boolValue: true } },
|
|
10833
|
+
{ key: "neatlogs.span.kind", value: { stringValue: "Neatlogs.INTERNAL" } }
|
|
10834
|
+
]
|
|
10835
|
+
});
|
|
10836
|
+
st.rootSpan = void 0;
|
|
10837
|
+
}
|
|
10838
|
+
await shipper.flush();
|
|
10839
|
+
void sessionID;
|
|
10840
|
+
}
|
|
10371
10841
|
return {
|
|
10372
|
-
/**
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10842
|
+
/** Fired when the user submits a prompt — open the turn's AGENT root. */
|
|
10843
|
+
"chat.message": async (_input, output) => {
|
|
10844
|
+
try {
|
|
10845
|
+
const sessionID = String(_input?.sessionID ?? output?.sessionID ?? "");
|
|
10846
|
+
if (!sessionID) return;
|
|
10847
|
+
const st = stateFor(sessionID);
|
|
10848
|
+
const parts = output?.parts ?? [];
|
|
10849
|
+
const text = Array.isArray(parts) ? parts.filter((p) => p?.type === "text" && typeof p.text === "string").map((p) => p.text).join("\n") : "";
|
|
10850
|
+
if (text) st.currentInput = text;
|
|
10851
|
+
startRoot(st, sessionID);
|
|
10852
|
+
} catch {
|
|
10853
|
+
}
|
|
10854
|
+
},
|
|
10855
|
+
/** Capture the system prompt (opt-in). */
|
|
10856
|
+
"experimental.chat.system.transform": async (_input, output) => {
|
|
10857
|
+
try {
|
|
10858
|
+
if (!captureSystemPrompt) return;
|
|
10859
|
+
const sessionID = String(_input?.sessionID ?? "");
|
|
10860
|
+
const parts = output?.system ?? output?.parts ?? output;
|
|
10861
|
+
const joined = Array.isArray(parts) ? parts.map((p) => typeof p === "string" ? p : p?.text ?? "").join("\n") : String(parts ?? "");
|
|
10862
|
+
if (sessionID && joined) stateFor(sessionID).systemPrompt = joined;
|
|
10863
|
+
} catch {
|
|
10864
|
+
}
|
|
10865
|
+
},
|
|
10866
|
+
/** Global event bus — message parts, assistant completions, session idle. */
|
|
10377
10867
|
event: async ({ event }) => {
|
|
10378
10868
|
try {
|
|
10379
|
-
await handleEvent2(
|
|
10869
|
+
await handleEvent2(shipper, sessions, stateFor, startRoot, closeAndFlush, event);
|
|
10380
10870
|
} catch {
|
|
10381
10871
|
}
|
|
10382
10872
|
},
|
|
10383
|
-
/**
|
|
10873
|
+
/** Tool start — record start time + args (span built atomically in `after`). */
|
|
10384
10874
|
"tool.execute.before": async (input, output) => {
|
|
10385
10875
|
try {
|
|
10386
|
-
const sessionID = input?.sessionID ?? "";
|
|
10387
|
-
|
|
10876
|
+
const sessionID = String(input?.sessionID ?? "");
|
|
10877
|
+
if (!sessionID) return;
|
|
10388
10878
|
const st = stateFor(sessionID);
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
}
|
|
10398
|
-
},
|
|
10399
|
-
import_api20.context.active()
|
|
10400
|
-
);
|
|
10401
|
-
if (callID) st.toolSpans.set(String(callID), span2);
|
|
10879
|
+
startRoot(st, sessionID);
|
|
10880
|
+
const callID = String(input?.callID ?? input?.tool ?? "");
|
|
10881
|
+
st.toolStarts.set(callID, {
|
|
10882
|
+
spanId: generateSpanId(),
|
|
10883
|
+
startNano: nowNanoString(),
|
|
10884
|
+
tool: String(input?.tool ?? "tool"),
|
|
10885
|
+
args: output?.args
|
|
10886
|
+
});
|
|
10402
10887
|
} catch {
|
|
10403
10888
|
}
|
|
10404
10889
|
},
|
|
10405
|
-
/**
|
|
10406
|
-
"tool.execute.after": async (input,
|
|
10890
|
+
/** Tool end — enqueue the completed TOOL span (parented to the turn root). */
|
|
10891
|
+
"tool.execute.after": async (input, result) => {
|
|
10407
10892
|
try {
|
|
10408
|
-
const sessionID = input?.sessionID ?? "";
|
|
10409
|
-
|
|
10893
|
+
const sessionID = String(input?.sessionID ?? "");
|
|
10894
|
+
if (!sessionID) return;
|
|
10410
10895
|
const st = stateFor(sessionID);
|
|
10411
|
-
const
|
|
10412
|
-
|
|
10413
|
-
if (
|
|
10414
|
-
|
|
10896
|
+
const callID = String(input?.callID ?? input?.tool ?? "");
|
|
10897
|
+
const start = st.toolStarts.get(callID);
|
|
10898
|
+
if (!start) return;
|
|
10899
|
+
st.toolStarts.delete(callID);
|
|
10900
|
+
const attrs = [
|
|
10901
|
+
{ key: "neatlogs.span.kind", value: { stringValue: "TOOL" } },
|
|
10902
|
+
{ key: "neatlogs.tool.name", value: { stringValue: start.tool } },
|
|
10903
|
+
{ key: "neatlogs.conversation.id", value: { stringValue: sessionID } }
|
|
10904
|
+
];
|
|
10905
|
+
if (start.args !== void 0) {
|
|
10906
|
+
setIO(attrs, "TOOL", safeStringify15(start.args), void 0);
|
|
10907
|
+
push(attrs, attrStr("neatlogs.tool.input", safeStringify15(start.args)));
|
|
10908
|
+
}
|
|
10909
|
+
if (result?.title) push(attrs, attrStr("neatlogs.tool.title", String(result.title)));
|
|
10910
|
+
const out = result?.output ?? result?.result;
|
|
10415
10911
|
if (out !== void 0) {
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10912
|
+
const o = typeof out === "string" ? out : safeStringify15(out);
|
|
10913
|
+
setIO(attrs, "TOOL", void 0, o);
|
|
10914
|
+
push(attrs, attrStr("neatlogs.tool.output", o));
|
|
10915
|
+
}
|
|
10916
|
+
if (result?.metadata !== void 0) {
|
|
10917
|
+
push(attrs, attrStr("neatlogs.tool.metadata", safeStringify15(result.metadata)));
|
|
10918
|
+
}
|
|
10919
|
+
shipper.enqueue({
|
|
10920
|
+
traceId: st.traceId,
|
|
10921
|
+
spanId: start.spanId,
|
|
10922
|
+
parentSpanId: st.rootSpan?.spanId,
|
|
10923
|
+
name: `opencode.tool.${start.tool}`,
|
|
10924
|
+
kind: 1,
|
|
10925
|
+
startTimeUnixNano: start.startNano,
|
|
10926
|
+
endTimeUnixNano: nowNanoString(),
|
|
10927
|
+
attributes: attrs,
|
|
10928
|
+
status: { code: SpanStatusCode16.OK }
|
|
10929
|
+
});
|
|
10424
10930
|
} catch {
|
|
10425
10931
|
}
|
|
10426
10932
|
}
|
|
10427
10933
|
};
|
|
10428
10934
|
};
|
|
10429
|
-
function handleEvent2(
|
|
10935
|
+
function handleEvent2(shipper, sessions, stateFor, startRoot, closeAndFlush, event) {
|
|
10430
10936
|
const type = event?.type;
|
|
10431
10937
|
const props = event?.properties ?? {};
|
|
10432
10938
|
if (type === "message.part.updated" || type === "message.part.completed") {
|
|
10433
10939
|
const part = props.part ?? props;
|
|
10434
10940
|
const messageID = part?.messageID ?? part?.message_id;
|
|
10435
10941
|
const sessionID = part?.sessionID ?? props.sessionID;
|
|
10436
|
-
if (
|
|
10437
|
-
|
|
10438
|
-
|
|
10942
|
+
if (!messageID || !sessionID) return void 0;
|
|
10943
|
+
const st = stateFor(String(sessionID));
|
|
10944
|
+
if (part?.type === "text" && typeof part?.text === "string") {
|
|
10945
|
+
st.outputParts.set(String(messageID), part.text);
|
|
10946
|
+
} else if (part?.type === "tool" && part?.tool) {
|
|
10947
|
+
const list = st.toolCalls.get(String(messageID)) ?? [];
|
|
10948
|
+
const callID = String(part.callID ?? part.tool);
|
|
10949
|
+
const input = part?.state?.input ?? {};
|
|
10950
|
+
const existing = list.find((t) => t.callID === callID);
|
|
10951
|
+
if (existing) existing.input = input;
|
|
10952
|
+
else list.push({ name: String(part.tool), input, callID });
|
|
10953
|
+
st.toolCalls.set(String(messageID), list);
|
|
10439
10954
|
}
|
|
10440
|
-
return;
|
|
10955
|
+
return void 0;
|
|
10441
10956
|
}
|
|
10442
10957
|
if (type === "message.updated" || type === "message.completed") {
|
|
10443
10958
|
const info = props.info ?? props.message ?? props;
|
|
10444
10959
|
const sessionID = info?.sessionID ?? info?.session_id;
|
|
10445
|
-
if (!sessionID) return;
|
|
10960
|
+
if (!sessionID) return void 0;
|
|
10961
|
+
if (info?.role !== "assistant") return void 0;
|
|
10962
|
+
const completed = info?.time?.completed ?? info?.completed;
|
|
10963
|
+
const id = String(info?.id ?? "");
|
|
10964
|
+
if (!completed || !id) return void 0;
|
|
10446
10965
|
const st = stateFor(String(sessionID));
|
|
10447
|
-
if (
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
if (info?.role === "assistant") {
|
|
10453
|
-
const completed = info?.time?.completed ?? info?.completed;
|
|
10454
|
-
const id = String(info?.id ?? "");
|
|
10455
|
-
if (!completed || st.emitted.has(id)) return;
|
|
10456
|
-
st.emitted.add(id);
|
|
10457
|
-
emitLlmSpan2(tracer, st, captureSystemPrompt, info, String(sessionID));
|
|
10458
|
-
}
|
|
10459
|
-
return;
|
|
10966
|
+
if (st.processed.has(id)) return void 0;
|
|
10967
|
+
st.processed.add(id);
|
|
10968
|
+
startRoot(st, String(sessionID));
|
|
10969
|
+
emitLlmSpan2(shipper, st, info, String(sessionID));
|
|
10970
|
+
return shipper.flush().catch(() => void 0);
|
|
10460
10971
|
}
|
|
10461
10972
|
if (type === "session.idle" || type === "session.deleted") {
|
|
10462
10973
|
const sessionID = props.sessionID ?? props.info?.id;
|
|
10463
10974
|
if (!sessionID) return void 0;
|
|
10464
10975
|
const st = sessions.get(String(sessionID));
|
|
10465
10976
|
if (!st) return void 0;
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
ts.end();
|
|
10469
|
-
} catch {
|
|
10470
|
-
}
|
|
10471
|
-
}
|
|
10472
|
-
st.toolSpans.clear();
|
|
10977
|
+
st.toolStarts.clear();
|
|
10978
|
+
const p = closeAndFlush(st, String(sessionID));
|
|
10473
10979
|
if (type === "session.deleted") sessions.delete(String(sessionID));
|
|
10474
|
-
return
|
|
10980
|
+
return p;
|
|
10475
10981
|
}
|
|
10476
10982
|
return void 0;
|
|
10477
10983
|
}
|
|
10478
|
-
function emitLlmSpan2(
|
|
10984
|
+
function emitLlmSpan2(shipper, st, info, sessionID) {
|
|
10479
10985
|
const model = info?.modelID ?? info?.model ?? "";
|
|
10480
10986
|
const provider = info?.providerID ?? info?.provider ?? "";
|
|
10481
|
-
const attrs =
|
|
10482
|
-
"neatlogs.span.kind": "LLM",
|
|
10483
|
-
"neatlogs.conversation.id": sessionID
|
|
10484
|
-
|
|
10485
|
-
|
|
10486
|
-
|
|
10487
|
-
|
|
10488
|
-
|
|
10489
|
-
attrs
|
|
10490
|
-
attrs
|
|
10491
|
-
}
|
|
10492
|
-
let inIdx = captureSystemPrompt && info?.system ? 1 : 0;
|
|
10493
|
-
if (st.lastUserText) {
|
|
10494
|
-
attrs[`neatlogs.llm.input_messages.${inIdx}.role`] = "user";
|
|
10495
|
-
attrs[`neatlogs.llm.input_messages.${inIdx}.content`] = st.lastUserText;
|
|
10987
|
+
const attrs = [
|
|
10988
|
+
{ key: "neatlogs.span.kind", value: { stringValue: "LLM" } },
|
|
10989
|
+
{ key: "neatlogs.conversation.id", value: { stringValue: sessionID } }
|
|
10990
|
+
];
|
|
10991
|
+
push(attrs, attrStr("neatlogs.llm.model_name", model ? String(model) : void 0));
|
|
10992
|
+
push(attrs, attrStr("neatlogs.llm.provider", provider ? String(provider) : void 0));
|
|
10993
|
+
let inIdx = 0;
|
|
10994
|
+
if (st.systemPrompt) {
|
|
10995
|
+
push(attrs, attrStr(`neatlogs.llm.input_messages.${inIdx}.role`, "system"));
|
|
10996
|
+
push(attrs, attrStr(`neatlogs.llm.input_messages.${inIdx}.content`, st.systemPrompt));
|
|
10496
10997
|
inIdx++;
|
|
10497
10998
|
}
|
|
10498
|
-
|
|
10999
|
+
if (st.currentInput) {
|
|
11000
|
+
push(attrs, attrStr(`neatlogs.llm.input_messages.${inIdx}.role`, "user"));
|
|
11001
|
+
push(attrs, attrStr(`neatlogs.llm.input_messages.${inIdx}.content`, st.currentInput));
|
|
11002
|
+
setIO(attrs, "LLM", st.currentInput, void 0);
|
|
11003
|
+
}
|
|
11004
|
+
const outText = st.outputParts.get(String(info?.id)) || messageText2(info) || "";
|
|
11005
|
+
const toolCalls = st.toolCalls.get(String(info?.id)) ?? [];
|
|
10499
11006
|
if (outText) {
|
|
10500
|
-
attrs
|
|
10501
|
-
attrs
|
|
11007
|
+
push(attrs, attrStr("neatlogs.llm.output_messages.0.role", "assistant"));
|
|
11008
|
+
push(attrs, attrStr("neatlogs.llm.output_messages.0.content", outText));
|
|
11009
|
+
setIO(attrs, "LLM", void 0, outText);
|
|
11010
|
+
st.lastAssistantText = outText;
|
|
11011
|
+
}
|
|
11012
|
+
if (toolCalls.length) {
|
|
11013
|
+
toolCalls.forEach((tc, j) => {
|
|
11014
|
+
push(attrs, attrStr(`neatlogs.llm.tool_calls.${j}.name`, tc.name));
|
|
11015
|
+
push(attrs, attrStr(`neatlogs.llm.tool_calls.${j}.arguments`, safeStringify15(tc.input ?? {})));
|
|
11016
|
+
});
|
|
11017
|
+
if (!outText) {
|
|
11018
|
+
const rendered = toolCalls.map((tc) => `\u2192 ${tc.name}(${safeStringify15(tc.input ?? {})})`).join("\n");
|
|
11019
|
+
push(attrs, attrStr("neatlogs.llm.output_messages.0.role", "assistant"));
|
|
11020
|
+
push(attrs, attrStr("neatlogs.llm.output_messages.0.content", rendered));
|
|
11021
|
+
setIO(attrs, "LLM", void 0, rendered);
|
|
11022
|
+
}
|
|
10502
11023
|
}
|
|
10503
11024
|
const tokens = info?.tokens;
|
|
10504
11025
|
if (tokens) {
|
|
10505
|
-
|
|
10506
|
-
|
|
11026
|
+
push(attrs, attrInt("neatlogs.llm.token_count.prompt", tokens.input));
|
|
11027
|
+
push(attrs, attrInt("neatlogs.llm.token_count.completion", tokens.output));
|
|
10507
11028
|
if (tokens.input != null && tokens.output != null) {
|
|
10508
|
-
attrs
|
|
10509
|
-
}
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
|
|
11029
|
+
push(attrs, attrInt("neatlogs.llm.token_count.total", tokens.input + tokens.output));
|
|
11030
|
+
}
|
|
11031
|
+
push(attrs, attrInt("neatlogs.llm.token_count.reasoning", tokens.reasoning));
|
|
11032
|
+
push(attrs, attrInt("neatlogs.llm.token_count.cache_read", tokens.cache?.read));
|
|
11033
|
+
push(attrs, attrInt("neatlogs.llm.token_count.cache_write", tokens.cache?.write));
|
|
11034
|
+
}
|
|
11035
|
+
push(attrs, attrDouble("neatlogs.llm.cost_usd", info?.cost));
|
|
11036
|
+
const createdMs = info?.time?.created;
|
|
11037
|
+
const startNano = typeof createdMs === "number" ? msToNanoString(Math.floor(createdMs)) : nowNanoString();
|
|
11038
|
+
shipper.enqueue({
|
|
11039
|
+
traceId: st.traceId,
|
|
11040
|
+
spanId: generateSpanId(),
|
|
11041
|
+
parentSpanId: st.rootSpan?.spanId,
|
|
11042
|
+
name: `opencode.llm.${model || "model"}`,
|
|
11043
|
+
kind: 1,
|
|
11044
|
+
startTimeUnixNano: startNano,
|
|
11045
|
+
endTimeUnixNano: nowNanoString(),
|
|
11046
|
+
attributes: attrs,
|
|
11047
|
+
status: { code: SpanStatusCode16.OK }
|
|
11048
|
+
});
|
|
11049
|
+
if (info?.id) {
|
|
11050
|
+
st.outputParts.delete(String(info.id));
|
|
11051
|
+
st.toolCalls.delete(String(info.id));
|
|
11052
|
+
}
|
|
11053
|
+
}
|
|
11054
|
+
function push(arr, kv) {
|
|
11055
|
+
if (kv) arr.push(kv);
|
|
11056
|
+
}
|
|
11057
|
+
function setIO(arr, kind, input, output) {
|
|
11058
|
+
const k = kind.toLowerCase();
|
|
11059
|
+
if (input !== void 0) {
|
|
11060
|
+
push(arr, attrStr("input.value", input));
|
|
11061
|
+
push(arr, attrStr("neatlogs.input.value", input));
|
|
11062
|
+
push(arr, attrStr(`neatlogs.${k}.input`, input));
|
|
11063
|
+
}
|
|
11064
|
+
if (output !== void 0) {
|
|
11065
|
+
push(arr, attrStr("output.value", output));
|
|
11066
|
+
push(arr, attrStr("neatlogs.output.value", output));
|
|
11067
|
+
push(arr, attrStr(`neatlogs.${k}.output`, output));
|
|
10513
11068
|
}
|
|
10514
|
-
if (info?.cost != null) attrs["neatlogs.llm.cost_usd"] = info.cost;
|
|
10515
|
-
const span2 = tracer.startSpan(`opencode.llm.${model || "model"}`, { attributes: attrs }, import_api20.context.active());
|
|
10516
|
-
span2.setStatus({ code: import_api20.SpanStatusCode.OK });
|
|
10517
|
-
span2.end();
|
|
10518
|
-
if (info?.id) st.messageText.delete(String(info.id));
|
|
10519
11069
|
}
|
|
10520
11070
|
function messageText2(info) {
|
|
10521
11071
|
if (!info) return "";
|
|
@@ -10535,7 +11085,7 @@ function safeStringify15(value) {
|
|
|
10535
11085
|
try {
|
|
10536
11086
|
return JSON.stringify(value) ?? "";
|
|
10537
11087
|
} catch {
|
|
10538
|
-
return
|
|
11088
|
+
return String(value);
|
|
10539
11089
|
}
|
|
10540
11090
|
}
|
|
10541
11091
|
|