@farzanhossans/agentlens 0.2.0 → 0.2.1
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.d.mts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +99 -46
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -46
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import { getCurrentTraceId, runWithTrace, getCurrentSpanId } from '@farzanhossans/agentlens-core';
|
|
3
3
|
export { getCurrentSpanId, getCurrentTrace, getCurrentTraceId, runWithTrace } from '@farzanhossans/agentlens-core';
|
|
4
|
+
import http from 'http';
|
|
5
|
+
import https from 'https';
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
-
}) : x)(function(x) {
|
|
8
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
-
});
|
|
7
|
+
// src/index.ts
|
|
11
8
|
|
|
12
9
|
// src/registry.ts
|
|
13
10
|
var LLM_REGISTRY = {
|
|
@@ -344,25 +341,40 @@ function patchFetch(transport2) {
|
|
|
344
341
|
patched.__agentlens_patched = true;
|
|
345
342
|
globalThis.fetch = patched;
|
|
346
343
|
}
|
|
347
|
-
|
|
348
|
-
|
|
344
|
+
var responseChunkRegistry = /* @__PURE__ */ new WeakMap();
|
|
345
|
+
var incomingMessagePatched = false;
|
|
349
346
|
function patchHttps(transport2) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
try {
|
|
354
|
-
patchModule("https", transport2);
|
|
355
|
-
patchModule("http", transport2);
|
|
356
|
-
} catch {
|
|
357
|
-
}
|
|
347
|
+
patchIncomingMessage();
|
|
348
|
+
patchModule(http, "http", transport2);
|
|
349
|
+
patchModule(https, "https", transport2);
|
|
358
350
|
}
|
|
359
|
-
function
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
351
|
+
function patchIncomingMessage() {
|
|
352
|
+
if (incomingMessagePatched) return;
|
|
353
|
+
const IncomingMessage = http.IncomingMessage;
|
|
354
|
+
if (!IncomingMessage?.prototype) return;
|
|
355
|
+
const proto = IncomingMessage.prototype;
|
|
356
|
+
const originalPush = proto.push;
|
|
357
|
+
proto.push = function patchedPush(chunk, encoding) {
|
|
358
|
+
if (chunk !== null) {
|
|
359
|
+
const chunks = responseChunkRegistry.get(this);
|
|
360
|
+
if (chunks) {
|
|
361
|
+
try {
|
|
362
|
+
if (Buffer.isBuffer(chunk)) {
|
|
363
|
+
chunks.push(chunk);
|
|
364
|
+
} else if (typeof chunk === "string") {
|
|
365
|
+
chunks.push(Buffer.from(chunk, encoding ?? "utf8"));
|
|
366
|
+
} else if (chunk && typeof chunk === "object") {
|
|
367
|
+
chunks.push(Buffer.from(chunk));
|
|
368
|
+
}
|
|
369
|
+
} catch {
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return originalPush.call(this, chunk, encoding);
|
|
374
|
+
};
|
|
375
|
+
incomingMessagePatched = true;
|
|
376
|
+
}
|
|
377
|
+
function patchModule(mod, name, transport2) {
|
|
366
378
|
if (mod.__agentlens_patched) return;
|
|
367
379
|
const original = mod.request.bind(mod);
|
|
368
380
|
mod.request = function patchedRequest(...args) {
|
|
@@ -370,7 +382,6 @@ function patchModule(name, transport2) {
|
|
|
370
382
|
if (!ctx) return original(...args);
|
|
371
383
|
const start = Date.now();
|
|
372
384
|
const requestChunks = [];
|
|
373
|
-
const responseChunks = [];
|
|
374
385
|
const req = original(...args);
|
|
375
386
|
const originalWrite = req.write.bind(req);
|
|
376
387
|
req.write = function(chunk, ...rest) {
|
|
@@ -382,16 +393,12 @@ function patchModule(name, transport2) {
|
|
|
382
393
|
};
|
|
383
394
|
req.on("response", (...resArgs) => {
|
|
384
395
|
const res = resArgs[0];
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
responseChunks.push(toBuffer(chunk));
|
|
388
|
-
} catch {
|
|
389
|
-
}
|
|
390
|
-
});
|
|
396
|
+
const chunks = [];
|
|
397
|
+
responseChunkRegistry.set(res, chunks);
|
|
391
398
|
res.on("end", () => {
|
|
392
399
|
const latency = Date.now() - start;
|
|
393
400
|
const requestText = Buffer.concat(requestChunks).toString("utf8");
|
|
394
|
-
const responseText = Buffer.concat(
|
|
401
|
+
const responseText = Buffer.concat(chunks).toString("utf8");
|
|
395
402
|
const requestBody = safeParse(requestText);
|
|
396
403
|
const responseBody = safeParse(responseText);
|
|
397
404
|
if (responseBody) {
|
|
@@ -405,6 +412,7 @@ function patchModule(name, transport2) {
|
|
|
405
412
|
isStream: requestBody?.stream === true
|
|
406
413
|
});
|
|
407
414
|
}
|
|
415
|
+
responseChunkRegistry.delete(res);
|
|
408
416
|
});
|
|
409
417
|
});
|
|
410
418
|
req.on("error", (...errArgs) => {
|
|
@@ -838,6 +846,7 @@ var Transport = class {
|
|
|
838
846
|
constructor(config) {
|
|
839
847
|
this.config = {
|
|
840
848
|
apiKey: config.apiKey,
|
|
849
|
+
projectId: config.projectId,
|
|
841
850
|
endpoint: config.endpoint,
|
|
842
851
|
flushIntervalMs: config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
|
|
843
852
|
maxBatchSize: config.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE,
|
|
@@ -848,6 +857,8 @@ var Transport = class {
|
|
|
848
857
|
this.registerExitHandler();
|
|
849
858
|
}
|
|
850
859
|
push(payload) {
|
|
860
|
+
const startedAt = new Date(Date.now() - payload.latency).toISOString();
|
|
861
|
+
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
851
862
|
let parsed;
|
|
852
863
|
try {
|
|
853
864
|
parsed = parseSpan({
|
|
@@ -862,28 +873,34 @@ var Transport = class {
|
|
|
862
873
|
}
|
|
863
874
|
return;
|
|
864
875
|
}
|
|
865
|
-
const outbound = this.toOutbound(parsed, payload
|
|
876
|
+
const outbound = this.toOutbound(parsed, payload, startedAt, endedAt);
|
|
866
877
|
this.enqueue(outbound);
|
|
867
878
|
}
|
|
868
879
|
pushError(payload) {
|
|
869
880
|
const ids = this.resolveIds();
|
|
881
|
+
const startedAt = new Date(Date.now() - payload.latency).toISOString();
|
|
882
|
+
const endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
870
883
|
const span = {
|
|
871
884
|
spanId: ids.spanId,
|
|
872
885
|
traceId: ids.traceId,
|
|
873
886
|
parentSpanId: ids.parentSpanId,
|
|
887
|
+
projectId: this.config.projectId,
|
|
888
|
+
name: `${payload.provider}.error`,
|
|
874
889
|
model: "unknown",
|
|
875
890
|
provider: payload.provider,
|
|
891
|
+
input: this.scrub(this.stringifyRequest(payload.request)),
|
|
892
|
+
output: "",
|
|
876
893
|
inputTokens: 0,
|
|
877
894
|
outputTokens: 0,
|
|
878
895
|
totalTokens: 0,
|
|
879
896
|
costUsd: 0,
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
897
|
+
latencyMs: payload.latency,
|
|
898
|
+
status: "error",
|
|
899
|
+
errorMessage: payload.error,
|
|
900
|
+
metadata: { httpStatus: 0 },
|
|
901
|
+
startedAt,
|
|
902
|
+
endedAt,
|
|
903
|
+
isStream: false
|
|
887
904
|
};
|
|
888
905
|
this.enqueue(span);
|
|
889
906
|
}
|
|
@@ -905,18 +922,30 @@ var Transport = class {
|
|
|
905
922
|
this.timer = null;
|
|
906
923
|
}
|
|
907
924
|
}
|
|
908
|
-
toOutbound(parsed,
|
|
925
|
+
toOutbound(parsed, payload, startedAt, endedAt) {
|
|
909
926
|
const ids = this.resolveIds();
|
|
927
|
+
const status = payload.status >= 200 && payload.status < 400 ? "success" : "error";
|
|
910
928
|
return {
|
|
911
|
-
...parsed,
|
|
912
929
|
spanId: ids.spanId,
|
|
913
930
|
traceId: ids.traceId,
|
|
914
931
|
parentSpanId: ids.parentSpanId,
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
932
|
+
projectId: this.config.projectId,
|
|
933
|
+
name: spanNameFor(payload),
|
|
934
|
+
model: parsed.model,
|
|
935
|
+
provider: parsed.provider,
|
|
936
|
+
input: this.scrub(parsed.inputText),
|
|
937
|
+
output: this.scrub(parsed.outputText),
|
|
938
|
+
inputTokens: parsed.inputTokens,
|
|
939
|
+
outputTokens: parsed.outputTokens,
|
|
940
|
+
totalTokens: parsed.totalTokens,
|
|
941
|
+
costUsd: parsed.costUsd,
|
|
942
|
+
latencyMs: payload.latency,
|
|
918
943
|
status,
|
|
919
|
-
|
|
944
|
+
errorMessage: parsed.error,
|
|
945
|
+
metadata: { httpStatus: payload.status },
|
|
946
|
+
startedAt,
|
|
947
|
+
endedAt,
|
|
948
|
+
isStream: parsed.isStream
|
|
920
949
|
};
|
|
921
950
|
}
|
|
922
951
|
/**
|
|
@@ -955,12 +984,13 @@ var Transport = class {
|
|
|
955
984
|
enqueue(span) {
|
|
956
985
|
if (this.config.debug) {
|
|
957
986
|
console.log("[agentlens] span", {
|
|
987
|
+
name: span.name,
|
|
958
988
|
model: span.model,
|
|
959
989
|
provider: span.provider,
|
|
960
990
|
inputTokens: span.inputTokens,
|
|
961
991
|
outputTokens: span.outputTokens,
|
|
962
992
|
costUsd: span.costUsd,
|
|
963
|
-
|
|
993
|
+
latencyMs: span.latencyMs,
|
|
964
994
|
isStream: span.isStream
|
|
965
995
|
});
|
|
966
996
|
}
|
|
@@ -1021,6 +1051,9 @@ var Transport = class {
|
|
|
1021
1051
|
method: "POST",
|
|
1022
1052
|
headers: {
|
|
1023
1053
|
"content-type": "application/json",
|
|
1054
|
+
// Hosted ingest expects X-API-Key. Send Authorization too for any
|
|
1055
|
+
// gateways that may sit in front (some Cloudflare workers want it).
|
|
1056
|
+
"x-api-key": this.config.apiKey,
|
|
1024
1057
|
authorization: `Bearer ${this.config.apiKey}`
|
|
1025
1058
|
},
|
|
1026
1059
|
body
|
|
@@ -1028,6 +1061,17 @@ var Transport = class {
|
|
|
1028
1061
|
return { ok: res.ok, status: res.status };
|
|
1029
1062
|
}
|
|
1030
1063
|
};
|
|
1064
|
+
function spanNameFor(payload) {
|
|
1065
|
+
const req = payload.request;
|
|
1066
|
+
if (req && Array.isArray(req.messages)) return `${payload.provider}.chat`;
|
|
1067
|
+
if (req && (typeof req.prompt === "string" || typeof req.input === "string")) {
|
|
1068
|
+
return `${payload.provider}.completion`;
|
|
1069
|
+
}
|
|
1070
|
+
if (req && (req.input !== void 0 || req.contents !== void 0)) {
|
|
1071
|
+
return `${payload.provider}.embedding`;
|
|
1072
|
+
}
|
|
1073
|
+
return `${payload.provider}.call`;
|
|
1074
|
+
}
|
|
1031
1075
|
function sleep(ms) {
|
|
1032
1076
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1033
1077
|
}
|
|
@@ -1040,9 +1084,13 @@ var AgentLens = {
|
|
|
1040
1084
|
if (!config?.apiKey) {
|
|
1041
1085
|
throw new Error("AgentLens.init requires an apiKey");
|
|
1042
1086
|
}
|
|
1087
|
+
if (!config?.projectId) {
|
|
1088
|
+
throw new Error("AgentLens.init requires a projectId");
|
|
1089
|
+
}
|
|
1043
1090
|
initialized = true;
|
|
1044
1091
|
transport = new Transport({
|
|
1045
1092
|
apiKey: config.apiKey,
|
|
1093
|
+
projectId: config.projectId,
|
|
1046
1094
|
endpoint: config.endpoint ?? DEFAULT_ENDPOINT,
|
|
1047
1095
|
debug: config.debug ?? false,
|
|
1048
1096
|
pii: config.pii ?? true,
|