neatlogs 1.0.3 → 1.0.5
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 +373 -0
- package/dist/anthropic.cjs.map +1 -0
- package/dist/anthropic.d.ts +27 -0
- package/dist/anthropic.mjs +347 -0
- package/dist/anthropic.mjs.map +1 -0
- package/dist/index.cjs +1665 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.mjs +1656 -7
- package/dist/index.mjs.map +1 -1
- package/dist/langchain.cjs +269 -0
- package/dist/langchain.cjs.map +1 -0
- package/dist/langchain.d.ts +16 -0
- package/dist/langchain.mjs +244 -0
- package/dist/langchain.mjs.map +1 -0
- package/dist/mastra-wrap.cjs +597 -0
- package/dist/mastra-wrap.cjs.map +1 -0
- package/dist/mastra-wrap.d.ts +38 -0
- package/dist/mastra-wrap.mjs +571 -0
- package/dist/mastra-wrap.mjs.map +1 -0
- package/dist/openai-agents.cjs +215 -0
- package/dist/openai-agents.cjs.map +1 -0
- package/dist/openai-agents.d.ts +13 -0
- package/dist/openai-agents.mjs +190 -0
- package/dist/openai-agents.mjs.map +1 -0
- package/dist/openai.cjs +342 -0
- package/dist/openai.cjs.map +1 -0
- package/dist/openai.d.ts +26 -0
- package/dist/openai.mjs +316 -0
- package/dist/openai.mjs.map +1 -0
- package/dist/strands.cjs +44 -0
- package/dist/strands.cjs.map +1 -0
- package/dist/strands.d.ts +27 -0
- package/dist/strands.mjs +19 -0
- package/dist/strands.mjs.map +1 -0
- package/package.json +80 -10
package/dist/openai.mjs
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// src/openai.ts
|
|
2
|
+
import { trace, context as otelContext, SpanStatusCode } from "@opentelemetry/api";
|
|
3
|
+
var TRACER_NAME = "neatlogs.openai";
|
|
4
|
+
function wrapOpenAI(client) {
|
|
5
|
+
return wrapNamespace(client, []);
|
|
6
|
+
}
|
|
7
|
+
function traceTool(name, fn) {
|
|
8
|
+
return async function tracedTool(args) {
|
|
9
|
+
const tracer = trace.getTracer(TRACER_NAME);
|
|
10
|
+
return tracer.startActiveSpan(
|
|
11
|
+
`tool.${name}`,
|
|
12
|
+
{
|
|
13
|
+
attributes: {
|
|
14
|
+
"neatlogs.span.kind": "TOOL",
|
|
15
|
+
"neatlogs.tool.name": name,
|
|
16
|
+
"input.value": safeStringify(args)
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
otelContext.active(),
|
|
20
|
+
async (span) => {
|
|
21
|
+
try {
|
|
22
|
+
const result = await fn(args);
|
|
23
|
+
span.setAttribute("output.value", safeStringify(result));
|
|
24
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
25
|
+
return result;
|
|
26
|
+
} catch (err) {
|
|
27
|
+
recordError(span, err);
|
|
28
|
+
throw err;
|
|
29
|
+
} finally {
|
|
30
|
+
span.end();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function wrapNamespace(target, path) {
|
|
37
|
+
return new Proxy(target, {
|
|
38
|
+
get(obj, prop, receiver) {
|
|
39
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
40
|
+
if (typeof prop === "symbol" || String(prop).startsWith("_")) return value;
|
|
41
|
+
const currentPath = [...path, String(prop)];
|
|
42
|
+
const pathStr = currentPath.join(".");
|
|
43
|
+
if (pathStr === "chat.completions.create" && typeof value === "function") {
|
|
44
|
+
return tracedChatCompletionsCreate(value.bind(obj));
|
|
45
|
+
}
|
|
46
|
+
if (pathStr === "responses.create" && typeof value === "function") {
|
|
47
|
+
return tracedResponsesCreate(value.bind(obj));
|
|
48
|
+
}
|
|
49
|
+
if (value && typeof value === "object" && !Array.isArray(value) && isNamespace(currentPath)) {
|
|
50
|
+
return wrapNamespace(value, currentPath);
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function isNamespace(path) {
|
|
57
|
+
if (path.length > 3) return false;
|
|
58
|
+
const key = path[path.length - 1];
|
|
59
|
+
return ["chat", "completions", "responses", "beta"].includes(key);
|
|
60
|
+
}
|
|
61
|
+
function tracedChatCompletionsCreate(original) {
|
|
62
|
+
return function(opts, ...rest) {
|
|
63
|
+
const tracer = trace.getTracer(TRACER_NAME);
|
|
64
|
+
const model = opts?.model ?? "";
|
|
65
|
+
const messages = opts?.messages ?? [];
|
|
66
|
+
const isStream = opts?.stream === true;
|
|
67
|
+
const span = tracer.startSpan("openai.chat.completions.create", {
|
|
68
|
+
attributes: {
|
|
69
|
+
"neatlogs.span.kind": "LLM",
|
|
70
|
+
"neatlogs.llm.provider": "openai",
|
|
71
|
+
"neatlogs.llm.system": "openai",
|
|
72
|
+
"neatlogs.llm.model_name": model,
|
|
73
|
+
"neatlogs.llm.is_streaming": isStream
|
|
74
|
+
}
|
|
75
|
+
}, otelContext.active());
|
|
76
|
+
for (let i = 0; i < messages.length; i++) {
|
|
77
|
+
const msg = messages[i];
|
|
78
|
+
span.setAttribute(`neatlogs.llm.input_messages.${i}.role`, msg.role ?? "");
|
|
79
|
+
if (typeof msg.content === "string") {
|
|
80
|
+
span.setAttribute(`neatlogs.llm.input_messages.${i}.content`, msg.content);
|
|
81
|
+
} else if (msg.content) {
|
|
82
|
+
span.setAttribute(`neatlogs.llm.input_messages.${i}.content`, safeStringify(msg.content));
|
|
83
|
+
}
|
|
84
|
+
if (msg.tool_call_id) {
|
|
85
|
+
span.setAttribute(`neatlogs.llm.input_messages.${i}.tool_call_id`, msg.tool_call_id);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (opts?.tools) {
|
|
89
|
+
for (let i = 0; i < opts.tools.length; i++) {
|
|
90
|
+
const fn = opts.tools[i]?.function ?? {};
|
|
91
|
+
span.setAttribute(`neatlogs.llm.tools.${i}.name`, fn.name ?? "");
|
|
92
|
+
if (fn.description) span.setAttribute(`neatlogs.llm.tools.${i}.description`, fn.description);
|
|
93
|
+
if (fn.parameters) span.setAttribute(`neatlogs.llm.tools.${i}.input_schema`, safeStringify(fn.parameters));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
setInvocationParams(span, opts);
|
|
97
|
+
if (isStream) {
|
|
98
|
+
opts = { ...opts };
|
|
99
|
+
const streamOpts = opts.stream_options ?? {};
|
|
100
|
+
if (!streamOpts.include_usage) {
|
|
101
|
+
opts.stream_options = { ...streamOpts, include_usage: true };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const ctx = trace.setSpan(otelContext.active(), span);
|
|
105
|
+
const promise = otelContext.with(ctx, () => original(opts, ...rest));
|
|
106
|
+
return promise.then(
|
|
107
|
+
(response) => {
|
|
108
|
+
if (isStream) {
|
|
109
|
+
return wrapAsyncIterableStream(response, span);
|
|
110
|
+
}
|
|
111
|
+
finalizeChatResponse(span, response);
|
|
112
|
+
return response;
|
|
113
|
+
},
|
|
114
|
+
(err) => {
|
|
115
|
+
recordError(span, err);
|
|
116
|
+
throw err;
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
function tracedResponsesCreate(original) {
|
|
122
|
+
return function(opts, ...rest) {
|
|
123
|
+
const tracer = trace.getTracer(TRACER_NAME);
|
|
124
|
+
const model = opts?.model ?? "";
|
|
125
|
+
const span = tracer.startSpan("openai.responses.create", {
|
|
126
|
+
attributes: {
|
|
127
|
+
"neatlogs.span.kind": "LLM",
|
|
128
|
+
"neatlogs.llm.provider": "openai",
|
|
129
|
+
"neatlogs.llm.system": "openai",
|
|
130
|
+
"neatlogs.llm.model_name": model,
|
|
131
|
+
"input.value": safeStringify(opts?.input ?? "")
|
|
132
|
+
}
|
|
133
|
+
}, otelContext.active());
|
|
134
|
+
const ctx = trace.setSpan(otelContext.active(), span);
|
|
135
|
+
const promise = otelContext.with(ctx, () => original(opts, ...rest));
|
|
136
|
+
return promise.then(
|
|
137
|
+
(response) => {
|
|
138
|
+
if (response?.output_text) {
|
|
139
|
+
span.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
140
|
+
span.setAttribute("neatlogs.llm.output_messages.0.content", response.output_text);
|
|
141
|
+
}
|
|
142
|
+
if (response?.model) span.setAttribute("neatlogs.llm.model_name", response.model);
|
|
143
|
+
if (response?.usage) {
|
|
144
|
+
if (response.usage.input_tokens != null) span.setAttribute("neatlogs.llm.token_count.prompt", response.usage.input_tokens);
|
|
145
|
+
if (response.usage.output_tokens != null) span.setAttribute("neatlogs.llm.token_count.completion", response.usage.output_tokens);
|
|
146
|
+
}
|
|
147
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
148
|
+
span.end();
|
|
149
|
+
return response;
|
|
150
|
+
},
|
|
151
|
+
(err) => {
|
|
152
|
+
recordError(span, err);
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function wrapAsyncIterableStream(stream, span) {
|
|
159
|
+
const chunks = [];
|
|
160
|
+
const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);
|
|
161
|
+
if (!originalAsyncIterator) {
|
|
162
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
163
|
+
span.end();
|
|
164
|
+
return stream;
|
|
165
|
+
}
|
|
166
|
+
const wrapped = Object.create(Object.getPrototypeOf(stream));
|
|
167
|
+
Object.assign(wrapped, stream);
|
|
168
|
+
wrapped[Symbol.asyncIterator] = function() {
|
|
169
|
+
const iterator = originalAsyncIterator();
|
|
170
|
+
return {
|
|
171
|
+
async next() {
|
|
172
|
+
try {
|
|
173
|
+
const result = await iterator.next();
|
|
174
|
+
if (result.done) {
|
|
175
|
+
finalizeStreamChunks(span, chunks);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
chunks.push(result.value);
|
|
179
|
+
return result;
|
|
180
|
+
} catch (err) {
|
|
181
|
+
recordError(span, err);
|
|
182
|
+
throw err;
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
async return(value) {
|
|
186
|
+
finalizeStreamChunks(span, chunks);
|
|
187
|
+
return iterator.return?.(value) ?? { done: true, value: void 0 };
|
|
188
|
+
},
|
|
189
|
+
async throw(err) {
|
|
190
|
+
recordError(span, err);
|
|
191
|
+
return iterator.throw?.(err) ?? { done: true, value: void 0 };
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
return wrapped;
|
|
196
|
+
}
|
|
197
|
+
function finalizeStreamChunks(span, chunks) {
|
|
198
|
+
const textParts = [];
|
|
199
|
+
const toolCallsAcc = {};
|
|
200
|
+
let finishReason = "";
|
|
201
|
+
let model = "";
|
|
202
|
+
let usage = null;
|
|
203
|
+
for (const chunk of chunks) {
|
|
204
|
+
if (!chunk?.choices?.length) {
|
|
205
|
+
if (chunk?.usage) usage = chunk.usage;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const choice = chunk.choices[0];
|
|
209
|
+
const delta = choice?.delta;
|
|
210
|
+
if (delta?.content) textParts.push(delta.content);
|
|
211
|
+
if (delta?.tool_calls) {
|
|
212
|
+
for (const tc of delta.tool_calls) {
|
|
213
|
+
const idx = tc.index ?? 0;
|
|
214
|
+
if (!toolCallsAcc[idx]) toolCallsAcc[idx] = { id: "", name: "", arguments: "" };
|
|
215
|
+
if (tc.id) toolCallsAcc[idx].id = tc.id;
|
|
216
|
+
if (tc.function?.name) toolCallsAcc[idx].name = tc.function.name;
|
|
217
|
+
if (tc.function?.arguments) toolCallsAcc[idx].arguments += tc.function.arguments;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
221
|
+
if (chunk?.model) model = chunk.model;
|
|
222
|
+
}
|
|
223
|
+
const fullText = textParts.join("");
|
|
224
|
+
if (fullText) {
|
|
225
|
+
span.setAttribute("neatlogs.llm.output_messages.0.role", "assistant");
|
|
226
|
+
span.setAttribute("neatlogs.llm.output_messages.0.content", fullText);
|
|
227
|
+
}
|
|
228
|
+
let j = 0;
|
|
229
|
+
for (const tc of Object.values(toolCallsAcc)) {
|
|
230
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id);
|
|
231
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.name);
|
|
232
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.arguments);
|
|
233
|
+
j++;
|
|
234
|
+
}
|
|
235
|
+
if (model) span.setAttribute("neatlogs.llm.model_name", model);
|
|
236
|
+
if (finishReason) span.setAttribute("neatlogs.llm.finish_reason", finishReason);
|
|
237
|
+
if (usage) {
|
|
238
|
+
if (usage.prompt_tokens != null) span.setAttribute("neatlogs.llm.token_count.prompt", usage.prompt_tokens);
|
|
239
|
+
if (usage.completion_tokens != null) span.setAttribute("neatlogs.llm.token_count.completion", usage.completion_tokens);
|
|
240
|
+
if (usage.total_tokens != null) span.setAttribute("neatlogs.llm.token_count.total", usage.total_tokens);
|
|
241
|
+
if (usage.prompt_tokens_details?.cached_tokens != null) {
|
|
242
|
+
span.setAttribute("neatlogs.llm.token_count.cache_read", usage.prompt_tokens_details.cached_tokens);
|
|
243
|
+
}
|
|
244
|
+
if (usage.completion_tokens_details?.reasoning_tokens != null) {
|
|
245
|
+
span.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
249
|
+
span.end();
|
|
250
|
+
}
|
|
251
|
+
function finalizeChatResponse(span, response) {
|
|
252
|
+
const choices = response?.choices ?? [];
|
|
253
|
+
for (let i = 0; i < choices.length; i++) {
|
|
254
|
+
const message = choices[i]?.message;
|
|
255
|
+
if (!message) continue;
|
|
256
|
+
span.setAttribute(`neatlogs.llm.output_messages.${i}.role`, "assistant");
|
|
257
|
+
if (message.content) {
|
|
258
|
+
span.setAttribute(`neatlogs.llm.output_messages.${i}.content`, message.content);
|
|
259
|
+
}
|
|
260
|
+
if (message.tool_calls) {
|
|
261
|
+
for (let j = 0; j < message.tool_calls.length; j++) {
|
|
262
|
+
const tc = message.tool_calls[j];
|
|
263
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id ?? "");
|
|
264
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.function?.name ?? "");
|
|
265
|
+
span.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.function?.arguments ?? "");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (choices[i].finish_reason) {
|
|
269
|
+
span.setAttribute("neatlogs.llm.finish_reason", choices[i].finish_reason);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
const usage = response?.usage;
|
|
273
|
+
if (usage) {
|
|
274
|
+
if (usage.prompt_tokens != null) span.setAttribute("neatlogs.llm.token_count.prompt", usage.prompt_tokens);
|
|
275
|
+
if (usage.completion_tokens != null) span.setAttribute("neatlogs.llm.token_count.completion", usage.completion_tokens);
|
|
276
|
+
if (usage.total_tokens != null) span.setAttribute("neatlogs.llm.token_count.total", usage.total_tokens);
|
|
277
|
+
if (usage.prompt_tokens_details?.cached_tokens != null) {
|
|
278
|
+
span.setAttribute("neatlogs.llm.token_count.cache_read", usage.prompt_tokens_details.cached_tokens);
|
|
279
|
+
}
|
|
280
|
+
if (usage.completion_tokens_details?.reasoning_tokens != null) {
|
|
281
|
+
span.setAttribute("neatlogs.llm.token_count.reasoning", usage.completion_tokens_details.reasoning_tokens);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (response?.model) span.setAttribute("neatlogs.llm.model_name", response.model);
|
|
285
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
286
|
+
span.end();
|
|
287
|
+
}
|
|
288
|
+
function setInvocationParams(span, opts) {
|
|
289
|
+
if (opts?.temperature != null) span.setAttribute("neatlogs.llm.temperature", opts.temperature);
|
|
290
|
+
if (opts?.top_p != null) span.setAttribute("neatlogs.llm.top_p", opts.top_p);
|
|
291
|
+
if (opts?.max_tokens != null) span.setAttribute("neatlogs.llm.max_tokens", opts.max_tokens);
|
|
292
|
+
if (opts?.frequency_penalty != null) span.setAttribute("neatlogs.llm.frequency_penalty", opts.frequency_penalty);
|
|
293
|
+
if (opts?.presence_penalty != null) span.setAttribute("neatlogs.llm.presence_penalty", opts.presence_penalty);
|
|
294
|
+
if (opts?.stop) span.setAttribute("neatlogs.llm.stop_sequences", safeStringify(opts.stop));
|
|
295
|
+
}
|
|
296
|
+
function safeStringify(value) {
|
|
297
|
+
try {
|
|
298
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
299
|
+
} catch {
|
|
300
|
+
return "";
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function recordError(span, err) {
|
|
304
|
+
if (err instanceof Error) {
|
|
305
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
|
|
306
|
+
span.recordException(err);
|
|
307
|
+
} else {
|
|
308
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) });
|
|
309
|
+
}
|
|
310
|
+
span.end();
|
|
311
|
+
}
|
|
312
|
+
export {
|
|
313
|
+
traceTool,
|
|
314
|
+
wrapOpenAI
|
|
315
|
+
};
|
|
316
|
+
//# sourceMappingURL=openai.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/openai.ts"],"sourcesContent":["/**\n * Neatlogs OpenAI wrapper — ES6 Proxy-based.\n *\n * Usage:\n * import { wrapOpenAI, traceTool } from 'neatlogs/openai';\n * import OpenAI from 'openai';\n * const client = wrapOpenAI(new OpenAI());\n *\n * Intercepts:\n * - client.chat.completions.create() — non-streaming and streaming\n * - client.responses.create() — Responses API\n *\n * Also exports traceTool() to wrap user-defined tool functions with TOOL spans.\n */\n\nimport { trace, context as otelContext, SpanStatusCode, type Span } from '@opentelemetry/api';\n\nconst TRACER_NAME = 'neatlogs.openai';\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\nexport function wrapOpenAI<T extends object>(client: T): T {\n return wrapNamespace(client, []) as T;\n}\n\n/**\n * Wrap a tool/function implementation to emit TOOL spans when executed.\n *\n * Usage:\n * const getWeather = traceTool('get_weather', async (args: { city: string }) => {\n * return `Weather in ${args.city}: sunny`;\n * });\n */\nexport function traceTool<TArgs = any, TResult = any>(\n name: string,\n fn: (args: TArgs) => TResult | Promise<TResult>,\n): (args: TArgs) => Promise<TResult> {\n return async function tracedTool(args: TArgs): Promise<TResult> {\n const tracer = trace.getTracer(TRACER_NAME);\n return tracer.startActiveSpan(\n `tool.${name}`,\n {\n attributes: {\n 'neatlogs.span.kind': 'TOOL',\n 'neatlogs.tool.name': name,\n 'input.value': safeStringify(args),\n },\n },\n otelContext.active(),\n async (span) => {\n try {\n const result = await fn(args);\n span.setAttribute('output.value', safeStringify(result));\n span.setStatus({ code: SpanStatusCode.OK });\n return result;\n } catch (err) {\n recordError(span, err);\n throw err;\n } finally {\n span.end();\n }\n },\n );\n };\n}\n\n// ---------------------------------------------------------------------------\n// Proxy wrapping\n// ---------------------------------------------------------------------------\n\nfunction wrapNamespace(target: any, path: string[]): any {\n return new Proxy(target, {\n get(obj, prop, receiver) {\n const value = Reflect.get(obj, prop, receiver);\n if (typeof prop === 'symbol' || String(prop).startsWith('_')) return value;\n\n const currentPath = [...path, String(prop)];\n const pathStr = currentPath.join('.');\n\n if (pathStr === 'chat.completions.create' && typeof value === 'function') {\n return tracedChatCompletionsCreate(value.bind(obj));\n }\n if (pathStr === 'responses.create' && typeof value === 'function') {\n return tracedResponsesCreate(value.bind(obj));\n }\n\n if (value && typeof value === 'object' && !Array.isArray(value) && isNamespace(currentPath)) {\n return wrapNamespace(value, currentPath);\n }\n\n return value;\n },\n });\n}\n\nfunction isNamespace(path: string[]): boolean {\n if (path.length > 3) return false;\n const key = path[path.length - 1];\n return ['chat', 'completions', 'responses', 'beta'].includes(key);\n}\n\n// ---------------------------------------------------------------------------\n// chat.completions.create — non-streaming + streaming\n// ---------------------------------------------------------------------------\n\nfunction tracedChatCompletionsCreate(original: (...args: any[]) => any) {\n return function (opts: any, ...rest: any[]): any {\n const tracer = trace.getTracer(TRACER_NAME);\n const model = opts?.model ?? '';\n const messages: any[] = opts?.messages ?? [];\n const isStream = opts?.stream === true;\n\n const span = tracer.startSpan('openai.chat.completions.create', {\n attributes: {\n 'neatlogs.span.kind': 'LLM',\n 'neatlogs.llm.provider': 'openai',\n 'neatlogs.llm.system': 'openai',\n 'neatlogs.llm.model_name': model,\n 'neatlogs.llm.is_streaming': isStream,\n },\n }, otelContext.active());\n\n // Input messages\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n span.setAttribute(`neatlogs.llm.input_messages.${i}.role`, msg.role ?? '');\n if (typeof msg.content === 'string') {\n span.setAttribute(`neatlogs.llm.input_messages.${i}.content`, msg.content);\n } else if (msg.content) {\n span.setAttribute(`neatlogs.llm.input_messages.${i}.content`, safeStringify(msg.content));\n }\n if (msg.tool_call_id) {\n span.setAttribute(`neatlogs.llm.input_messages.${i}.tool_call_id`, msg.tool_call_id);\n }\n }\n\n // Tools\n if (opts?.tools) {\n for (let i = 0; i < opts.tools.length; i++) {\n const fn = opts.tools[i]?.function ?? {};\n span.setAttribute(`neatlogs.llm.tools.${i}.name`, fn.name ?? '');\n if (fn.description) span.setAttribute(`neatlogs.llm.tools.${i}.description`, fn.description);\n if (fn.parameters) span.setAttribute(`neatlogs.llm.tools.${i}.input_schema`, safeStringify(fn.parameters));\n }\n }\n\n // Invocation parameters\n setInvocationParams(span, opts);\n\n // Force stream_options.include_usage for streaming\n if (isStream) {\n opts = { ...opts };\n const streamOpts = opts.stream_options ?? {};\n if (!streamOpts.include_usage) {\n opts.stream_options = { ...streamOpts, include_usage: true };\n }\n }\n\n const ctx = trace.setSpan(otelContext.active(), span);\n const promise = otelContext.with(ctx, () => original(opts, ...rest));\n\n return promise.then(\n (response: any) => {\n if (isStream) {\n return wrapAsyncIterableStream(response, span);\n }\n finalizeChatResponse(span, response);\n return response;\n },\n (err: any) => {\n recordError(span, err);\n throw err;\n },\n );\n };\n}\n\n// ---------------------------------------------------------------------------\n// responses.create\n// ---------------------------------------------------------------------------\n\nfunction tracedResponsesCreate(original: (...args: any[]) => any) {\n return function (opts: any, ...rest: any[]): any {\n const tracer = trace.getTracer(TRACER_NAME);\n const model = opts?.model ?? '';\n\n const span = tracer.startSpan('openai.responses.create', {\n attributes: {\n 'neatlogs.span.kind': 'LLM',\n 'neatlogs.llm.provider': 'openai',\n 'neatlogs.llm.system': 'openai',\n 'neatlogs.llm.model_name': model,\n 'input.value': safeStringify(opts?.input ?? ''),\n },\n }, otelContext.active());\n\n const ctx = trace.setSpan(otelContext.active(), span);\n const promise = otelContext.with(ctx, () => original(opts, ...rest));\n\n return promise.then(\n (response: any) => {\n if (response?.output_text) {\n span.setAttribute('neatlogs.llm.output_messages.0.role', 'assistant');\n span.setAttribute('neatlogs.llm.output_messages.0.content', response.output_text);\n }\n if (response?.model) span.setAttribute('neatlogs.llm.model_name', response.model);\n if (response?.usage) {\n if (response.usage.input_tokens != null) span.setAttribute('neatlogs.llm.token_count.prompt', response.usage.input_tokens);\n if (response.usage.output_tokens != null) span.setAttribute('neatlogs.llm.token_count.completion', response.usage.output_tokens);\n }\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return response;\n },\n (err: any) => {\n recordError(span, err);\n throw err;\n },\n );\n };\n}\n\n// ---------------------------------------------------------------------------\n// Streaming support\n// ---------------------------------------------------------------------------\n\nfunction wrapAsyncIterableStream(stream: any, span: Span): any {\n const chunks: any[] = [];\n const originalAsyncIterator = stream[Symbol.asyncIterator]?.bind(stream);\n\n if (!originalAsyncIterator) {\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n return stream;\n }\n\n const wrapped = Object.create(Object.getPrototypeOf(stream));\n Object.assign(wrapped, stream);\n\n wrapped[Symbol.asyncIterator] = function () {\n const iterator = originalAsyncIterator();\n return {\n async next(): Promise<IteratorResult<any>> {\n try {\n const result = await iterator.next();\n if (result.done) {\n finalizeStreamChunks(span, chunks);\n return result;\n }\n chunks.push(result.value);\n return result;\n } catch (err) {\n recordError(span, err);\n throw err;\n }\n },\n async return(value?: any): Promise<IteratorResult<any>> {\n finalizeStreamChunks(span, chunks);\n return iterator.return?.(value) ?? { done: true, value: undefined };\n },\n async throw(err?: any): Promise<IteratorResult<any>> {\n recordError(span, err);\n return iterator.throw?.(err) ?? { done: true, value: undefined };\n },\n };\n };\n\n return wrapped;\n}\n\nfunction finalizeStreamChunks(span: Span, chunks: any[]): void {\n const textParts: string[] = [];\n const toolCallsAcc: Record<number, { id: string; name: string; arguments: string }> = {};\n let finishReason = '';\n let model = '';\n let usage: any = null;\n\n for (const chunk of chunks) {\n if (!chunk?.choices?.length) {\n if (chunk?.usage) usage = chunk.usage;\n continue;\n }\n const choice = chunk.choices[0];\n const delta = choice?.delta;\n if (delta?.content) textParts.push(delta.content);\n if (delta?.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index ?? 0;\n if (!toolCallsAcc[idx]) toolCallsAcc[idx] = { id: '', name: '', arguments: '' };\n if (tc.id) toolCallsAcc[idx].id = tc.id;\n if (tc.function?.name) toolCallsAcc[idx].name = tc.function.name;\n if (tc.function?.arguments) toolCallsAcc[idx].arguments += tc.function.arguments;\n }\n }\n if (choice?.finish_reason) finishReason = choice.finish_reason;\n if (chunk?.model) model = chunk.model;\n }\n\n const fullText = textParts.join('');\n if (fullText) {\n span.setAttribute('neatlogs.llm.output_messages.0.role', 'assistant');\n span.setAttribute('neatlogs.llm.output_messages.0.content', fullText);\n }\n\n let j = 0;\n for (const tc of Object.values(toolCallsAcc)) {\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id);\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.name);\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.arguments);\n j++;\n }\n\n if (model) span.setAttribute('neatlogs.llm.model_name', model);\n if (finishReason) span.setAttribute('neatlogs.llm.finish_reason', finishReason);\n\n if (usage) {\n if (usage.prompt_tokens != null) span.setAttribute('neatlogs.llm.token_count.prompt', usage.prompt_tokens);\n if (usage.completion_tokens != null) span.setAttribute('neatlogs.llm.token_count.completion', usage.completion_tokens);\n if (usage.total_tokens != null) span.setAttribute('neatlogs.llm.token_count.total', usage.total_tokens);\n if (usage.prompt_tokens_details?.cached_tokens != null) {\n span.setAttribute('neatlogs.llm.token_count.cache_read', usage.prompt_tokens_details.cached_tokens);\n }\n if (usage.completion_tokens_details?.reasoning_tokens != null) {\n span.setAttribute('neatlogs.llm.token_count.reasoning', usage.completion_tokens_details.reasoning_tokens);\n }\n }\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n}\n\n// ---------------------------------------------------------------------------\n// Non-streaming response finalization\n// ---------------------------------------------------------------------------\n\nfunction finalizeChatResponse(span: Span, response: any): void {\n const choices = response?.choices ?? [];\n for (let i = 0; i < choices.length; i++) {\n const message = choices[i]?.message;\n if (!message) continue;\n\n span.setAttribute(`neatlogs.llm.output_messages.${i}.role`, 'assistant');\n if (message.content) {\n span.setAttribute(`neatlogs.llm.output_messages.${i}.content`, message.content);\n }\n if (message.tool_calls) {\n for (let j = 0; j < message.tool_calls.length; j++) {\n const tc = message.tool_calls[j];\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.id`, tc.id ?? '');\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.name`, tc.function?.name ?? '');\n span.setAttribute(`neatlogs.llm.tool_calls.${j}.arguments`, tc.function?.arguments ?? '');\n }\n }\n if (choices[i].finish_reason) {\n span.setAttribute('neatlogs.llm.finish_reason', choices[i].finish_reason);\n }\n }\n\n const usage = response?.usage;\n if (usage) {\n if (usage.prompt_tokens != null) span.setAttribute('neatlogs.llm.token_count.prompt', usage.prompt_tokens);\n if (usage.completion_tokens != null) span.setAttribute('neatlogs.llm.token_count.completion', usage.completion_tokens);\n if (usage.total_tokens != null) span.setAttribute('neatlogs.llm.token_count.total', usage.total_tokens);\n if (usage.prompt_tokens_details?.cached_tokens != null) {\n span.setAttribute('neatlogs.llm.token_count.cache_read', usage.prompt_tokens_details.cached_tokens);\n }\n if (usage.completion_tokens_details?.reasoning_tokens != null) {\n span.setAttribute('neatlogs.llm.token_count.reasoning', usage.completion_tokens_details.reasoning_tokens);\n }\n }\n\n if (response?.model) span.setAttribute('neatlogs.llm.model_name', response.model);\n\n span.setStatus({ code: SpanStatusCode.OK });\n span.end();\n}\n\n// ---------------------------------------------------------------------------\n// Utilities\n// ---------------------------------------------------------------------------\n\nfunction setInvocationParams(span: Span, opts: any): void {\n if (opts?.temperature != null) span.setAttribute('neatlogs.llm.temperature', opts.temperature);\n if (opts?.top_p != null) span.setAttribute('neatlogs.llm.top_p', opts.top_p);\n if (opts?.max_tokens != null) span.setAttribute('neatlogs.llm.max_tokens', opts.max_tokens);\n if (opts?.frequency_penalty != null) span.setAttribute('neatlogs.llm.frequency_penalty', opts.frequency_penalty);\n if (opts?.presence_penalty != null) span.setAttribute('neatlogs.llm.presence_penalty', opts.presence_penalty);\n if (opts?.stop) span.setAttribute('neatlogs.llm.stop_sequences', safeStringify(opts.stop));\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return typeof value === 'string' ? value : JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\nfunction recordError(span: Span, err: unknown): void {\n if (err instanceof Error) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });\n span.recordException(err);\n } else {\n span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) });\n }\n span.end();\n}\n"],"mappings":"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","names":[]}
|
package/dist/strands.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/strands.ts
|
|
21
|
+
var strands_exports = {};
|
|
22
|
+
__export(strands_exports, {
|
|
23
|
+
strandsHooks: () => strandsHooks
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(strands_exports);
|
|
26
|
+
function strandsHooks(agent) {
|
|
27
|
+
if (agent && typeof agent === "object") {
|
|
28
|
+
try {
|
|
29
|
+
Object.defineProperty(agent, "_neatlogs_patched", {
|
|
30
|
+
value: true,
|
|
31
|
+
enumerable: false,
|
|
32
|
+
configurable: true
|
|
33
|
+
});
|
|
34
|
+
} catch {
|
|
35
|
+
agent._neatlogs_patched = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return agent;
|
|
39
|
+
}
|
|
40
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
41
|
+
0 && (module.exports = {
|
|
42
|
+
strandsHooks
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=strands.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/strands.ts"],"sourcesContent":["/**\n * Neatlogs Strands Agents integration.\n *\n * Usage:\n * import { init } from 'neatlogs';\n * import { strandsHooks } from 'neatlogs/strands';\n * import { Agent } from '@strands-agents/sdk';\n *\n * await init({ apiKey, workflowName }); // registers the OTel tracer provider\n * const agent = strandsHooks(new Agent({ model }));\n *\n * The Strands Agents SDK emits its own OpenTelemetry spans (gen_ai.* semantic\n * conventions) for agent invocations, model calls, and tool calls. Those spans\n * flow into neatlogs automatically once `init()` has registered the global\n * tracer provider — and the neatlogs attribute mapper translates Strands'\n * `gen_ai.*` attributes into the `neatlogs.*` namespace (span kind, tool name,\n * model, token counts, etc.).\n *\n * Because Strands self-instruments and its native tracing cannot be disabled,\n * `strandsHooks()` does NOT emit its own spans — doing so would duplicate every\n * agent/model/tool span. It is a pass-through kept for API symmetry with the\n * other framework integrations: call it (or don't) — `init()` is what enables\n * capture. The function marks the agent so re-wrapping is a no-op.\n */\n\nexport function strandsHooks<T extends object>(agent: T): T {\n if (agent && typeof agent === 'object') {\n try {\n Object.defineProperty(agent, '_neatlogs_patched', {\n value: true,\n enumerable: false,\n configurable: true,\n });\n } catch {\n (agent as any)._neatlogs_patched = true;\n }\n }\n return agent;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBO,SAAS,aAA+B,OAAa;AAC1D,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,QAAI;AACF,aAAO,eAAe,OAAO,qBAAqB;AAAA,QAChD,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,QAAQ;AACN,MAAC,MAAc,oBAAoB;AAAA,IACrC;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neatlogs Strands Agents integration.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { init } from 'neatlogs';
|
|
6
|
+
* import { strandsHooks } from 'neatlogs/strands';
|
|
7
|
+
* import { Agent } from '@strands-agents/sdk';
|
|
8
|
+
*
|
|
9
|
+
* await init({ apiKey, workflowName }); // registers the OTel tracer provider
|
|
10
|
+
* const agent = strandsHooks(new Agent({ model }));
|
|
11
|
+
*
|
|
12
|
+
* The Strands Agents SDK emits its own OpenTelemetry spans (gen_ai.* semantic
|
|
13
|
+
* conventions) for agent invocations, model calls, and tool calls. Those spans
|
|
14
|
+
* flow into neatlogs automatically once `init()` has registered the global
|
|
15
|
+
* tracer provider — and the neatlogs attribute mapper translates Strands'
|
|
16
|
+
* `gen_ai.*` attributes into the `neatlogs.*` namespace (span kind, tool name,
|
|
17
|
+
* model, token counts, etc.).
|
|
18
|
+
*
|
|
19
|
+
* Because Strands self-instruments and its native tracing cannot be disabled,
|
|
20
|
+
* `strandsHooks()` does NOT emit its own spans — doing so would duplicate every
|
|
21
|
+
* agent/model/tool span. It is a pass-through kept for API symmetry with the
|
|
22
|
+
* other framework integrations: call it (or don't) — `init()` is what enables
|
|
23
|
+
* capture. The function marks the agent so re-wrapping is a no-op.
|
|
24
|
+
*/
|
|
25
|
+
declare function strandsHooks<T extends object>(agent: T): T;
|
|
26
|
+
|
|
27
|
+
export { strandsHooks };
|
package/dist/strands.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/strands.ts
|
|
2
|
+
function strandsHooks(agent) {
|
|
3
|
+
if (agent && typeof agent === "object") {
|
|
4
|
+
try {
|
|
5
|
+
Object.defineProperty(agent, "_neatlogs_patched", {
|
|
6
|
+
value: true,
|
|
7
|
+
enumerable: false,
|
|
8
|
+
configurable: true
|
|
9
|
+
});
|
|
10
|
+
} catch {
|
|
11
|
+
agent._neatlogs_patched = true;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return agent;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
strandsHooks
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=strands.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/strands.ts"],"sourcesContent":["/**\n * Neatlogs Strands Agents integration.\n *\n * Usage:\n * import { init } from 'neatlogs';\n * import { strandsHooks } from 'neatlogs/strands';\n * import { Agent } from '@strands-agents/sdk';\n *\n * await init({ apiKey, workflowName }); // registers the OTel tracer provider\n * const agent = strandsHooks(new Agent({ model }));\n *\n * The Strands Agents SDK emits its own OpenTelemetry spans (gen_ai.* semantic\n * conventions) for agent invocations, model calls, and tool calls. Those spans\n * flow into neatlogs automatically once `init()` has registered the global\n * tracer provider — and the neatlogs attribute mapper translates Strands'\n * `gen_ai.*` attributes into the `neatlogs.*` namespace (span kind, tool name,\n * model, token counts, etc.).\n *\n * Because Strands self-instruments and its native tracing cannot be disabled,\n * `strandsHooks()` does NOT emit its own spans — doing so would duplicate every\n * agent/model/tool span. It is a pass-through kept for API symmetry with the\n * other framework integrations: call it (or don't) — `init()` is what enables\n * capture. The function marks the agent so re-wrapping is a no-op.\n */\n\nexport function strandsHooks<T extends object>(agent: T): T {\n if (agent && typeof agent === 'object') {\n try {\n Object.defineProperty(agent, '_neatlogs_patched', {\n value: true,\n enumerable: false,\n configurable: true,\n });\n } catch {\n (agent as any)._neatlogs_patched = true;\n }\n }\n return agent;\n}\n"],"mappings":";AAyBO,SAAS,aAA+B,OAAa;AAC1D,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,QAAI;AACF,aAAO,eAAe,OAAO,qBAAqB;AAAA,QAChD,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAAA,IACH,QAAQ;AACN,MAAC,MAAc,oBAAoB;AAAA,IACrC;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neatlogs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "AI agent debugging, collaboration, and trace observability. Built for teams using CrewAI, OpenAI, and more.",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
10
|
"import": {
|
|
11
|
-
"types": "./dist/index.d.
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
12
|
"default": "./dist/index.mjs"
|
|
13
13
|
},
|
|
14
14
|
"require": {
|
|
@@ -18,13 +18,73 @@
|
|
|
18
18
|
},
|
|
19
19
|
"./ai": {
|
|
20
20
|
"import": {
|
|
21
|
-
"types": "./dist/ai-sdk.d.
|
|
21
|
+
"types": "./dist/ai-sdk.d.ts",
|
|
22
22
|
"default": "./dist/ai-sdk.mjs"
|
|
23
23
|
},
|
|
24
24
|
"require": {
|
|
25
25
|
"types": "./dist/ai-sdk.d.ts",
|
|
26
26
|
"default": "./dist/ai-sdk.cjs"
|
|
27
27
|
}
|
|
28
|
+
},
|
|
29
|
+
"./openai": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/openai.d.ts",
|
|
32
|
+
"default": "./dist/openai.mjs"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/openai.d.ts",
|
|
36
|
+
"default": "./dist/openai.cjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"./anthropic": {
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./dist/anthropic.d.ts",
|
|
42
|
+
"default": "./dist/anthropic.mjs"
|
|
43
|
+
},
|
|
44
|
+
"require": {
|
|
45
|
+
"types": "./dist/anthropic.d.ts",
|
|
46
|
+
"default": "./dist/anthropic.cjs"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"./langchain": {
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/langchain.d.ts",
|
|
52
|
+
"default": "./dist/langchain.mjs"
|
|
53
|
+
},
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./dist/langchain.d.ts",
|
|
56
|
+
"default": "./dist/langchain.cjs"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"./strands": {
|
|
60
|
+
"import": {
|
|
61
|
+
"types": "./dist/strands.d.ts",
|
|
62
|
+
"default": "./dist/strands.mjs"
|
|
63
|
+
},
|
|
64
|
+
"require": {
|
|
65
|
+
"types": "./dist/strands.d.ts",
|
|
66
|
+
"default": "./dist/strands.cjs"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"./openai-agents": {
|
|
70
|
+
"import": {
|
|
71
|
+
"types": "./dist/openai-agents.d.ts",
|
|
72
|
+
"default": "./dist/openai-agents.mjs"
|
|
73
|
+
},
|
|
74
|
+
"require": {
|
|
75
|
+
"types": "./dist/openai-agents.d.ts",
|
|
76
|
+
"default": "./dist/openai-agents.cjs"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
"./mastra": {
|
|
80
|
+
"import": {
|
|
81
|
+
"types": "./dist/mastra-wrap.d.ts",
|
|
82
|
+
"default": "./dist/mastra-wrap.mjs"
|
|
83
|
+
},
|
|
84
|
+
"require": {
|
|
85
|
+
"types": "./dist/mastra-wrap.d.ts",
|
|
86
|
+
"default": "./dist/mastra-wrap.cjs"
|
|
87
|
+
}
|
|
28
88
|
}
|
|
29
89
|
},
|
|
30
90
|
"files": [
|
|
@@ -61,9 +121,6 @@
|
|
|
61
121
|
"license": "MIT",
|
|
62
122
|
"dependencies": {
|
|
63
123
|
"@ai-sdk/cohere": "^3.0.36",
|
|
64
|
-
"@mastra/observability": "^1.11.1",
|
|
65
|
-
"@neatlogs/instrumentation-google-genai": "^0.1.2",
|
|
66
|
-
"@neatlogs/instrumentation-mastra": "^0.1.2",
|
|
67
124
|
"@opentelemetry/api": "^1.9.0",
|
|
68
125
|
"@opentelemetry/api-logs": "^0.57.0",
|
|
69
126
|
"@opentelemetry/exporter-logs-otlp-proto": "^0.216.0",
|
|
@@ -76,10 +133,11 @@
|
|
|
76
133
|
"@opentelemetry/sdk-metrics": "^1.30.0",
|
|
77
134
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|
|
78
135
|
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
79
|
-
"@opentelemetry/semantic-conventions": "^1.28.0"
|
|
136
|
+
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
137
|
+
"neatlogs": "^1.0.3"
|
|
80
138
|
},
|
|
81
139
|
"devDependencies": {
|
|
82
|
-
"@ai-sdk/azure": "^3.0.
|
|
140
|
+
"@ai-sdk/azure": "^3.0.66",
|
|
83
141
|
"@ai-sdk/openai": "^3.0.64",
|
|
84
142
|
"@anthropic-ai/bedrock-sdk": "^0.29.1",
|
|
85
143
|
"@anthropic-ai/sdk": "^0.68.0",
|
|
@@ -94,7 +152,7 @@
|
|
|
94
152
|
"@langchain/langgraph": "^0.3.12",
|
|
95
153
|
"@langchain/openai": "^0.6.17",
|
|
96
154
|
"@types/node": "^20.0.0",
|
|
97
|
-
"ai": "^6.0.
|
|
155
|
+
"ai": "^6.0.190",
|
|
98
156
|
"dotenv": "^17.4.2",
|
|
99
157
|
"openai": "^6.34.0",
|
|
100
158
|
"tsup": "^8.0.0",
|
|
@@ -113,7 +171,10 @@
|
|
|
113
171
|
"@arizeai/openinference-instrumentation-mcp": ">=1.0.0",
|
|
114
172
|
"@arizeai/openinference-instrumentation-openai": ">=1.0.0",
|
|
115
173
|
"@google/genai": ">=0.1.0",
|
|
116
|
-
"@mastra/core": "^1.32.1"
|
|
174
|
+
"@mastra/core": "^1.32.1",
|
|
175
|
+
"@mastra/observability": "^1.11.1",
|
|
176
|
+
"@neatlogs/instrumentation-google-genai": "^0.1.2",
|
|
177
|
+
"@neatlogs/instrumentation-mastra": "^0.1.2"
|
|
117
178
|
},
|
|
118
179
|
"peerDependenciesMeta": {
|
|
119
180
|
"@arizeai/openinference-instrumentation-openai": {
|
|
@@ -142,6 +203,15 @@
|
|
|
142
203
|
},
|
|
143
204
|
"@mastra/core": {
|
|
144
205
|
"optional": true
|
|
206
|
+
},
|
|
207
|
+
"@mastra/observability": {
|
|
208
|
+
"optional": true
|
|
209
|
+
},
|
|
210
|
+
"@neatlogs/instrumentation-google-genai": {
|
|
211
|
+
"optional": true
|
|
212
|
+
},
|
|
213
|
+
"@neatlogs/instrumentation-mastra": {
|
|
214
|
+
"optional": true
|
|
145
215
|
}
|
|
146
216
|
}
|
|
147
217
|
}
|