@prefactor/langchain 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +252 -0
- package/dist/index.cjs.map +13 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +233 -0
- package/dist/index.js.map +13 -0
- package/dist/init.d.ts +76 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +153 -0
- package/dist/init.js.map +1 -0
- package/dist/metadata-extractor.d.ts +20 -0
- package/dist/metadata-extractor.d.ts.map +1 -0
- package/dist/metadata-extractor.js +54 -0
- package/dist/metadata-extractor.js.map +1 -0
- package/dist/middleware.d.ts +84 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +180 -0
- package/dist/middleware.js.map +1 -0
- package/package.json +40 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
6
|
+
var __toCommonJS = (from) => {
|
|
7
|
+
var entry = __moduleCache.get(from), desc;
|
|
8
|
+
if (entry)
|
|
9
|
+
return entry;
|
|
10
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
12
|
+
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
13
|
+
get: () => from[key],
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
}));
|
|
16
|
+
__moduleCache.set(from, entry);
|
|
17
|
+
return entry;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, {
|
|
22
|
+
get: all[name],
|
|
23
|
+
enumerable: true,
|
|
24
|
+
configurable: true,
|
|
25
|
+
set: (newValue) => all[name] = () => newValue
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// packages/langchain/src/index.ts
|
|
30
|
+
var exports_src = {};
|
|
31
|
+
__export(exports_src, {
|
|
32
|
+
shutdown: () => shutdown,
|
|
33
|
+
init: () => init,
|
|
34
|
+
getTracer: () => getTracer,
|
|
35
|
+
extractTokenUsage: () => extractTokenUsage,
|
|
36
|
+
SpanType: () => import_core3.SpanType,
|
|
37
|
+
SpanStatus: () => import_core3.SpanStatus,
|
|
38
|
+
PrefactorMiddleware: () => PrefactorMiddleware
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(exports_src);
|
|
41
|
+
var import_core3 = require("@prefactor/core");
|
|
42
|
+
|
|
43
|
+
// packages/langchain/src/init.ts
|
|
44
|
+
var import_core2 = require("@prefactor/core");
|
|
45
|
+
var import_pfid = require("@prefactor/pfid");
|
|
46
|
+
var import_langchain = require("langchain");
|
|
47
|
+
|
|
48
|
+
// packages/langchain/src/middleware.ts
|
|
49
|
+
var import_core = require("@prefactor/core");
|
|
50
|
+
|
|
51
|
+
// packages/langchain/src/metadata-extractor.ts
|
|
52
|
+
function extractTokenUsage(response) {
|
|
53
|
+
try {
|
|
54
|
+
const tokenUsage = response?.token_usage ?? response?.usage;
|
|
55
|
+
if (tokenUsage) {
|
|
56
|
+
return {
|
|
57
|
+
promptTokens: tokenUsage.prompt_tokens ?? 0,
|
|
58
|
+
completionTokens: tokenUsage.completion_tokens ?? 0,
|
|
59
|
+
totalTokens: tokenUsage.total_tokens ?? 0
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const usageMetadata = response?.usage_metadata;
|
|
63
|
+
if (usageMetadata) {
|
|
64
|
+
return {
|
|
65
|
+
promptTokens: usageMetadata.input_tokens ?? 0,
|
|
66
|
+
completionTokens: usageMetadata.output_tokens ?? 0,
|
|
67
|
+
totalTokens: usageMetadata.total_tokens ?? 0
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const responseMetadata = response?.response_metadata;
|
|
71
|
+
if (responseMetadata?.token_usage) {
|
|
72
|
+
return {
|
|
73
|
+
promptTokens: responseMetadata.token_usage.prompt_tokens ?? 0,
|
|
74
|
+
completionTokens: responseMetadata.token_usage.completion_tokens ?? 0,
|
|
75
|
+
totalTokens: responseMetadata.token_usage.total_tokens ?? 0
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// packages/langchain/src/middleware.ts
|
|
85
|
+
class PrefactorMiddleware {
|
|
86
|
+
tracer;
|
|
87
|
+
rootSpan = null;
|
|
88
|
+
constructor(tracer) {
|
|
89
|
+
this.tracer = tracer;
|
|
90
|
+
}
|
|
91
|
+
async beforeAgent(state) {
|
|
92
|
+
const parentSpan = import_core.SpanContext.getCurrent();
|
|
93
|
+
const messages = state?.messages ?? [];
|
|
94
|
+
this.tracer.startAgentInstance();
|
|
95
|
+
const span = this.tracer.startSpan({
|
|
96
|
+
name: "agent",
|
|
97
|
+
spanType: import_core.SpanType.AGENT,
|
|
98
|
+
inputs: { messages: messages.slice(-3).map((m) => String(m)) },
|
|
99
|
+
parentSpanId: parentSpan?.spanId,
|
|
100
|
+
traceId: parentSpan?.traceId
|
|
101
|
+
});
|
|
102
|
+
this.rootSpan = span;
|
|
103
|
+
}
|
|
104
|
+
async afterAgent(state) {
|
|
105
|
+
if (!this.rootSpan) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const messages = state?.messages ?? [];
|
|
109
|
+
this.tracer.endSpan(this.rootSpan, {
|
|
110
|
+
outputs: { messages: messages.slice(-3).map((m) => String(m)) }
|
|
111
|
+
});
|
|
112
|
+
this.tracer.finishAgentInstance();
|
|
113
|
+
import_core.SpanContext.clear();
|
|
114
|
+
this.rootSpan = null;
|
|
115
|
+
}
|
|
116
|
+
async wrapModelCall(request, handler) {
|
|
117
|
+
const parentSpan = import_core.SpanContext.getCurrent();
|
|
118
|
+
const span = this.tracer.startSpan({
|
|
119
|
+
name: this.extractModelName(request),
|
|
120
|
+
spanType: import_core.SpanType.LLM,
|
|
121
|
+
inputs: this.extractModelInputs(request),
|
|
122
|
+
parentSpanId: parentSpan?.spanId,
|
|
123
|
+
traceId: parentSpan?.traceId
|
|
124
|
+
});
|
|
125
|
+
try {
|
|
126
|
+
const response = await import_core.SpanContext.runAsync(span, async () => {
|
|
127
|
+
return handler(request);
|
|
128
|
+
});
|
|
129
|
+
const outputs = this.extractModelOutputs(response);
|
|
130
|
+
const tokenUsage = extractTokenUsage(response);
|
|
131
|
+
this.tracer.endSpan(span, { outputs, tokenUsage: tokenUsage ?? undefined });
|
|
132
|
+
return response;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
this.tracer.endSpan(span, { error });
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async wrapToolCall(request, handler) {
|
|
139
|
+
const parentSpan = import_core.SpanContext.getCurrent();
|
|
140
|
+
const span = this.tracer.startSpan({
|
|
141
|
+
name: this.extractToolName(request),
|
|
142
|
+
spanType: import_core.SpanType.TOOL,
|
|
143
|
+
inputs: this.extractToolInputs(request),
|
|
144
|
+
parentSpanId: parentSpan?.spanId,
|
|
145
|
+
traceId: parentSpan?.traceId
|
|
146
|
+
});
|
|
147
|
+
try {
|
|
148
|
+
const response = await import_core.SpanContext.runAsync(span, async () => {
|
|
149
|
+
return handler(request);
|
|
150
|
+
});
|
|
151
|
+
this.tracer.endSpan(span, {
|
|
152
|
+
outputs: this.extractToolOutputs(response)
|
|
153
|
+
});
|
|
154
|
+
return response;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this.tracer.endSpan(span, { error });
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
extractModelName(request) {
|
|
161
|
+
return request?.model ?? request?.modelName ?? "unknown";
|
|
162
|
+
}
|
|
163
|
+
extractModelInputs(request) {
|
|
164
|
+
const messages = request?.messages ?? [];
|
|
165
|
+
return { messages: messages.slice(-3).map((m) => String(m)) };
|
|
166
|
+
}
|
|
167
|
+
extractModelOutputs(response) {
|
|
168
|
+
const content = response?.content ?? response?.text ?? "";
|
|
169
|
+
return { content: String(content) };
|
|
170
|
+
}
|
|
171
|
+
extractToolName(request) {
|
|
172
|
+
return request?.name ?? request?.tool ?? "unknown";
|
|
173
|
+
}
|
|
174
|
+
extractToolInputs(request) {
|
|
175
|
+
return { input: request?.input ?? request?.args ?? {} };
|
|
176
|
+
}
|
|
177
|
+
extractToolOutputs(response) {
|
|
178
|
+
return { output: response?.output ?? response };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// packages/langchain/src/init.ts
|
|
183
|
+
var logger = import_core2.getLogger("init");
|
|
184
|
+
var globalTracer = null;
|
|
185
|
+
var globalMiddleware = null;
|
|
186
|
+
function init(config) {
|
|
187
|
+
import_core2.configureLogging();
|
|
188
|
+
const finalConfig = import_core2.createConfig(config);
|
|
189
|
+
logger.info("Initializing Prefactor SDK", { transport: finalConfig.transportType });
|
|
190
|
+
if (globalMiddleware !== null) {
|
|
191
|
+
return globalMiddleware;
|
|
192
|
+
}
|
|
193
|
+
let transport;
|
|
194
|
+
if (finalConfig.transportType === "stdio") {
|
|
195
|
+
transport = new import_core2.StdioTransport;
|
|
196
|
+
} else {
|
|
197
|
+
if (!finalConfig.httpConfig) {
|
|
198
|
+
throw new Error("HTTP transport requires httpConfig to be provided in configuration");
|
|
199
|
+
}
|
|
200
|
+
const httpConfig = import_core2.HttpTransportConfigSchema.parse(finalConfig.httpConfig);
|
|
201
|
+
transport = new import_core2.HttpTransport(httpConfig);
|
|
202
|
+
}
|
|
203
|
+
let partition;
|
|
204
|
+
if (finalConfig.httpConfig?.agentId) {
|
|
205
|
+
try {
|
|
206
|
+
partition = import_pfid.extractPartition(finalConfig.httpConfig.agentId);
|
|
207
|
+
logger.debug("Extracted partition from agent_id", { partition });
|
|
208
|
+
} catch (error) {
|
|
209
|
+
logger.warn("Failed to extract partition from agent_id, using random partition", { error });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
globalTracer = new import_core2.Tracer(transport, partition);
|
|
213
|
+
const prefactorMiddleware = new PrefactorMiddleware(globalTracer);
|
|
214
|
+
const middleware = import_langchain.createMiddleware({
|
|
215
|
+
name: "prefactor",
|
|
216
|
+
wrapModelCall: async (request, handler) => {
|
|
217
|
+
return prefactorMiddleware.wrapModelCall(request, handler);
|
|
218
|
+
},
|
|
219
|
+
wrapToolCall: async (request, handler) => {
|
|
220
|
+
return prefactorMiddleware.wrapToolCall(request, handler);
|
|
221
|
+
},
|
|
222
|
+
beforeAgent: async (state) => {
|
|
223
|
+
await prefactorMiddleware.beforeAgent(state);
|
|
224
|
+
},
|
|
225
|
+
afterAgent: async (state) => {
|
|
226
|
+
await prefactorMiddleware.afterAgent(state);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
globalMiddleware = middleware;
|
|
230
|
+
return middleware;
|
|
231
|
+
}
|
|
232
|
+
function getTracer() {
|
|
233
|
+
if (!globalTracer) {
|
|
234
|
+
init();
|
|
235
|
+
}
|
|
236
|
+
return globalTracer;
|
|
237
|
+
}
|
|
238
|
+
async function shutdown() {
|
|
239
|
+
if (globalTracer) {
|
|
240
|
+
logger.info("Shutting down Prefactor SDK");
|
|
241
|
+
await globalTracer.close();
|
|
242
|
+
}
|
|
243
|
+
globalTracer = null;
|
|
244
|
+
globalMiddleware = null;
|
|
245
|
+
}
|
|
246
|
+
process.on("beforeExit", () => {
|
|
247
|
+
shutdown().catch((error) => {
|
|
248
|
+
console.error("Error during Prefactor SDK shutdown:", error);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
//# debugId=46B60F8DD9AA982064756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/init.ts", "../src/middleware.ts", "../src/metadata-extractor.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Main entry points\n\n// Convenience re-exports from core\nexport {\n type Config,\n type HttpTransportConfig,\n type Span,\n SpanStatus,\n SpanType,\n} from '@prefactor/core';\nexport { getTracer, init, shutdown } from './init.js';\nexport { extractTokenUsage } from './metadata-extractor.js';\n// Middleware\nexport { PrefactorMiddleware } from './middleware.js';\n",
|
|
6
|
+
"import {\n type Config,\n configureLogging,\n createConfig,\n getLogger,\n HttpTransport,\n HttpTransportConfigSchema,\n StdioTransport,\n Tracer,\n type Transport,\n} from '@prefactor/core';\nimport { extractPartition, type Partition } from '@prefactor/pfid';\nimport { type AgentMiddleware, createMiddleware } from 'langchain';\nimport { PrefactorMiddleware } from './middleware.js';\n\nconst logger = getLogger('init');\n\nlet globalTracer: Tracer | null = null;\nlet globalMiddleware: AgentMiddleware | null = null;\n\n/**\n * Initialize the Prefactor SDK and return middleware for LangChain.js\n *\n * This is the main entry point for the SDK. Call this function to create a middleware\n * instance that you can pass to your LangChain.js agents.\n *\n * @param config - Optional configuration object\n * @returns PrefactorMiddleware instance to use with LangChain.js agents\n *\n * @example\n * ```typescript\n * import { init } from '@prefactor/langchain';\n * import { createAgent } from 'langchain';\n *\n * // Initialize with defaults (stdio transport)\n * const middleware = init();\n *\n * // Or configure HTTP transport\n * const middleware = init({\n * transportType: 'http',\n * httpConfig: {\n * apiUrl: 'https://api.prefactor.ai',\n * apiToken: process.env.PREFACTOR_API_TOKEN!,\n * }\n * });\n *\n * const agent = createAgent({\n * model: 'claude-sonnet-4-5-20250929',\n * tools: [myTool],\n * middleware: [middleware],\n * });\n * ```\n */\nexport function init(config?: Partial<Config>): AgentMiddleware {\n configureLogging();\n\n const finalConfig = createConfig(config);\n logger.info('Initializing Prefactor SDK', { transport: finalConfig.transportType });\n\n if (globalMiddleware !== null) {\n return globalMiddleware;\n }\n\n let transport: Transport;\n if (finalConfig.transportType === 'stdio') {\n transport = new StdioTransport();\n } else {\n if (!finalConfig.httpConfig) {\n throw new Error('HTTP transport requires httpConfig to be provided in configuration');\n }\n // Parse httpConfig to apply defaults from schema\n const httpConfig = HttpTransportConfigSchema.parse(finalConfig.httpConfig);\n transport = new HttpTransport(httpConfig);\n }\n\n // Extract partition from agent_id if provided (for HTTP transport)\n let partition: Partition | undefined;\n if (finalConfig.httpConfig?.agentId) {\n try {\n partition = extractPartition(finalConfig.httpConfig.agentId);\n logger.debug('Extracted partition from agent_id', { partition });\n } catch (error) {\n logger.warn('Failed to extract partition from agent_id, using random partition', { error });\n }\n }\n\n globalTracer = new Tracer(transport, partition);\n const prefactorMiddleware = new PrefactorMiddleware(globalTracer);\n\n const middleware = createMiddleware({\n name: 'prefactor',\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n wrapModelCall: async (request: any, handler: any) => {\n return prefactorMiddleware.wrapModelCall(request, handler);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n wrapToolCall: async (request: any, handler: any) => {\n return prefactorMiddleware.wrapToolCall(request, handler);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n beforeAgent: async (state: any) => {\n await prefactorMiddleware.beforeAgent(state);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n afterAgent: async (state: any) => {\n await prefactorMiddleware.afterAgent(state);\n },\n });\n\n globalMiddleware = middleware;\n return middleware;\n}\n\n/**\n * Get the current tracer instance.\n *\n * If no tracer has been created yet, this will call init() with default configuration.\n *\n * @returns Tracer instance\n *\n * @example\n * ```typescript\n * import { getTracer } from '@prefactor/langchain';\n *\n * const tracer = getTracer();\n * const span = tracer.startSpan({\n * name: 'custom-operation',\n * spanType: SpanType.TOOL,\n * inputs: { data: 'example' }\n * });\n * ```\n */\nexport function getTracer(): Tracer {\n if (!globalTracer) {\n init();\n }\n // Safe because init() always sets globalTracer\n return globalTracer as Tracer;\n}\n\n/**\n * Shutdown the SDK and flush any pending spans.\n *\n * Call this before your application exits to ensure all spans are sent to the transport.\n * This is especially important for HTTP transport which has a queue of pending requests.\n *\n * @returns Promise that resolves when shutdown is complete\n *\n * @example\n * ```typescript\n * import { shutdown } from '@prefactor/langchain';\n *\n * process.on('SIGTERM', async () => {\n * await shutdown();\n * process.exit(0);\n * });\n * ```\n */\nexport async function shutdown(): Promise<void> {\n if (globalTracer) {\n logger.info('Shutting down Prefactor SDK');\n await globalTracer.close();\n }\n globalTracer = null;\n globalMiddleware = null;\n}\n\n// Automatic shutdown on process exit\nprocess.on('beforeExit', () => {\n shutdown().catch((error) => {\n console.error('Error during Prefactor SDK shutdown:', error);\n });\n});\n",
|
|
7
|
+
"import { type Span, SpanContext, SpanType, type Tracer } from '@prefactor/core';\nimport { extractTokenUsage } from './metadata-extractor.js';\n\n/**\n * Prefactor middleware for LangChain.js agents.\n *\n * This middleware automatically traces LLM calls, tool executions, and agent workflows.\n * It integrates with LangChain.js middleware API to provide transparent instrumentation.\n *\n * Features:\n * - Automatic parent-child span relationships via context propagation\n * - Token usage extraction for LLM calls\n * - Error tracking and debugging\n * - Zero-overhead instrumentation (graceful failure)\n *\n * @example\n * ```typescript\n * import { init } from '@prefactor/langchain';\n * import { createReactAgent } from '@langchain/langgraph/prebuilt';\n *\n * const middleware = init();\n * const agent = createReactAgent({\n * llm: model,\n * tools: [myTool],\n * middleware: [middleware],\n * });\n * ```\n */\nexport class PrefactorMiddleware {\n private rootSpan: Span | null = null;\n\n constructor(private tracer: Tracer) {}\n\n /**\n * Called before agent execution starts\n *\n * @param state - Agent state containing messages\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure\n async beforeAgent(state: any): Promise<void> {\n const parentSpan = SpanContext.getCurrent();\n const messages = state?.messages ?? [];\n\n this.tracer.startAgentInstance();\n\n const span = this.tracer.startSpan({\n name: 'agent',\n spanType: SpanType.AGENT,\n inputs: { messages: messages.slice(-3).map((m: unknown) => String(m)) },\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n this.rootSpan = span;\n }\n\n /**\n * Called after agent execution completes\n *\n * @param state - Agent state containing messages\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure\n async afterAgent(state: any): Promise<void> {\n if (!this.rootSpan) {\n return;\n }\n\n const messages = state?.messages ?? [];\n this.tracer.endSpan(this.rootSpan, {\n outputs: { messages: messages.slice(-3).map((m: unknown) => String(m)) },\n });\n\n this.tracer.finishAgentInstance();\n SpanContext.clear();\n this.rootSpan = null;\n }\n\n /**\n * Wrap a model call to trace LLM invocations\n *\n * @param request - Model invocation request\n * @param handler - The actual model call function\n * @returns Promise resolving to the model response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic\n async wrapModelCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T> {\n const parentSpan = SpanContext.getCurrent();\n\n const span = this.tracer.startSpan({\n name: this.extractModelName(request),\n spanType: SpanType.LLM,\n inputs: this.extractModelInputs(request),\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n try {\n // CRITICAL: Wrap handler in context so child operations see this span\n const response = await SpanContext.runAsync(span, async () => {\n return handler(request);\n });\n\n const outputs = this.extractModelOutputs(response);\n const tokenUsage = extractTokenUsage(response);\n\n this.tracer.endSpan(span, { outputs, tokenUsage: tokenUsage ?? undefined });\n return response;\n } catch (error) {\n this.tracer.endSpan(span, { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Wrap a tool call to trace tool executions\n *\n * @param request - Tool invocation request\n * @param handler - The actual tool call function\n * @returns Promise resolving to the tool response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic\n async wrapToolCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T> {\n const parentSpan = SpanContext.getCurrent();\n\n const span = this.tracer.startSpan({\n name: this.extractToolName(request),\n spanType: SpanType.TOOL,\n inputs: this.extractToolInputs(request),\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n try {\n // CRITICAL: Wrap handler in context so child operations see this span\n const response = await SpanContext.runAsync(span, async () => {\n return handler(request);\n });\n\n this.tracer.endSpan(span, {\n outputs: this.extractToolOutputs(response),\n });\n return response;\n } catch (error) {\n this.tracer.endSpan(span, { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Extract model name from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractModelName(request: any): string {\n return request?.model ?? request?.modelName ?? 'unknown';\n }\n\n /**\n * Extract model inputs from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractModelInputs(request: any): Record<string, unknown> {\n const messages = request?.messages ?? [];\n return { messages: messages.slice(-3).map((m: unknown) => String(m)) };\n }\n\n /**\n * Extract model outputs from response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic\n private extractModelOutputs(response: any): Record<string, unknown> {\n const content = response?.content ?? response?.text ?? '';\n return { content: String(content) };\n }\n\n /**\n * Extract tool name from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractToolName(request: any): string {\n return request?.name ?? request?.tool ?? 'unknown';\n }\n\n /**\n * Extract tool inputs from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractToolInputs(request: any): Record<string, unknown> {\n return { input: request?.input ?? request?.args ?? {} };\n }\n\n /**\n * Extract tool outputs from response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic\n private extractToolOutputs(response: any): Record<string, unknown> {\n return { output: response?.output ?? response };\n }\n}\n",
|
|
8
|
+
"import type { TokenUsage } from '@prefactor/core';\n\n/**\n * Extract token usage information from LLM responses.\n *\n * Handles multiple response formats from different LLM providers and LangChain versions.\n *\n * @param response - The LLM response object\n * @returns TokenUsage object or null if no usage data found\n *\n * @example\n * ```typescript\n * const response = await model.invoke(messages);\n * const tokenUsage = extractTokenUsage(response);\n * if (tokenUsage) {\n * console.log(`Tokens used: ${tokenUsage.totalTokens}`);\n * }\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: LLM response structure varies by provider\nexport function extractTokenUsage(response: any): TokenUsage | null {\n try {\n // Try token_usage field (common format)\n const tokenUsage = response?.token_usage ?? response?.usage;\n if (tokenUsage) {\n return {\n promptTokens: tokenUsage.prompt_tokens ?? 0,\n completionTokens: tokenUsage.completion_tokens ?? 0,\n totalTokens: tokenUsage.total_tokens ?? 0,\n };\n }\n\n // Try usage_metadata field (LangChain format)\n const usageMetadata = response?.usage_metadata;\n if (usageMetadata) {\n return {\n promptTokens: usageMetadata.input_tokens ?? 0,\n completionTokens: usageMetadata.output_tokens ?? 0,\n totalTokens: usageMetadata.total_tokens ?? 0,\n };\n }\n\n // Try response_metadata.token_usage (nested format)\n const responseMetadata = response?.response_metadata;\n if (responseMetadata?.token_usage) {\n return {\n promptTokens: responseMetadata.token_usage.prompt_tokens ?? 0,\n completionTokens: responseMetadata.token_usage.completion_tokens ?? 0,\n totalTokens: responseMetadata.token_usage.total_tokens ?? 0,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "46B60F8DD9AA982064756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type Config, type HttpTransportConfig, type Span, SpanStatus, SpanType, } from '@prefactor/core';
|
|
2
|
+
export { getTracer, init, shutdown } from './init.js';
|
|
3
|
+
export { extractTokenUsage } from './metadata-extractor.js';
|
|
4
|
+
export { PrefactorMiddleware } from './middleware.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,MAAM,EACX,KAAK,mBAAmB,EACxB,KAAK,IAAI,EACT,UAAU,EACV,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
// packages/langchain/src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
SpanStatus,
|
|
4
|
+
SpanType as SpanType2
|
|
5
|
+
} from "@prefactor/core";
|
|
6
|
+
|
|
7
|
+
// packages/langchain/src/init.ts
|
|
8
|
+
import {
|
|
9
|
+
configureLogging,
|
|
10
|
+
createConfig,
|
|
11
|
+
getLogger,
|
|
12
|
+
HttpTransport,
|
|
13
|
+
HttpTransportConfigSchema,
|
|
14
|
+
StdioTransport,
|
|
15
|
+
Tracer
|
|
16
|
+
} from "@prefactor/core";
|
|
17
|
+
import { extractPartition } from "@prefactor/pfid";
|
|
18
|
+
import { createMiddleware } from "langchain";
|
|
19
|
+
|
|
20
|
+
// packages/langchain/src/middleware.ts
|
|
21
|
+
import { SpanContext, SpanType } from "@prefactor/core";
|
|
22
|
+
|
|
23
|
+
// packages/langchain/src/metadata-extractor.ts
|
|
24
|
+
function extractTokenUsage(response) {
|
|
25
|
+
try {
|
|
26
|
+
const tokenUsage = response?.token_usage ?? response?.usage;
|
|
27
|
+
if (tokenUsage) {
|
|
28
|
+
return {
|
|
29
|
+
promptTokens: tokenUsage.prompt_tokens ?? 0,
|
|
30
|
+
completionTokens: tokenUsage.completion_tokens ?? 0,
|
|
31
|
+
totalTokens: tokenUsage.total_tokens ?? 0
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const usageMetadata = response?.usage_metadata;
|
|
35
|
+
if (usageMetadata) {
|
|
36
|
+
return {
|
|
37
|
+
promptTokens: usageMetadata.input_tokens ?? 0,
|
|
38
|
+
completionTokens: usageMetadata.output_tokens ?? 0,
|
|
39
|
+
totalTokens: usageMetadata.total_tokens ?? 0
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const responseMetadata = response?.response_metadata;
|
|
43
|
+
if (responseMetadata?.token_usage) {
|
|
44
|
+
return {
|
|
45
|
+
promptTokens: responseMetadata.token_usage.prompt_tokens ?? 0,
|
|
46
|
+
completionTokens: responseMetadata.token_usage.completion_tokens ?? 0,
|
|
47
|
+
totalTokens: responseMetadata.token_usage.total_tokens ?? 0
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// packages/langchain/src/middleware.ts
|
|
57
|
+
class PrefactorMiddleware {
|
|
58
|
+
tracer;
|
|
59
|
+
rootSpan = null;
|
|
60
|
+
constructor(tracer) {
|
|
61
|
+
this.tracer = tracer;
|
|
62
|
+
}
|
|
63
|
+
async beforeAgent(state) {
|
|
64
|
+
const parentSpan = SpanContext.getCurrent();
|
|
65
|
+
const messages = state?.messages ?? [];
|
|
66
|
+
this.tracer.startAgentInstance();
|
|
67
|
+
const span = this.tracer.startSpan({
|
|
68
|
+
name: "agent",
|
|
69
|
+
spanType: SpanType.AGENT,
|
|
70
|
+
inputs: { messages: messages.slice(-3).map((m) => String(m)) },
|
|
71
|
+
parentSpanId: parentSpan?.spanId,
|
|
72
|
+
traceId: parentSpan?.traceId
|
|
73
|
+
});
|
|
74
|
+
this.rootSpan = span;
|
|
75
|
+
}
|
|
76
|
+
async afterAgent(state) {
|
|
77
|
+
if (!this.rootSpan) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const messages = state?.messages ?? [];
|
|
81
|
+
this.tracer.endSpan(this.rootSpan, {
|
|
82
|
+
outputs: { messages: messages.slice(-3).map((m) => String(m)) }
|
|
83
|
+
});
|
|
84
|
+
this.tracer.finishAgentInstance();
|
|
85
|
+
SpanContext.clear();
|
|
86
|
+
this.rootSpan = null;
|
|
87
|
+
}
|
|
88
|
+
async wrapModelCall(request, handler) {
|
|
89
|
+
const parentSpan = SpanContext.getCurrent();
|
|
90
|
+
const span = this.tracer.startSpan({
|
|
91
|
+
name: this.extractModelName(request),
|
|
92
|
+
spanType: SpanType.LLM,
|
|
93
|
+
inputs: this.extractModelInputs(request),
|
|
94
|
+
parentSpanId: parentSpan?.spanId,
|
|
95
|
+
traceId: parentSpan?.traceId
|
|
96
|
+
});
|
|
97
|
+
try {
|
|
98
|
+
const response = await SpanContext.runAsync(span, async () => {
|
|
99
|
+
return handler(request);
|
|
100
|
+
});
|
|
101
|
+
const outputs = this.extractModelOutputs(response);
|
|
102
|
+
const tokenUsage = extractTokenUsage(response);
|
|
103
|
+
this.tracer.endSpan(span, { outputs, tokenUsage: tokenUsage ?? undefined });
|
|
104
|
+
return response;
|
|
105
|
+
} catch (error) {
|
|
106
|
+
this.tracer.endSpan(span, { error });
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async wrapToolCall(request, handler) {
|
|
111
|
+
const parentSpan = SpanContext.getCurrent();
|
|
112
|
+
const span = this.tracer.startSpan({
|
|
113
|
+
name: this.extractToolName(request),
|
|
114
|
+
spanType: SpanType.TOOL,
|
|
115
|
+
inputs: this.extractToolInputs(request),
|
|
116
|
+
parentSpanId: parentSpan?.spanId,
|
|
117
|
+
traceId: parentSpan?.traceId
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
const response = await SpanContext.runAsync(span, async () => {
|
|
121
|
+
return handler(request);
|
|
122
|
+
});
|
|
123
|
+
this.tracer.endSpan(span, {
|
|
124
|
+
outputs: this.extractToolOutputs(response)
|
|
125
|
+
});
|
|
126
|
+
return response;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
this.tracer.endSpan(span, { error });
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
extractModelName(request) {
|
|
133
|
+
return request?.model ?? request?.modelName ?? "unknown";
|
|
134
|
+
}
|
|
135
|
+
extractModelInputs(request) {
|
|
136
|
+
const messages = request?.messages ?? [];
|
|
137
|
+
return { messages: messages.slice(-3).map((m) => String(m)) };
|
|
138
|
+
}
|
|
139
|
+
extractModelOutputs(response) {
|
|
140
|
+
const content = response?.content ?? response?.text ?? "";
|
|
141
|
+
return { content: String(content) };
|
|
142
|
+
}
|
|
143
|
+
extractToolName(request) {
|
|
144
|
+
return request?.name ?? request?.tool ?? "unknown";
|
|
145
|
+
}
|
|
146
|
+
extractToolInputs(request) {
|
|
147
|
+
return { input: request?.input ?? request?.args ?? {} };
|
|
148
|
+
}
|
|
149
|
+
extractToolOutputs(response) {
|
|
150
|
+
return { output: response?.output ?? response };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// packages/langchain/src/init.ts
|
|
155
|
+
var logger = getLogger("init");
|
|
156
|
+
var globalTracer = null;
|
|
157
|
+
var globalMiddleware = null;
|
|
158
|
+
function init(config) {
|
|
159
|
+
configureLogging();
|
|
160
|
+
const finalConfig = createConfig(config);
|
|
161
|
+
logger.info("Initializing Prefactor SDK", { transport: finalConfig.transportType });
|
|
162
|
+
if (globalMiddleware !== null) {
|
|
163
|
+
return globalMiddleware;
|
|
164
|
+
}
|
|
165
|
+
let transport;
|
|
166
|
+
if (finalConfig.transportType === "stdio") {
|
|
167
|
+
transport = new StdioTransport;
|
|
168
|
+
} else {
|
|
169
|
+
if (!finalConfig.httpConfig) {
|
|
170
|
+
throw new Error("HTTP transport requires httpConfig to be provided in configuration");
|
|
171
|
+
}
|
|
172
|
+
const httpConfig = HttpTransportConfigSchema.parse(finalConfig.httpConfig);
|
|
173
|
+
transport = new HttpTransport(httpConfig);
|
|
174
|
+
}
|
|
175
|
+
let partition;
|
|
176
|
+
if (finalConfig.httpConfig?.agentId) {
|
|
177
|
+
try {
|
|
178
|
+
partition = extractPartition(finalConfig.httpConfig.agentId);
|
|
179
|
+
logger.debug("Extracted partition from agent_id", { partition });
|
|
180
|
+
} catch (error) {
|
|
181
|
+
logger.warn("Failed to extract partition from agent_id, using random partition", { error });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
globalTracer = new Tracer(transport, partition);
|
|
185
|
+
const prefactorMiddleware = new PrefactorMiddleware(globalTracer);
|
|
186
|
+
const middleware = createMiddleware({
|
|
187
|
+
name: "prefactor",
|
|
188
|
+
wrapModelCall: async (request, handler) => {
|
|
189
|
+
return prefactorMiddleware.wrapModelCall(request, handler);
|
|
190
|
+
},
|
|
191
|
+
wrapToolCall: async (request, handler) => {
|
|
192
|
+
return prefactorMiddleware.wrapToolCall(request, handler);
|
|
193
|
+
},
|
|
194
|
+
beforeAgent: async (state) => {
|
|
195
|
+
await prefactorMiddleware.beforeAgent(state);
|
|
196
|
+
},
|
|
197
|
+
afterAgent: async (state) => {
|
|
198
|
+
await prefactorMiddleware.afterAgent(state);
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
globalMiddleware = middleware;
|
|
202
|
+
return middleware;
|
|
203
|
+
}
|
|
204
|
+
function getTracer() {
|
|
205
|
+
if (!globalTracer) {
|
|
206
|
+
init();
|
|
207
|
+
}
|
|
208
|
+
return globalTracer;
|
|
209
|
+
}
|
|
210
|
+
async function shutdown() {
|
|
211
|
+
if (globalTracer) {
|
|
212
|
+
logger.info("Shutting down Prefactor SDK");
|
|
213
|
+
await globalTracer.close();
|
|
214
|
+
}
|
|
215
|
+
globalTracer = null;
|
|
216
|
+
globalMiddleware = null;
|
|
217
|
+
}
|
|
218
|
+
process.on("beforeExit", () => {
|
|
219
|
+
shutdown().catch((error) => {
|
|
220
|
+
console.error("Error during Prefactor SDK shutdown:", error);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
export {
|
|
224
|
+
shutdown,
|
|
225
|
+
init,
|
|
226
|
+
getTracer,
|
|
227
|
+
extractTokenUsage,
|
|
228
|
+
SpanType2 as SpanType,
|
|
229
|
+
SpanStatus,
|
|
230
|
+
PrefactorMiddleware
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
//# debugId=B136D336DD9CEBB764756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/init.ts", "../src/middleware.ts", "../src/metadata-extractor.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Main entry points\n\n// Convenience re-exports from core\nexport {\n type Config,\n type HttpTransportConfig,\n type Span,\n SpanStatus,\n SpanType,\n} from '@prefactor/core';\nexport { getTracer, init, shutdown } from './init.js';\nexport { extractTokenUsage } from './metadata-extractor.js';\n// Middleware\nexport { PrefactorMiddleware } from './middleware.js';\n",
|
|
6
|
+
"import {\n type Config,\n configureLogging,\n createConfig,\n getLogger,\n HttpTransport,\n HttpTransportConfigSchema,\n StdioTransport,\n Tracer,\n type Transport,\n} from '@prefactor/core';\nimport { extractPartition, type Partition } from '@prefactor/pfid';\nimport { type AgentMiddleware, createMiddleware } from 'langchain';\nimport { PrefactorMiddleware } from './middleware.js';\n\nconst logger = getLogger('init');\n\nlet globalTracer: Tracer | null = null;\nlet globalMiddleware: AgentMiddleware | null = null;\n\n/**\n * Initialize the Prefactor SDK and return middleware for LangChain.js\n *\n * This is the main entry point for the SDK. Call this function to create a middleware\n * instance that you can pass to your LangChain.js agents.\n *\n * @param config - Optional configuration object\n * @returns PrefactorMiddleware instance to use with LangChain.js agents\n *\n * @example\n * ```typescript\n * import { init } from '@prefactor/langchain';\n * import { createAgent } from 'langchain';\n *\n * // Initialize with defaults (stdio transport)\n * const middleware = init();\n *\n * // Or configure HTTP transport\n * const middleware = init({\n * transportType: 'http',\n * httpConfig: {\n * apiUrl: 'https://api.prefactor.ai',\n * apiToken: process.env.PREFACTOR_API_TOKEN!,\n * }\n * });\n *\n * const agent = createAgent({\n * model: 'claude-sonnet-4-5-20250929',\n * tools: [myTool],\n * middleware: [middleware],\n * });\n * ```\n */\nexport function init(config?: Partial<Config>): AgentMiddleware {\n configureLogging();\n\n const finalConfig = createConfig(config);\n logger.info('Initializing Prefactor SDK', { transport: finalConfig.transportType });\n\n if (globalMiddleware !== null) {\n return globalMiddleware;\n }\n\n let transport: Transport;\n if (finalConfig.transportType === 'stdio') {\n transport = new StdioTransport();\n } else {\n if (!finalConfig.httpConfig) {\n throw new Error('HTTP transport requires httpConfig to be provided in configuration');\n }\n // Parse httpConfig to apply defaults from schema\n const httpConfig = HttpTransportConfigSchema.parse(finalConfig.httpConfig);\n transport = new HttpTransport(httpConfig);\n }\n\n // Extract partition from agent_id if provided (for HTTP transport)\n let partition: Partition | undefined;\n if (finalConfig.httpConfig?.agentId) {\n try {\n partition = extractPartition(finalConfig.httpConfig.agentId);\n logger.debug('Extracted partition from agent_id', { partition });\n } catch (error) {\n logger.warn('Failed to extract partition from agent_id, using random partition', { error });\n }\n }\n\n globalTracer = new Tracer(transport, partition);\n const prefactorMiddleware = new PrefactorMiddleware(globalTracer);\n\n const middleware = createMiddleware({\n name: 'prefactor',\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n wrapModelCall: async (request: any, handler: any) => {\n return prefactorMiddleware.wrapModelCall(request, handler);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n wrapToolCall: async (request: any, handler: any) => {\n return prefactorMiddleware.wrapToolCall(request, handler);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n beforeAgent: async (state: any) => {\n await prefactorMiddleware.beforeAgent(state);\n },\n // biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types\n afterAgent: async (state: any) => {\n await prefactorMiddleware.afterAgent(state);\n },\n });\n\n globalMiddleware = middleware;\n return middleware;\n}\n\n/**\n * Get the current tracer instance.\n *\n * If no tracer has been created yet, this will call init() with default configuration.\n *\n * @returns Tracer instance\n *\n * @example\n * ```typescript\n * import { getTracer } from '@prefactor/langchain';\n *\n * const tracer = getTracer();\n * const span = tracer.startSpan({\n * name: 'custom-operation',\n * spanType: SpanType.TOOL,\n * inputs: { data: 'example' }\n * });\n * ```\n */\nexport function getTracer(): Tracer {\n if (!globalTracer) {\n init();\n }\n // Safe because init() always sets globalTracer\n return globalTracer as Tracer;\n}\n\n/**\n * Shutdown the SDK and flush any pending spans.\n *\n * Call this before your application exits to ensure all spans are sent to the transport.\n * This is especially important for HTTP transport which has a queue of pending requests.\n *\n * @returns Promise that resolves when shutdown is complete\n *\n * @example\n * ```typescript\n * import { shutdown } from '@prefactor/langchain';\n *\n * process.on('SIGTERM', async () => {\n * await shutdown();\n * process.exit(0);\n * });\n * ```\n */\nexport async function shutdown(): Promise<void> {\n if (globalTracer) {\n logger.info('Shutting down Prefactor SDK');\n await globalTracer.close();\n }\n globalTracer = null;\n globalMiddleware = null;\n}\n\n// Automatic shutdown on process exit\nprocess.on('beforeExit', () => {\n shutdown().catch((error) => {\n console.error('Error during Prefactor SDK shutdown:', error);\n });\n});\n",
|
|
7
|
+
"import { type Span, SpanContext, SpanType, type Tracer } from '@prefactor/core';\nimport { extractTokenUsage } from './metadata-extractor.js';\n\n/**\n * Prefactor middleware for LangChain.js agents.\n *\n * This middleware automatically traces LLM calls, tool executions, and agent workflows.\n * It integrates with LangChain.js middleware API to provide transparent instrumentation.\n *\n * Features:\n * - Automatic parent-child span relationships via context propagation\n * - Token usage extraction for LLM calls\n * - Error tracking and debugging\n * - Zero-overhead instrumentation (graceful failure)\n *\n * @example\n * ```typescript\n * import { init } from '@prefactor/langchain';\n * import { createReactAgent } from '@langchain/langgraph/prebuilt';\n *\n * const middleware = init();\n * const agent = createReactAgent({\n * llm: model,\n * tools: [myTool],\n * middleware: [middleware],\n * });\n * ```\n */\nexport class PrefactorMiddleware {\n private rootSpan: Span | null = null;\n\n constructor(private tracer: Tracer) {}\n\n /**\n * Called before agent execution starts\n *\n * @param state - Agent state containing messages\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure\n async beforeAgent(state: any): Promise<void> {\n const parentSpan = SpanContext.getCurrent();\n const messages = state?.messages ?? [];\n\n this.tracer.startAgentInstance();\n\n const span = this.tracer.startSpan({\n name: 'agent',\n spanType: SpanType.AGENT,\n inputs: { messages: messages.slice(-3).map((m: unknown) => String(m)) },\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n this.rootSpan = span;\n }\n\n /**\n * Called after agent execution completes\n *\n * @param state - Agent state containing messages\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure\n async afterAgent(state: any): Promise<void> {\n if (!this.rootSpan) {\n return;\n }\n\n const messages = state?.messages ?? [];\n this.tracer.endSpan(this.rootSpan, {\n outputs: { messages: messages.slice(-3).map((m: unknown) => String(m)) },\n });\n\n this.tracer.finishAgentInstance();\n SpanContext.clear();\n this.rootSpan = null;\n }\n\n /**\n * Wrap a model call to trace LLM invocations\n *\n * @param request - Model invocation request\n * @param handler - The actual model call function\n * @returns Promise resolving to the model response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic\n async wrapModelCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T> {\n const parentSpan = SpanContext.getCurrent();\n\n const span = this.tracer.startSpan({\n name: this.extractModelName(request),\n spanType: SpanType.LLM,\n inputs: this.extractModelInputs(request),\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n try {\n // CRITICAL: Wrap handler in context so child operations see this span\n const response = await SpanContext.runAsync(span, async () => {\n return handler(request);\n });\n\n const outputs = this.extractModelOutputs(response);\n const tokenUsage = extractTokenUsage(response);\n\n this.tracer.endSpan(span, { outputs, tokenUsage: tokenUsage ?? undefined });\n return response;\n } catch (error) {\n this.tracer.endSpan(span, { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Wrap a tool call to trace tool executions\n *\n * @param request - Tool invocation request\n * @param handler - The actual tool call function\n * @returns Promise resolving to the tool response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic\n async wrapToolCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T> {\n const parentSpan = SpanContext.getCurrent();\n\n const span = this.tracer.startSpan({\n name: this.extractToolName(request),\n spanType: SpanType.TOOL,\n inputs: this.extractToolInputs(request),\n parentSpanId: parentSpan?.spanId,\n traceId: parentSpan?.traceId,\n });\n\n try {\n // CRITICAL: Wrap handler in context so child operations see this span\n const response = await SpanContext.runAsync(span, async () => {\n return handler(request);\n });\n\n this.tracer.endSpan(span, {\n outputs: this.extractToolOutputs(response),\n });\n return response;\n } catch (error) {\n this.tracer.endSpan(span, { error: error as Error });\n throw error;\n }\n }\n\n /**\n * Extract model name from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractModelName(request: any): string {\n return request?.model ?? request?.modelName ?? 'unknown';\n }\n\n /**\n * Extract model inputs from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractModelInputs(request: any): Record<string, unknown> {\n const messages = request?.messages ?? [];\n return { messages: messages.slice(-3).map((m: unknown) => String(m)) };\n }\n\n /**\n * Extract model outputs from response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic\n private extractModelOutputs(response: any): Record<string, unknown> {\n const content = response?.content ?? response?.text ?? '';\n return { content: String(content) };\n }\n\n /**\n * Extract tool name from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractToolName(request: any): string {\n return request?.name ?? request?.tool ?? 'unknown';\n }\n\n /**\n * Extract tool inputs from request\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic\n private extractToolInputs(request: any): Record<string, unknown> {\n return { input: request?.input ?? request?.args ?? {} };\n }\n\n /**\n * Extract tool outputs from response\n */\n // biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic\n private extractToolOutputs(response: any): Record<string, unknown> {\n return { output: response?.output ?? response };\n }\n}\n",
|
|
8
|
+
"import type { TokenUsage } from '@prefactor/core';\n\n/**\n * Extract token usage information from LLM responses.\n *\n * Handles multiple response formats from different LLM providers and LangChain versions.\n *\n * @param response - The LLM response object\n * @returns TokenUsage object or null if no usage data found\n *\n * @example\n * ```typescript\n * const response = await model.invoke(messages);\n * const tokenUsage = extractTokenUsage(response);\n * if (tokenUsage) {\n * console.log(`Tokens used: ${tokenUsage.totalTokens}`);\n * }\n * ```\n */\n// biome-ignore lint/suspicious/noExplicitAny: LLM response structure varies by provider\nexport function extractTokenUsage(response: any): TokenUsage | null {\n try {\n // Try token_usage field (common format)\n const tokenUsage = response?.token_usage ?? response?.usage;\n if (tokenUsage) {\n return {\n promptTokens: tokenUsage.prompt_tokens ?? 0,\n completionTokens: tokenUsage.completion_tokens ?? 0,\n totalTokens: tokenUsage.total_tokens ?? 0,\n };\n }\n\n // Try usage_metadata field (LangChain format)\n const usageMetadata = response?.usage_metadata;\n if (usageMetadata) {\n return {\n promptTokens: usageMetadata.input_tokens ?? 0,\n completionTokens: usageMetadata.output_tokens ?? 0,\n totalTokens: usageMetadata.total_tokens ?? 0,\n };\n }\n\n // Try response_metadata.token_usage (nested format)\n const responseMetadata = response?.response_metadata;\n if (responseMetadata?.token_usage) {\n return {\n promptTokens: responseMetadata.token_usage.prompt_tokens ?? 0,\n completionTokens: responseMetadata.token_usage.completion_tokens ?? 0,\n totalTokens: responseMetadata.token_usage.total_tokens ?? 0,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "B136D336DD9CEBB764756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { type Config, Tracer } from '@prefactor/core';
|
|
2
|
+
import { type AgentMiddleware } from 'langchain';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the Prefactor SDK and return middleware for LangChain.js
|
|
5
|
+
*
|
|
6
|
+
* This is the main entry point for the SDK. Call this function to create a middleware
|
|
7
|
+
* instance that you can pass to your LangChain.js agents.
|
|
8
|
+
*
|
|
9
|
+
* @param config - Optional configuration object
|
|
10
|
+
* @returns PrefactorMiddleware instance to use with LangChain.js agents
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { init } from '@prefactor/langchain';
|
|
15
|
+
* import { createAgent } from 'langchain';
|
|
16
|
+
*
|
|
17
|
+
* // Initialize with defaults (stdio transport)
|
|
18
|
+
* const middleware = init();
|
|
19
|
+
*
|
|
20
|
+
* // Or configure HTTP transport
|
|
21
|
+
* const middleware = init({
|
|
22
|
+
* transportType: 'http',
|
|
23
|
+
* httpConfig: {
|
|
24
|
+
* apiUrl: 'https://api.prefactor.ai',
|
|
25
|
+
* apiToken: process.env.PREFACTOR_API_TOKEN!,
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* const agent = createAgent({
|
|
30
|
+
* model: 'claude-sonnet-4-5-20250929',
|
|
31
|
+
* tools: [myTool],
|
|
32
|
+
* middleware: [middleware],
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function init(config?: Partial<Config>): AgentMiddleware;
|
|
37
|
+
/**
|
|
38
|
+
* Get the current tracer instance.
|
|
39
|
+
*
|
|
40
|
+
* If no tracer has been created yet, this will call init() with default configuration.
|
|
41
|
+
*
|
|
42
|
+
* @returns Tracer instance
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* import { getTracer } from '@prefactor/langchain';
|
|
47
|
+
*
|
|
48
|
+
* const tracer = getTracer();
|
|
49
|
+
* const span = tracer.startSpan({
|
|
50
|
+
* name: 'custom-operation',
|
|
51
|
+
* spanType: SpanType.TOOL,
|
|
52
|
+
* inputs: { data: 'example' }
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function getTracer(): Tracer;
|
|
57
|
+
/**
|
|
58
|
+
* Shutdown the SDK and flush any pending spans.
|
|
59
|
+
*
|
|
60
|
+
* Call this before your application exits to ensure all spans are sent to the transport.
|
|
61
|
+
* This is especially important for HTTP transport which has a queue of pending requests.
|
|
62
|
+
*
|
|
63
|
+
* @returns Promise that resolves when shutdown is complete
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { shutdown } from '@prefactor/langchain';
|
|
68
|
+
*
|
|
69
|
+
* process.on('SIGTERM', async () => {
|
|
70
|
+
* await shutdown();
|
|
71
|
+
* process.exit(0);
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export declare function shutdown(): Promise<void>;
|
|
76
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,MAAM,EAOX,MAAM,EAEP,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,WAAW,CAAC;AAQnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,eAAe,CA0D9D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAMlC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAO9C"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { configureLogging, createConfig, getLogger, HttpTransport, HttpTransportConfigSchema, StdioTransport, Tracer, } from '@prefactor/core';
|
|
2
|
+
import { extractPartition } from '@prefactor/pfid';
|
|
3
|
+
import { createMiddleware } from 'langchain';
|
|
4
|
+
import { PrefactorMiddleware } from './middleware.js';
|
|
5
|
+
const logger = getLogger('init');
|
|
6
|
+
let globalTracer = null;
|
|
7
|
+
let globalMiddleware = null;
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the Prefactor SDK and return middleware for LangChain.js
|
|
10
|
+
*
|
|
11
|
+
* This is the main entry point for the SDK. Call this function to create a middleware
|
|
12
|
+
* instance that you can pass to your LangChain.js agents.
|
|
13
|
+
*
|
|
14
|
+
* @param config - Optional configuration object
|
|
15
|
+
* @returns PrefactorMiddleware instance to use with LangChain.js agents
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { init } from '@prefactor/langchain';
|
|
20
|
+
* import { createAgent } from 'langchain';
|
|
21
|
+
*
|
|
22
|
+
* // Initialize with defaults (stdio transport)
|
|
23
|
+
* const middleware = init();
|
|
24
|
+
*
|
|
25
|
+
* // Or configure HTTP transport
|
|
26
|
+
* const middleware = init({
|
|
27
|
+
* transportType: 'http',
|
|
28
|
+
* httpConfig: {
|
|
29
|
+
* apiUrl: 'https://api.prefactor.ai',
|
|
30
|
+
* apiToken: process.env.PREFACTOR_API_TOKEN!,
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* const agent = createAgent({
|
|
35
|
+
* model: 'claude-sonnet-4-5-20250929',
|
|
36
|
+
* tools: [myTool],
|
|
37
|
+
* middleware: [middleware],
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function init(config) {
|
|
42
|
+
configureLogging();
|
|
43
|
+
const finalConfig = createConfig(config);
|
|
44
|
+
logger.info('Initializing Prefactor SDK', { transport: finalConfig.transportType });
|
|
45
|
+
if (globalMiddleware !== null) {
|
|
46
|
+
return globalMiddleware;
|
|
47
|
+
}
|
|
48
|
+
let transport;
|
|
49
|
+
if (finalConfig.transportType === 'stdio') {
|
|
50
|
+
transport = new StdioTransport();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
if (!finalConfig.httpConfig) {
|
|
54
|
+
throw new Error('HTTP transport requires httpConfig to be provided in configuration');
|
|
55
|
+
}
|
|
56
|
+
// Parse httpConfig to apply defaults from schema
|
|
57
|
+
const httpConfig = HttpTransportConfigSchema.parse(finalConfig.httpConfig);
|
|
58
|
+
transport = new HttpTransport(httpConfig);
|
|
59
|
+
}
|
|
60
|
+
// Extract partition from agent_id if provided (for HTTP transport)
|
|
61
|
+
let partition;
|
|
62
|
+
if (finalConfig.httpConfig?.agentId) {
|
|
63
|
+
try {
|
|
64
|
+
partition = extractPartition(finalConfig.httpConfig.agentId);
|
|
65
|
+
logger.debug('Extracted partition from agent_id', { partition });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
logger.warn('Failed to extract partition from agent_id, using random partition', { error });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
globalTracer = new Tracer(transport, partition);
|
|
72
|
+
const prefactorMiddleware = new PrefactorMiddleware(globalTracer);
|
|
73
|
+
const middleware = createMiddleware({
|
|
74
|
+
name: 'prefactor',
|
|
75
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types
|
|
76
|
+
wrapModelCall: async (request, handler) => {
|
|
77
|
+
return prefactorMiddleware.wrapModelCall(request, handler);
|
|
78
|
+
},
|
|
79
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types
|
|
80
|
+
wrapToolCall: async (request, handler) => {
|
|
81
|
+
return prefactorMiddleware.wrapToolCall(request, handler);
|
|
82
|
+
},
|
|
83
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types
|
|
84
|
+
beforeAgent: async (state) => {
|
|
85
|
+
await prefactorMiddleware.beforeAgent(state);
|
|
86
|
+
},
|
|
87
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain middleware hooks use dynamic types
|
|
88
|
+
afterAgent: async (state) => {
|
|
89
|
+
await prefactorMiddleware.afterAgent(state);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
globalMiddleware = middleware;
|
|
93
|
+
return middleware;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get the current tracer instance.
|
|
97
|
+
*
|
|
98
|
+
* If no tracer has been created yet, this will call init() with default configuration.
|
|
99
|
+
*
|
|
100
|
+
* @returns Tracer instance
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* import { getTracer } from '@prefactor/langchain';
|
|
105
|
+
*
|
|
106
|
+
* const tracer = getTracer();
|
|
107
|
+
* const span = tracer.startSpan({
|
|
108
|
+
* name: 'custom-operation',
|
|
109
|
+
* spanType: SpanType.TOOL,
|
|
110
|
+
* inputs: { data: 'example' }
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export function getTracer() {
|
|
115
|
+
if (!globalTracer) {
|
|
116
|
+
init();
|
|
117
|
+
}
|
|
118
|
+
// Safe because init() always sets globalTracer
|
|
119
|
+
return globalTracer;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Shutdown the SDK and flush any pending spans.
|
|
123
|
+
*
|
|
124
|
+
* Call this before your application exits to ensure all spans are sent to the transport.
|
|
125
|
+
* This is especially important for HTTP transport which has a queue of pending requests.
|
|
126
|
+
*
|
|
127
|
+
* @returns Promise that resolves when shutdown is complete
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import { shutdown } from '@prefactor/langchain';
|
|
132
|
+
*
|
|
133
|
+
* process.on('SIGTERM', async () => {
|
|
134
|
+
* await shutdown();
|
|
135
|
+
* process.exit(0);
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export async function shutdown() {
|
|
140
|
+
if (globalTracer) {
|
|
141
|
+
logger.info('Shutting down Prefactor SDK');
|
|
142
|
+
await globalTracer.close();
|
|
143
|
+
}
|
|
144
|
+
globalTracer = null;
|
|
145
|
+
globalMiddleware = null;
|
|
146
|
+
}
|
|
147
|
+
// Automatic shutdown on process exit
|
|
148
|
+
process.on('beforeExit', () => {
|
|
149
|
+
shutdown().catch((error) => {
|
|
150
|
+
console.error('Error during Prefactor SDK shutdown:', error);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TokenUsage } from '@prefactor/core';
|
|
2
|
+
/**
|
|
3
|
+
* Extract token usage information from LLM responses.
|
|
4
|
+
*
|
|
5
|
+
* Handles multiple response formats from different LLM providers and LangChain versions.
|
|
6
|
+
*
|
|
7
|
+
* @param response - The LLM response object
|
|
8
|
+
* @returns TokenUsage object or null if no usage data found
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const response = await model.invoke(messages);
|
|
13
|
+
* const tokenUsage = extractTokenUsage(response);
|
|
14
|
+
* if (tokenUsage) {
|
|
15
|
+
* console.log(`Tokens used: ${tokenUsage.totalTokens}`);
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractTokenUsage(response: any): TokenUsage | null;
|
|
20
|
+
//# sourceMappingURL=metadata-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata-extractor.d.ts","sourceRoot":"","sources":["../src/metadata-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI,CAoClE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract token usage information from LLM responses.
|
|
3
|
+
*
|
|
4
|
+
* Handles multiple response formats from different LLM providers and LangChain versions.
|
|
5
|
+
*
|
|
6
|
+
* @param response - The LLM response object
|
|
7
|
+
* @returns TokenUsage object or null if no usage data found
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const response = await model.invoke(messages);
|
|
12
|
+
* const tokenUsage = extractTokenUsage(response);
|
|
13
|
+
* if (tokenUsage) {
|
|
14
|
+
* console.log(`Tokens used: ${tokenUsage.totalTokens}`);
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
// biome-ignore lint/suspicious/noExplicitAny: LLM response structure varies by provider
|
|
19
|
+
export function extractTokenUsage(response) {
|
|
20
|
+
try {
|
|
21
|
+
// Try token_usage field (common format)
|
|
22
|
+
const tokenUsage = response?.token_usage ?? response?.usage;
|
|
23
|
+
if (tokenUsage) {
|
|
24
|
+
return {
|
|
25
|
+
promptTokens: tokenUsage.prompt_tokens ?? 0,
|
|
26
|
+
completionTokens: tokenUsage.completion_tokens ?? 0,
|
|
27
|
+
totalTokens: tokenUsage.total_tokens ?? 0,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Try usage_metadata field (LangChain format)
|
|
31
|
+
const usageMetadata = response?.usage_metadata;
|
|
32
|
+
if (usageMetadata) {
|
|
33
|
+
return {
|
|
34
|
+
promptTokens: usageMetadata.input_tokens ?? 0,
|
|
35
|
+
completionTokens: usageMetadata.output_tokens ?? 0,
|
|
36
|
+
totalTokens: usageMetadata.total_tokens ?? 0,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Try response_metadata.token_usage (nested format)
|
|
40
|
+
const responseMetadata = response?.response_metadata;
|
|
41
|
+
if (responseMetadata?.token_usage) {
|
|
42
|
+
return {
|
|
43
|
+
promptTokens: responseMetadata.token_usage.prompt_tokens ?? 0,
|
|
44
|
+
completionTokens: responseMetadata.token_usage.completion_tokens ?? 0,
|
|
45
|
+
totalTokens: responseMetadata.token_usage.total_tokens ?? 0,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=metadata-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata-extractor.js","sourceRoot":"","sources":["../src/metadata-extractor.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,QAAa;IAC7C,IAAI,CAAC;QACH,wCAAwC;QACxC,MAAM,UAAU,GAAG,QAAQ,EAAE,WAAW,IAAI,QAAQ,EAAE,KAAK,CAAC;QAC5D,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,YAAY,EAAE,UAAU,CAAC,aAAa,IAAI,CAAC;gBAC3C,gBAAgB,EAAE,UAAU,CAAC,iBAAiB,IAAI,CAAC;gBACnD,WAAW,EAAE,UAAU,CAAC,YAAY,IAAI,CAAC;aAC1C,CAAC;QACJ,CAAC;QAED,8CAA8C;QAC9C,MAAM,aAAa,GAAG,QAAQ,EAAE,cAAc,CAAC;QAC/C,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO;gBACL,YAAY,EAAE,aAAa,CAAC,YAAY,IAAI,CAAC;gBAC7C,gBAAgB,EAAE,aAAa,CAAC,aAAa,IAAI,CAAC;gBAClD,WAAW,EAAE,aAAa,CAAC,YAAY,IAAI,CAAC;aAC7C,CAAC;QACJ,CAAC;QAED,oDAAoD;QACpD,MAAM,gBAAgB,GAAG,QAAQ,EAAE,iBAAiB,CAAC;QACrD,IAAI,gBAAgB,EAAE,WAAW,EAAE,CAAC;YAClC,OAAO;gBACL,YAAY,EAAE,gBAAgB,CAAC,WAAW,CAAC,aAAa,IAAI,CAAC;gBAC7D,gBAAgB,EAAE,gBAAgB,CAAC,WAAW,CAAC,iBAAiB,IAAI,CAAC;gBACrE,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC,YAAY,IAAI,CAAC;aAC5D,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { type Tracer } from '@prefactor/core';
|
|
2
|
+
/**
|
|
3
|
+
* Prefactor middleware for LangChain.js agents.
|
|
4
|
+
*
|
|
5
|
+
* This middleware automatically traces LLM calls, tool executions, and agent workflows.
|
|
6
|
+
* It integrates with LangChain.js middleware API to provide transparent instrumentation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Automatic parent-child span relationships via context propagation
|
|
10
|
+
* - Token usage extraction for LLM calls
|
|
11
|
+
* - Error tracking and debugging
|
|
12
|
+
* - Zero-overhead instrumentation (graceful failure)
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { init } from '@prefactor/langchain';
|
|
17
|
+
* import { createReactAgent } from '@langchain/langgraph/prebuilt';
|
|
18
|
+
*
|
|
19
|
+
* const middleware = init();
|
|
20
|
+
* const agent = createReactAgent({
|
|
21
|
+
* llm: model,
|
|
22
|
+
* tools: [myTool],
|
|
23
|
+
* middleware: [middleware],
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class PrefactorMiddleware {
|
|
28
|
+
private tracer;
|
|
29
|
+
private rootSpan;
|
|
30
|
+
constructor(tracer: Tracer);
|
|
31
|
+
/**
|
|
32
|
+
* Called before agent execution starts
|
|
33
|
+
*
|
|
34
|
+
* @param state - Agent state containing messages
|
|
35
|
+
*/
|
|
36
|
+
beforeAgent(state: any): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Called after agent execution completes
|
|
39
|
+
*
|
|
40
|
+
* @param state - Agent state containing messages
|
|
41
|
+
*/
|
|
42
|
+
afterAgent(state: any): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Wrap a model call to trace LLM invocations
|
|
45
|
+
*
|
|
46
|
+
* @param request - Model invocation request
|
|
47
|
+
* @param handler - The actual model call function
|
|
48
|
+
* @returns Promise resolving to the model response
|
|
49
|
+
*/
|
|
50
|
+
wrapModelCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Wrap a tool call to trace tool executions
|
|
53
|
+
*
|
|
54
|
+
* @param request - Tool invocation request
|
|
55
|
+
* @param handler - The actual tool call function
|
|
56
|
+
* @returns Promise resolving to the tool response
|
|
57
|
+
*/
|
|
58
|
+
wrapToolCall<T>(request: any, handler: (req: any) => Promise<T>): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Extract model name from request
|
|
61
|
+
*/
|
|
62
|
+
private extractModelName;
|
|
63
|
+
/**
|
|
64
|
+
* Extract model inputs from request
|
|
65
|
+
*/
|
|
66
|
+
private extractModelInputs;
|
|
67
|
+
/**
|
|
68
|
+
* Extract model outputs from response
|
|
69
|
+
*/
|
|
70
|
+
private extractModelOutputs;
|
|
71
|
+
/**
|
|
72
|
+
* Extract tool name from request
|
|
73
|
+
*/
|
|
74
|
+
private extractToolName;
|
|
75
|
+
/**
|
|
76
|
+
* Extract tool inputs from request
|
|
77
|
+
*/
|
|
78
|
+
private extractToolInputs;
|
|
79
|
+
/**
|
|
80
|
+
* Extract tool outputs from response
|
|
81
|
+
*/
|
|
82
|
+
private extractToolOutputs;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGhF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBAAmB;IAGlB,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,QAAQ,CAAqB;gBAEjB,MAAM,EAAE,MAAM;IAElC;;;;OAIG;IAEG,WAAW,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB5C;;;;OAIG;IAEG,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAe3C;;;;;;OAMG;IAEG,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA4BnF;;;;;;OAMG;IAEG,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA2BlF;;OAEG;IAEH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IAEH,OAAO,CAAC,kBAAkB;IAK1B;;OAEG;IAEH,OAAO,CAAC,mBAAmB;IAK3B;;OAEG;IAEH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IAEH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IAEH,OAAO,CAAC,kBAAkB;CAG3B"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { SpanContext, SpanType } from '@prefactor/core';
|
|
2
|
+
import { extractTokenUsage } from './metadata-extractor.js';
|
|
3
|
+
/**
|
|
4
|
+
* Prefactor middleware for LangChain.js agents.
|
|
5
|
+
*
|
|
6
|
+
* This middleware automatically traces LLM calls, tool executions, and agent workflows.
|
|
7
|
+
* It integrates with LangChain.js middleware API to provide transparent instrumentation.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Automatic parent-child span relationships via context propagation
|
|
11
|
+
* - Token usage extraction for LLM calls
|
|
12
|
+
* - Error tracking and debugging
|
|
13
|
+
* - Zero-overhead instrumentation (graceful failure)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { init } from '@prefactor/langchain';
|
|
18
|
+
* import { createReactAgent } from '@langchain/langgraph/prebuilt';
|
|
19
|
+
*
|
|
20
|
+
* const middleware = init();
|
|
21
|
+
* const agent = createReactAgent({
|
|
22
|
+
* llm: model,
|
|
23
|
+
* tools: [myTool],
|
|
24
|
+
* middleware: [middleware],
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class PrefactorMiddleware {
|
|
29
|
+
tracer;
|
|
30
|
+
rootSpan = null;
|
|
31
|
+
constructor(tracer) {
|
|
32
|
+
this.tracer = tracer;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Called before agent execution starts
|
|
36
|
+
*
|
|
37
|
+
* @param state - Agent state containing messages
|
|
38
|
+
*/
|
|
39
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure
|
|
40
|
+
async beforeAgent(state) {
|
|
41
|
+
const parentSpan = SpanContext.getCurrent();
|
|
42
|
+
const messages = state?.messages ?? [];
|
|
43
|
+
this.tracer.startAgentInstance();
|
|
44
|
+
const span = this.tracer.startSpan({
|
|
45
|
+
name: 'agent',
|
|
46
|
+
spanType: SpanType.AGENT,
|
|
47
|
+
inputs: { messages: messages.slice(-3).map((m) => String(m)) },
|
|
48
|
+
parentSpanId: parentSpan?.spanId,
|
|
49
|
+
traceId: parentSpan?.traceId,
|
|
50
|
+
});
|
|
51
|
+
this.rootSpan = span;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Called after agent execution completes
|
|
55
|
+
*
|
|
56
|
+
* @param state - Agent state containing messages
|
|
57
|
+
*/
|
|
58
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain state can be any structure
|
|
59
|
+
async afterAgent(state) {
|
|
60
|
+
if (!this.rootSpan) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const messages = state?.messages ?? [];
|
|
64
|
+
this.tracer.endSpan(this.rootSpan, {
|
|
65
|
+
outputs: { messages: messages.slice(-3).map((m) => String(m)) },
|
|
66
|
+
});
|
|
67
|
+
this.tracer.finishAgentInstance();
|
|
68
|
+
SpanContext.clear();
|
|
69
|
+
this.rootSpan = null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Wrap a model call to trace LLM invocations
|
|
73
|
+
*
|
|
74
|
+
* @param request - Model invocation request
|
|
75
|
+
* @param handler - The actual model call function
|
|
76
|
+
* @returns Promise resolving to the model response
|
|
77
|
+
*/
|
|
78
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic
|
|
79
|
+
async wrapModelCall(request, handler) {
|
|
80
|
+
const parentSpan = SpanContext.getCurrent();
|
|
81
|
+
const span = this.tracer.startSpan({
|
|
82
|
+
name: this.extractModelName(request),
|
|
83
|
+
spanType: SpanType.LLM,
|
|
84
|
+
inputs: this.extractModelInputs(request),
|
|
85
|
+
parentSpanId: parentSpan?.spanId,
|
|
86
|
+
traceId: parentSpan?.traceId,
|
|
87
|
+
});
|
|
88
|
+
try {
|
|
89
|
+
// CRITICAL: Wrap handler in context so child operations see this span
|
|
90
|
+
const response = await SpanContext.runAsync(span, async () => {
|
|
91
|
+
return handler(request);
|
|
92
|
+
});
|
|
93
|
+
const outputs = this.extractModelOutputs(response);
|
|
94
|
+
const tokenUsage = extractTokenUsage(response);
|
|
95
|
+
this.tracer.endSpan(span, { outputs, tokenUsage: tokenUsage ?? undefined });
|
|
96
|
+
return response;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
this.tracer.endSpan(span, { error: error });
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Wrap a tool call to trace tool executions
|
|
105
|
+
*
|
|
106
|
+
* @param request - Tool invocation request
|
|
107
|
+
* @param handler - The actual tool call function
|
|
108
|
+
* @returns Promise resolving to the tool response
|
|
109
|
+
*/
|
|
110
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request/handler types are dynamic
|
|
111
|
+
async wrapToolCall(request, handler) {
|
|
112
|
+
const parentSpan = SpanContext.getCurrent();
|
|
113
|
+
const span = this.tracer.startSpan({
|
|
114
|
+
name: this.extractToolName(request),
|
|
115
|
+
spanType: SpanType.TOOL,
|
|
116
|
+
inputs: this.extractToolInputs(request),
|
|
117
|
+
parentSpanId: parentSpan?.spanId,
|
|
118
|
+
traceId: parentSpan?.traceId,
|
|
119
|
+
});
|
|
120
|
+
try {
|
|
121
|
+
// CRITICAL: Wrap handler in context so child operations see this span
|
|
122
|
+
const response = await SpanContext.runAsync(span, async () => {
|
|
123
|
+
return handler(request);
|
|
124
|
+
});
|
|
125
|
+
this.tracer.endSpan(span, {
|
|
126
|
+
outputs: this.extractToolOutputs(response),
|
|
127
|
+
});
|
|
128
|
+
return response;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.tracer.endSpan(span, { error: error });
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Extract model name from request
|
|
137
|
+
*/
|
|
138
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic
|
|
139
|
+
extractModelName(request) {
|
|
140
|
+
return request?.model ?? request?.modelName ?? 'unknown';
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Extract model inputs from request
|
|
144
|
+
*/
|
|
145
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic
|
|
146
|
+
extractModelInputs(request) {
|
|
147
|
+
const messages = request?.messages ?? [];
|
|
148
|
+
return { messages: messages.slice(-3).map((m) => String(m)) };
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract model outputs from response
|
|
152
|
+
*/
|
|
153
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic
|
|
154
|
+
extractModelOutputs(response) {
|
|
155
|
+
const content = response?.content ?? response?.text ?? '';
|
|
156
|
+
return { content: String(content) };
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Extract tool name from request
|
|
160
|
+
*/
|
|
161
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic
|
|
162
|
+
extractToolName(request) {
|
|
163
|
+
return request?.name ?? request?.tool ?? 'unknown';
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Extract tool inputs from request
|
|
167
|
+
*/
|
|
168
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain request structure is dynamic
|
|
169
|
+
extractToolInputs(request) {
|
|
170
|
+
return { input: request?.input ?? request?.args ?? {} };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Extract tool outputs from response
|
|
174
|
+
*/
|
|
175
|
+
// biome-ignore lint/suspicious/noExplicitAny: LangChain response structure is dynamic
|
|
176
|
+
extractToolOutputs(response) {
|
|
177
|
+
return { output: response?.output ?? response };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,WAAW,EAAE,QAAQ,EAAe,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,mBAAmB;IAGV;IAFZ,QAAQ,GAAgB,IAAI,CAAC;IAErC,YAAoB,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;IAEtC;;;;OAIG;IACH,mFAAmF;IACnF,KAAK,CAAC,WAAW,CAAC,KAAU;QAC1B,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC;QAEvC,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAEjC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACjC,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE,QAAQ,CAAC,KAAK;YACxB,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACvE,YAAY,EAAE,UAAU,EAAE,MAAM;YAChC,OAAO,EAAE,UAAU,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,mFAAmF;IACnF,KAAK,CAAC,UAAU,CAAC,KAAU;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE;YACjC,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;SACzE,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAClC,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,0FAA0F;IAC1F,KAAK,CAAC,aAAa,CAAI,OAAY,EAAE,OAAiC;QACpE,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;QAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;YACpC,QAAQ,EAAE,QAAQ,CAAC,GAAG;YACtB,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;YACxC,YAAY,EAAE,UAAU,EAAE,MAAM;YAChC,OAAO,EAAE,UAAU,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,sEAAsE;YACtE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC3D,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAE/C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,IAAI,SAAS,EAAE,CAAC,CAAC;YAC5E,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC,CAAC;YACrD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,0FAA0F;IAC1F,KAAK,CAAC,YAAY,CAAI,OAAY,EAAE,OAAiC;QACnE,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC;QAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;YACjC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YACnC,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YACvC,YAAY,EAAE,UAAU,EAAE,MAAM;YAChC,OAAO,EAAE,UAAU,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,sEAAsE;YACtE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBAC3D,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;gBACxB,OAAO,EAAE,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC;aAC3C,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC,CAAC;YACrD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,qFAAqF;IAC7E,gBAAgB,CAAC,OAAY;QACnC,OAAO,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,SAAS,IAAI,SAAS,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,qFAAqF;IAC7E,kBAAkB,CAAC,OAAY;QACrC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,EAAE,CAAC;QACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,sFAAsF;IAC9E,mBAAmB,CAAC,QAAa;QACvC,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;QAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,qFAAqF;IAC7E,eAAe,CAAC,OAAY;QAClC,OAAO,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,IAAI,SAAS,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,qFAAqF;IAC7E,iBAAiB,CAAC,OAAY;QACpC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,sFAAsF;IAC9E,kBAAkB,CAAC,QAAa;QACtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,CAAC;IAClD,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prefactor/langchain",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "LangChain.js integration for Prefactor observability",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"prefactor",
|
|
21
|
+
"observability",
|
|
22
|
+
"tracing",
|
|
23
|
+
"langchain",
|
|
24
|
+
"llm",
|
|
25
|
+
"agent",
|
|
26
|
+
"monitoring"
|
|
27
|
+
],
|
|
28
|
+
"author": "Prefactor",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@prefactor/core": "0.1.0",
|
|
32
|
+
"@prefactor/pfid": "^0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"langchain": "^1.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=24.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|