neatlogs 1.0.4 → 1.0.6
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 +1999 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.mjs +1993 -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/pi-agent.cjs +237 -0
- package/dist/pi-agent.cjs.map +1 -0
- package/dist/pi-agent.d.ts +31 -0
- package/dist/pi-agent.mjs +216 -0
- package/dist/pi-agent.mjs.map +1 -0
- package/dist/strands.cjs +167 -0
- package/dist/strands.cjs.map +1 -0
- package/dist/strands.d.ts +28 -0
- package/dist/strands.mjs +142 -0
- package/dist/strands.mjs.map +1 -0
- package/package.json +75 -3
|
@@ -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 });\n * const agent = strandsHooks(new Agent({ model }));\n *\n * Strands self-instruments via native OpenTelemetry (gen_ai.* spans for agent /\n * model / tool calls), which `init()` captures and the attribute mapper classifies\n * (kind, model, token counts).\n *\n * BUT Strands records prompt/response CONTENT as OTel span EVENTS\n * (gen_ai.user.message, gen_ai.system.message, gen_ai.choice, gen_ai.tool.message,\n * gen_ai.client.inference.operation.details) — not as span attributes. neatlogs\n * renders I/O from attributes, so without help those spans show tokens but EMPTY\n * input/output. `strandsHooks()` installs a single class-level hook on Strands'\n * own `Tracer._addEvent` chokepoint: after Strands records a message/choice event,\n * we also copy its content onto the span as input.value / output.value (+ the LLM\n * message attributes). We do NOT create spans — Strands' native tracing stays the\n * source of truth; we only enrich it. Mirrors the Python SDK's strands hook.\n */\n\nconst PATCH_FLAG = '_neatlogs_patched';\n\nexport function strandsHooks<T extends object>(agent: T): T {\n // Each Strands Agent constructs its OWN private Tracer (`agent._tracer = new\n // Tracer(...)`), and the Tracer class is NOT publicly exported — so we reach it\n // through the agent instance and patch its `_addEvent` chokepoint. Patching the\n // PROTOTYPE (reached via the instance) covers every agent sharing that class and\n // is idempotent. This is the only access path: the package's exports map blocks\n // deep imports and the top-level index doesn't export Tracer.\n installEventHookFromAgent(agent);\n\n if (agent && typeof agent === 'object') {\n try {\n Object.defineProperty(agent, PATCH_FLAG, {\n value: true,\n enumerable: false,\n configurable: true,\n });\n } catch {\n (agent as any)[PATCH_FLAG] = true;\n }\n }\n return agent;\n}\n\nfunction installEventHookFromAgent(agent: any): void {\n const tracer = agent?._tracer;\n const proto = tracer ? Object.getPrototypeOf(tracer) : undefined;\n if (!proto || typeof proto._addEvent !== 'function') return;\n if (proto._addEvent[PATCH_FLAG]) return;\n\n const orig = proto._addEvent;\n function patchedAddEvent(this: any, span: any, eventName: string, eventAttributes?: Record<string, unknown>) {\n const result = orig.call(this, span, eventName, eventAttributes);\n try {\n enrichSpanFromEvent(span, eventName, eventAttributes || {});\n } catch {\n // never break the agent run over tracing\n }\n return result;\n }\n (patchedAddEvent as any)[PATCH_FLAG] = true;\n proto._addEvent = patchedAddEvent;\n}\n\nfunction enrichSpanFromEvent(\n span: any,\n eventName: string,\n attrs: Record<string, unknown>,\n): void {\n if (!span || typeof span.setAttribute !== 'function') return;\n if (typeof span.isRecording === 'function' && !span.isRecording()) return;\n\n // Classify from the span's own gen_ai.operation.name (set at creation): the same\n // message/choice events fire on chat (LLM), execute_tool (TOOL) and agent spans.\n // We don't set neatlogs.span.kind (the mapper does, from the span name); we only\n // route I/O to the correct namespace so a {span_kind}-templated key isn't needed.\n const isTool = readSpanOp(span) === 'execute_tool';\n\n // Input-side messages: gen_ai.{system,user,assistant,tool}.message\n if (eventName.startsWith('gen_ai.') && eventName.endsWith('.message')) {\n const role = eventName.slice('gen_ai.'.length, -'.message'.length);\n const content = flattenStrandsContent(attrs.content);\n if (content) {\n if (isTool) {\n span.setAttribute('input.value', content);\n span.setAttribute('neatlogs.tool.input', content);\n } else {\n appendInputMessage(span, role, content);\n }\n }\n return;\n }\n\n // Output: legacy gen_ai.choice or the latest-convention details event.\n if (eventName === 'gen_ai.choice') {\n const out = flattenStrandsContent(attrs.message);\n if (out) setOutput(span, isTool, out);\n return;\n }\n if (eventName === 'gen_ai.client.inference.operation.details') {\n const out = flattenStrandsContent(attrs['gen_ai.output.messages']);\n if (out) setOutput(span, isTool, out);\n }\n}\n\nfunction setOutput(span: any, isTool: boolean, out: string): void {\n span.setAttribute('output.value', out);\n if (isTool) {\n span.setAttribute('neatlogs.tool.output', out);\n } else {\n span.setAttribute('neatlogs.llm.output_messages.0.role', 'assistant');\n span.setAttribute('neatlogs.llm.output_messages.0.content', out);\n span.setAttribute('neatlogs.llm.output', safeStringify({ role: 'assistant', content: out }));\n }\n}\n\nfunction appendInputMessage(span: any, role: string, content: string): void {\n const idx = (span.__neatlogs_in_idx as number) ?? 0;\n span.setAttribute(`neatlogs.llm.input_messages.${idx}.role`, role);\n span.setAttribute(`neatlogs.llm.input_messages.${idx}.content`, content);\n span.__neatlogs_in_idx = idx + 1;\n const existing: Array<{ role: string; content: string }> = span.__neatlogs_in_msgs ?? [];\n existing.push({ role, content });\n span.__neatlogs_in_msgs = existing;\n const blob = safeStringify({ messages: existing });\n span.setAttribute('input.value', blob);\n // Flat LLM input the backend reads directly (no reliance on {span_kind} mapping).\n span.setAttribute('neatlogs.llm.input', blob);\n}\n\nfunction readSpanOp(span: any): string {\n // OTel spans don't expose attributes publicly; Strands' span objects carry them\n // on `.attributes`. Best-effort read of gen_ai.operation.name.\n try {\n const a = span.attributes;\n if (!a) return '';\n const v = typeof a.get === 'function' ? a.get('gen_ai.operation.name') : a['gen_ai.operation.name'];\n return typeof v === 'string' ? v.toLowerCase() : '';\n } catch {\n return '';\n }\n}\n\n/**\n * Strands event content arrives as a JSON string of content blocks\n * ([{text}], [{toolUse|toolResult}], or {role,parts,...}) or a plain string.\n */\nfunction flattenStrandsContent(content: unknown): string {\n if (content == null) return '';\n let val: unknown = content;\n if (typeof val === 'string') {\n const s = val.trim();\n if (!(s.startsWith('[') || s.startsWith('{'))) return val; // already plain text\n try {\n val = JSON.parse(s);\n } catch {\n return val as string;\n }\n }\n return flattenBlocks(val);\n}\n\nfunction flattenBlocks(val: unknown): string {\n const items = Array.isArray(val) ? val : [val];\n const out: string[] = [];\n for (const item of items) {\n if (typeof item === 'string') {\n out.push(item);\n continue;\n }\n if (!item || typeof item !== 'object') {\n if (item != null) out.push(String(item));\n continue;\n }\n const o = item as Record<string, any>;\n if (typeof o.text === 'string') out.push(o.text);\n else if (typeof o.content === 'string') out.push(o.content);\n else if (o.toolUse) out.push(`${o.toolUse.name ?? 'tool'}(${safeStringify(o.toolUse.input ?? {})})`);\n else if (o.toolResult) out.push(flattenBlocks(o.toolResult.content ?? o.toolResult));\n else if (Array.isArray(o.parts)) out.push(flattenBlocks(o.parts));\n else if (Array.isArray(o.content)) out.push(flattenBlocks(o.content));\n else out.push(safeStringify(o));\n }\n return out.filter(Boolean).join('\\n');\n}\n\nfunction safeStringify(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value) ?? '';\n } catch {\n return '';\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neatlogs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
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,83 @@
|
|
|
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
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"./pi-agent": {
|
|
90
|
+
"import": {
|
|
91
|
+
"types": "./dist/pi-agent.d.ts",
|
|
92
|
+
"default": "./dist/pi-agent.mjs"
|
|
93
|
+
},
|
|
94
|
+
"require": {
|
|
95
|
+
"types": "./dist/pi-agent.d.ts",
|
|
96
|
+
"default": "./dist/pi-agent.cjs"
|
|
97
|
+
}
|
|
28
98
|
}
|
|
29
99
|
},
|
|
30
100
|
"files": [
|
|
@@ -34,6 +104,8 @@
|
|
|
34
104
|
"node": ">=18.0.0"
|
|
35
105
|
},
|
|
36
106
|
"scripts": {
|
|
107
|
+
"version:sync": "node scripts/sync-version.mjs",
|
|
108
|
+
"prebuild": "node scripts/sync-version.mjs",
|
|
37
109
|
"build": "tsup && rm -f dist/*.d.mts",
|
|
38
110
|
"test": "vitest run",
|
|
39
111
|
"test:watch": "vitest",
|