@use-lattice/litmus 0.121.3
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/LICENSE +19 -0
- package/dist/src/accounts-Bt1oJb1Z.cjs +219 -0
- package/dist/src/accounts-DjOU8Rm3.js +178 -0
- package/dist/src/agentic-utils-D03IiXQc.js +153 -0
- package/dist/src/agentic-utils-Dh7xaMQM.cjs +180 -0
- package/dist/src/agents-C6BIMlZa.js +231 -0
- package/dist/src/agents-DvIpNX1L.cjs +666 -0
- package/dist/src/agents-ZP0RP9vV.cjs +231 -0
- package/dist/src/agents-maJXdjbR.js +665 -0
- package/dist/src/aimlapi-BTbQjG2E.cjs +30 -0
- package/dist/src/aimlapi-CwMxqfXP.js +30 -0
- package/dist/src/audio-BBUdvsde.cjs +97 -0
- package/dist/src/audio-D5DPZ7I-.js +97 -0
- package/dist/src/base-BEysXrkq.cjs +222 -0
- package/dist/src/base-C451JQfq.js +193 -0
- package/dist/src/blobs-BY8MDmpo.js +230 -0
- package/dist/src/blobs-BgcNn97m.cjs +256 -0
- package/dist/src/cache-BBE_lsTA.cjs +4 -0
- package/dist/src/cache-BkrqU5Ba.js +237 -0
- package/dist/src/cache-DsCxFlsZ.cjs +297 -0
- package/dist/src/chat-CPJWDP6a.cjs +289 -0
- package/dist/src/chat-CXX3xzkk.cjs +811 -0
- package/dist/src/chat-CcDgZFJ4.js +787 -0
- package/dist/src/chat-Dz5ZeGO2.js +289 -0
- package/dist/src/chatkit-Dw0mKkML.cjs +1158 -0
- package/dist/src/chatkit-swAIVuea.js +1157 -0
- package/dist/src/chunk-DEq-mXcV.js +15 -0
- package/dist/src/claude-agent-sdk-BXZJtOg6.js +379 -0
- package/dist/src/claude-agent-sdk-CkfyjDoG.cjs +383 -0
- package/dist/src/cloudflare-ai-BzpJcqUH.js +161 -0
- package/dist/src/cloudflare-ai-Cmy_R1y2.cjs +161 -0
- package/dist/src/cloudflare-gateway-B9tVQKok.cjs +272 -0
- package/dist/src/cloudflare-gateway-DrD3ew3H.js +272 -0
- package/dist/src/codex-sdk-Dezj9Nwm.js +1056 -0
- package/dist/src/codex-sdk-Dl9D4k5B.cjs +1060 -0
- package/dist/src/cometapi-C-9YvCHC.js +54 -0
- package/dist/src/cometapi-DHgDKoO2.cjs +54 -0
- package/dist/src/completion-B8Ctyxpr.js +120 -0
- package/dist/src/completion-Cxrt08sj.cjs +131 -0
- package/dist/src/createHash-BwgE13yv.cjs +27 -0
- package/dist/src/createHash-DmPQkvBh.js +15 -0
- package/dist/src/docker-BiqcTwLv.js +80 -0
- package/dist/src/docker-C7tEJnP-.cjs +80 -0
- package/dist/src/esm-C62Zofr1.cjs +409 -0
- package/dist/src/esm-DMVc93eh.js +379 -0
- package/dist/src/evalResult-C3NJPQOo.cjs +301 -0
- package/dist/src/evalResult-C7JJAPBb.js +295 -0
- package/dist/src/evalResult-DoVTZZWI.cjs +2 -0
- package/dist/src/extractor-DnMD3fwt.cjs +391 -0
- package/dist/src/extractor-DtlL28vL.js +374 -0
- package/dist/src/fetch-BTxakTSg.cjs +1133 -0
- package/dist/src/fetch-DQckpUFz.js +928 -0
- package/dist/src/fileExtensions-DnqA1y9x.js +85 -0
- package/dist/src/fileExtensions-bYh77CN8.cjs +114 -0
- package/dist/src/genaiTracer-CyZrmaK0.cjs +268 -0
- package/dist/src/genaiTracer-D3fD9dNV.js +256 -0
- package/dist/src/graders-BNscxFrU.js +13644 -0
- package/dist/src/graders-D2oE9Msq.js +2 -0
- package/dist/src/graders-c0Ez_w-9.cjs +2 -0
- package/dist/src/graders-d0F2M3e9.cjs +14056 -0
- package/dist/src/image-0ZhE0VlR.cjs +280 -0
- package/dist/src/image-CWE1pdNv.js +257 -0
- package/dist/src/image-D9ZK6hwL.js +163 -0
- package/dist/src/image-DKZgZITg.cjs +163 -0
- package/dist/src/index.cjs +11366 -0
- package/dist/src/index.d.cts +19640 -0
- package/dist/src/index.d.ts +19641 -0
- package/dist/src/index.js +11306 -0
- package/dist/src/invariant-Ddh24eXh.js +25 -0
- package/dist/src/invariant-kfQ8Bu82.cjs +30 -0
- package/dist/src/knowledgeBase-BgPyGFUd.cjs +122 -0
- package/dist/src/knowledgeBase-DyHilYaP.js +122 -0
- package/dist/src/litellm-CyMeneHS.js +135 -0
- package/dist/src/litellm-DWDF73yF.cjs +135 -0
- package/dist/src/logger-C40ZGil9.js +717 -0
- package/dist/src/logger-DyfK9PBt.cjs +917 -0
- package/dist/src/luma-ray-BAU9X_ep.cjs +315 -0
- package/dist/src/luma-ray-nwVseBbv.js +313 -0
- package/dist/src/messages-B5ADWTTv.js +245 -0
- package/dist/src/messages-BCnZfqrS.cjs +257 -0
- package/dist/src/meteor-DLZZ3osF.cjs +134 -0
- package/dist/src/meteor-DUiCJRC-.js +134 -0
- package/dist/src/modelslab-00cveB8L.cjs +163 -0
- package/dist/src/modelslab-D9sCU_L7.js +163 -0
- package/dist/src/nova-reel-CTapvqYH.js +276 -0
- package/dist/src/nova-reel-DlWuuroF.cjs +278 -0
- package/dist/src/nova-sonic-5UPWfeMv.cjs +363 -0
- package/dist/src/nova-sonic-BhSwQNym.js +363 -0
- package/dist/src/openai-BWrJK9d8.cjs +52 -0
- package/dist/src/openai-DumO8WQn.js +47 -0
- package/dist/src/openclaw-B8brrjC_.cjs +577 -0
- package/dist/src/openclaw-Bkayww9q.js +571 -0
- package/dist/src/opencode-sdk-7xjoDNiM.cjs +562 -0
- package/dist/src/opencode-sdk-SGwAPxht.js +558 -0
- package/dist/src/otlpReceiver-CoAHfAN9.cjs +15 -0
- package/dist/src/otlpReceiver-oO3EQwI9.js +14 -0
- package/dist/src/providerRegistry-4yjhaEM8.js +45 -0
- package/dist/src/providerRegistry-DhV4rJIc.cjs +50 -0
- package/dist/src/providers-B5RJVG-7.cjs +33609 -0
- package/dist/src/providers-BdmZCLzV.js +33262 -0
- package/dist/src/providers-CxtRxn8e.js +2 -0
- package/dist/src/providers-DnQLNbx1.cjs +3 -0
- package/dist/src/pythonUtils-BD0druiM.cjs +275 -0
- package/dist/src/pythonUtils-IBhn5YGR.js +249 -0
- package/dist/src/quiverai-BDOwZBsM.cjs +213 -0
- package/dist/src/quiverai-D3JTF5lD.js +213 -0
- package/dist/src/responses-B2LCDCXZ.js +667 -0
- package/dist/src/responses-BvNm4Xv9.cjs +685 -0
- package/dist/src/rubyUtils-B0NwnfpY.cjs +245 -0
- package/dist/src/rubyUtils-BroxzZ7c.cjs +2 -0
- package/dist/src/rubyUtils-hqVw5UvJ.js +222 -0
- package/dist/src/sagemaker-Cno2V-Sx.js +689 -0
- package/dist/src/sagemaker-fV_KUgs5.cjs +691 -0
- package/dist/src/server-BOuAXb06.cjs +238 -0
- package/dist/src/server-CtI-EWzm.cjs +2 -0
- package/dist/src/server-Cy3DZymt.js +189 -0
- package/dist/src/slack-CP8xBePa.js +135 -0
- package/dist/src/slack-DSQ1yXVb.cjs +135 -0
- package/dist/src/store-BwDDaBjb.cjs +246 -0
- package/dist/src/store-DcbLC593.cjs +2 -0
- package/dist/src/store-IGpqMIkv.js +240 -0
- package/dist/src/tables-3Q2cL7So.cjs +373 -0
- package/dist/src/tables-Bi2fjr4W.js +288 -0
- package/dist/src/telemetry-Bg2WqF79.js +161 -0
- package/dist/src/telemetry-D0x6u5kX.cjs +166 -0
- package/dist/src/telemetry-DXNimrI0.cjs +2 -0
- package/dist/src/text-B_UCRPp2.js +22 -0
- package/dist/src/text-CW1cyrwj.cjs +33 -0
- package/dist/src/tokenUsageUtils-NYT-WKS6.js +138 -0
- package/dist/src/tokenUsageUtils-bVa1ga6f.cjs +173 -0
- package/dist/src/transcription-Cl_W16Pr.js +122 -0
- package/dist/src/transcription-yt1EecY8.cjs +124 -0
- package/dist/src/transform-BCtGrl_W.cjs +228 -0
- package/dist/src/transform-Bv6gG2MJ.cjs +1688 -0
- package/dist/src/transform-CY1wbpRy.js +1507 -0
- package/dist/src/transform-DU8rUL9P.cjs +2 -0
- package/dist/src/transform-yWaShiKr.js +216 -0
- package/dist/src/transformersAvailability-BGkzavwb.js +35 -0
- package/dist/src/transformersAvailability-DKoRtQLy.cjs +35 -0
- package/dist/src/types-5aqHpBwE.cjs +3769 -0
- package/dist/src/types-Bn6D9c4U.js +3300 -0
- package/dist/src/util-BkKlTkI2.js +293 -0
- package/dist/src/util-CTh0bfOm.cjs +1119 -0
- package/dist/src/util-D17oBwo7.cjs +328 -0
- package/dist/src/util-DsS_-v4p.js +613 -0
- package/dist/src/util-DuntT1Ga.js +951 -0
- package/dist/src/util-aWjdCYMI.cjs +667 -0
- package/dist/src/utils-CisQwpjA.js +94 -0
- package/dist/src/utils-yWamDvmz.cjs +123 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/drizzle/0000_lush_hellion.sql +36 -0
- package/drizzle/0001_wide_calypso.sql +3 -0
- package/drizzle/0002_tidy_juggernaut.sql +1 -0
- package/drizzle/0003_lively_naoko.sql +8 -0
- package/drizzle/0004_minor_peter_quill.sql +19 -0
- package/drizzle/0005_silky_millenium_guard.sql +2 -0
- package/drizzle/0006_harsh_caretaker.sql +42 -0
- package/drizzle/0007_cloudy_wong.sql +1 -0
- package/drizzle/0008_broad_boomer.sql +2 -0
- package/drizzle/0009_strong_marten_broadcloak.sql +19 -0
- package/drizzle/0010_needy_bishop.sql +11 -0
- package/drizzle/0011_moaning_millenium_guard.sql +1 -0
- package/drizzle/0012_late_marten_broadcloak.sql +2 -0
- package/drizzle/0013_previous_dormammu.sql +9 -0
- package/drizzle/0014_lazy_captain_universe.sql +2 -0
- package/drizzle/0015_zippy_wallop.sql +29 -0
- package/drizzle/0016_jazzy_zemo.sql +2 -0
- package/drizzle/0017_reflective_praxagora.sql +4 -0
- package/drizzle/0018_fat_vanisher.sql +22 -0
- package/drizzle/0019_new_clint_barton.sql +8 -0
- package/drizzle/0020_skinny_maverick.sql +1 -0
- package/drizzle/0021_mysterious_madelyne_pryor.sql +13 -0
- package/drizzle/0022_sleepy_ultimo.sql +25 -0
- package/drizzle/0023_wooden_mandrill.sql +2 -0
- package/drizzle/AGENTS.md +68 -0
- package/drizzle/CLAUDE.md +1 -0
- package/drizzle/meta/0000_snapshot.json +221 -0
- package/drizzle/meta/0001_snapshot.json +214 -0
- package/drizzle/meta/0002_snapshot.json +221 -0
- package/drizzle/meta/0005_snapshot.json +369 -0
- package/drizzle/meta/0006_snapshot.json +638 -0
- package/drizzle/meta/0007_snapshot.json +640 -0
- package/drizzle/meta/0008_snapshot.json +649 -0
- package/drizzle/meta/0009_snapshot.json +554 -0
- package/drizzle/meta/0010_snapshot.json +619 -0
- package/drizzle/meta/0011_snapshot.json +627 -0
- package/drizzle/meta/0012_snapshot.json +639 -0
- package/drizzle/meta/0013_snapshot.json +717 -0
- package/drizzle/meta/0014_snapshot.json +717 -0
- package/drizzle/meta/0015_snapshot.json +897 -0
- package/drizzle/meta/0016_snapshot.json +1031 -0
- package/drizzle/meta/0018_snapshot.json +1210 -0
- package/drizzle/meta/0019_snapshot.json +1165 -0
- package/drizzle/meta/0020_snapshot.json +1232 -0
- package/drizzle/meta/0021_snapshot.json +1311 -0
- package/drizzle/meta/0022_snapshot.json +1481 -0
- package/drizzle/meta/0023_snapshot.json +1496 -0
- package/drizzle/meta/_journal.json +174 -0
- package/package.json +240 -0
|
@@ -0,0 +1,917 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __exportAll = (all, no_symbols) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
+
key = keys[i];
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
21
|
+
get: ((k) => from[k]).bind(null, key),
|
|
22
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
28
|
+
value: mod,
|
|
29
|
+
enumerable: true
|
|
30
|
+
}) : target, mod));
|
|
31
|
+
//#endregion
|
|
32
|
+
const require_invariant = require("./invariant-kfQ8Bu82.cjs");
|
|
33
|
+
let fs = require("fs");
|
|
34
|
+
fs = __toESM(fs);
|
|
35
|
+
let path = require("path");
|
|
36
|
+
path = __toESM(path);
|
|
37
|
+
let js_yaml = require("js-yaml");
|
|
38
|
+
js_yaml = __toESM(js_yaml);
|
|
39
|
+
let dotenv = require("dotenv");
|
|
40
|
+
dotenv = __toESM(dotenv);
|
|
41
|
+
let winston = require("winston");
|
|
42
|
+
winston = __toESM(winston);
|
|
43
|
+
let os = require("os");
|
|
44
|
+
os = __toESM(os);
|
|
45
|
+
let ajv = require("ajv");
|
|
46
|
+
ajv = __toESM(ajv);
|
|
47
|
+
let ajv_formats = require("ajv-formats");
|
|
48
|
+
ajv_formats = __toESM(ajv_formats);
|
|
49
|
+
let fast_safe_stringify = require("fast-safe-stringify");
|
|
50
|
+
fast_safe_stringify = __toESM(fast_safe_stringify);
|
|
51
|
+
//#region src/cliState.ts
|
|
52
|
+
const state = {};
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/envars.ts
|
|
55
|
+
dotenv.default.config({ quiet: true });
|
|
56
|
+
function getEnvString(key, defaultValue) {
|
|
57
|
+
if (state.config?.env && typeof state.config.env === "object") {
|
|
58
|
+
const envValue = state.config.env[key];
|
|
59
|
+
if (envValue !== void 0) return String(envValue);
|
|
60
|
+
}
|
|
61
|
+
const value = process.env[key];
|
|
62
|
+
if (value === void 0) return defaultValue;
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get a boolean environment variable.
|
|
67
|
+
* @param key The name of the environment variable.
|
|
68
|
+
* @param defaultValue Optional default value if the environment variable is not set.
|
|
69
|
+
* @returns The boolean value of the environment variable, or the default value if provided.
|
|
70
|
+
*/
|
|
71
|
+
function getEnvBool(key, defaultValue) {
|
|
72
|
+
const value = getEnvString(key) || defaultValue;
|
|
73
|
+
if (typeof value === "boolean") return value;
|
|
74
|
+
if (typeof value === "string") return [
|
|
75
|
+
"1",
|
|
76
|
+
"true",
|
|
77
|
+
"yes",
|
|
78
|
+
"yup",
|
|
79
|
+
"yeppers"
|
|
80
|
+
].includes(value.toLowerCase());
|
|
81
|
+
return Boolean(defaultValue);
|
|
82
|
+
}
|
|
83
|
+
function getEnvInt(key, defaultValue) {
|
|
84
|
+
const str = getEnvString(key);
|
|
85
|
+
if (str === void 0 || str === "") return defaultValue;
|
|
86
|
+
const parsedValue = Number.parseInt(str, 10);
|
|
87
|
+
if (!Number.isNaN(parsedValue)) return parsedValue;
|
|
88
|
+
return defaultValue;
|
|
89
|
+
}
|
|
90
|
+
function getEnvFloat(key, defaultValue) {
|
|
91
|
+
const str = getEnvString(key);
|
|
92
|
+
if (str === void 0 || str === "") return defaultValue;
|
|
93
|
+
const parsedValue = Number.parseFloat(str);
|
|
94
|
+
if (!Number.isNaN(parsedValue)) return parsedValue;
|
|
95
|
+
return defaultValue;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get the timeout in milliseconds for each individual test case/provider API call.
|
|
99
|
+
* When this timeout is reached, that specific test is marked as an error.
|
|
100
|
+
* @param defaultValue Optional default value if the environment variable is not set. Defaults to 0 (no timeout).
|
|
101
|
+
* @returns The timeout value in milliseconds, or the default value if not set.
|
|
102
|
+
*/
|
|
103
|
+
function getEvalTimeoutMs(defaultValue = 0) {
|
|
104
|
+
return getEnvInt("PROMPTFOO_EVAL_TIMEOUT_MS", defaultValue);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the maximum total runtime in milliseconds for the entire evaluation process.
|
|
108
|
+
* When this timeout is reached, all remaining tests are marked as errors and the evaluation ends.
|
|
109
|
+
* @param defaultValue Optional default value if the environment variable is not set. Defaults to 0 (no limit).
|
|
110
|
+
* @returns The max duration in milliseconds, or the default value if not set.
|
|
111
|
+
*/
|
|
112
|
+
function getMaxEvalTimeMs(defaultValue = 0) {
|
|
113
|
+
return getEnvInt("PROMPTFOO_MAX_EVAL_TIME_MS", defaultValue);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Check if the application is running in a CI environment.
|
|
117
|
+
* @returns True if running in a CI environment, false otherwise.
|
|
118
|
+
*/
|
|
119
|
+
function isCI() {
|
|
120
|
+
return getEnvBool("CI") || getEnvBool("GITHUB_ACTIONS") || getEnvBool("TRAVIS") || getEnvBool("CIRCLECI") || getEnvBool("JENKINS") || getEnvBool("GITLAB_CI") || getEnvBool("APPVEYOR") || getEnvBool("CODEBUILD_BUILD_ID") || getEnvBool("TF_BUILD") || getEnvBool("BITBUCKET_COMMIT") || getEnvBool("BUDDY") || getEnvBool("BUILDKITE") || getEnvBool("TEAMCITY_VERSION");
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/util/config/manage.ts
|
|
124
|
+
let configDirectoryPath = getEnvString("PROMPTFOO_CONFIG_DIR");
|
|
125
|
+
const isNodeEnvironment = typeof process !== "undefined" && process.versions && process.versions.node;
|
|
126
|
+
function getConfigDirectoryPath(createIfNotExists = false) {
|
|
127
|
+
const p = configDirectoryPath || path.join(os.homedir(), ".promptfoo");
|
|
128
|
+
if (createIfNotExists && isNodeEnvironment) try {
|
|
129
|
+
fs.default.mkdirSync(p, { recursive: true });
|
|
130
|
+
} catch {}
|
|
131
|
+
return p;
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/util/json.ts
|
|
135
|
+
let ajvInstance = null;
|
|
136
|
+
function getAjv() {
|
|
137
|
+
if (!ajvInstance) {
|
|
138
|
+
ajvInstance = new ajv.default({ strictSchema: !getEnvBool("PROMPTFOO_DISABLE_AJV_STRICT_MODE") });
|
|
139
|
+
(0, ajv_formats.default)(ajvInstance);
|
|
140
|
+
}
|
|
141
|
+
return ajvInstance;
|
|
142
|
+
}
|
|
143
|
+
function isValidJson(str) {
|
|
144
|
+
try {
|
|
145
|
+
JSON.parse(str);
|
|
146
|
+
return true;
|
|
147
|
+
} catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Creates a truncated version of an object for safe JSON stringification.
|
|
153
|
+
* Prevents memory issues by limiting string, array, and object sizes.
|
|
154
|
+
*
|
|
155
|
+
* @param value - The value to truncate and stringify
|
|
156
|
+
* @param prettyPrint - Whether to format the JSON with indentation
|
|
157
|
+
* @returns A JSON string representation of the truncated value
|
|
158
|
+
*/
|
|
159
|
+
function safeJsonStringifyTruncated(value, prettyPrint = false) {
|
|
160
|
+
const cache = /* @__PURE__ */ new Set();
|
|
161
|
+
const space = prettyPrint ? 2 : void 0;
|
|
162
|
+
const truncateValue = (val) => {
|
|
163
|
+
if (typeof val === "string") return val.length > 1e3 ? val.substring(0, 1e3) + "...[truncated]" : val;
|
|
164
|
+
if (Array.isArray(val)) {
|
|
165
|
+
const truncated = val.slice(0, 10).map(truncateValue);
|
|
166
|
+
if (val.length > 10) truncated.push(`...[${val.length - 10} more items]`);
|
|
167
|
+
return truncated;
|
|
168
|
+
}
|
|
169
|
+
if (typeof val === "object" && val !== null) {
|
|
170
|
+
if (cache.has(val)) return "[Circular Reference]";
|
|
171
|
+
cache.add(val);
|
|
172
|
+
const truncated = {};
|
|
173
|
+
let count = 0;
|
|
174
|
+
for (const [k, v] of Object.entries(val)) {
|
|
175
|
+
if (count >= 20) {
|
|
176
|
+
truncated["...[truncated]"] = `${Object.keys(val).length - count} more keys`;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
truncated[k] = truncateValue(v);
|
|
180
|
+
count++;
|
|
181
|
+
}
|
|
182
|
+
cache.delete(val);
|
|
183
|
+
return truncated;
|
|
184
|
+
}
|
|
185
|
+
return val;
|
|
186
|
+
};
|
|
187
|
+
try {
|
|
188
|
+
return JSON.stringify(truncateValue(value), null, space) || "{}";
|
|
189
|
+
} catch {
|
|
190
|
+
return `{"error": "Failed to stringify even truncated data", "type": "${typeof value}", "constructor": "${value?.constructor?.name || "unknown"}"}`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Safely stringify a value to JSON, handling circular references and large objects.
|
|
195
|
+
*
|
|
196
|
+
* @param value - The value to stringify
|
|
197
|
+
* @param prettyPrint - Whether to format the JSON with indentation
|
|
198
|
+
* @returns JSON string representation, or undefined if serialization fails
|
|
199
|
+
*/
|
|
200
|
+
function safeJsonStringify(value, prettyPrint = false) {
|
|
201
|
+
const ancestors = [];
|
|
202
|
+
const space = prettyPrint ? 2 : void 0;
|
|
203
|
+
try {
|
|
204
|
+
return JSON.stringify(value, function(_key, val) {
|
|
205
|
+
if (typeof val === "object" && val !== null) {
|
|
206
|
+
while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) ancestors.pop();
|
|
207
|
+
if (ancestors.includes(val)) return;
|
|
208
|
+
ancestors.push(val);
|
|
209
|
+
}
|
|
210
|
+
return val;
|
|
211
|
+
}, space) || void 0;
|
|
212
|
+
} catch (error) {
|
|
213
|
+
if (error instanceof RangeError && error.message.includes("Invalid string length")) return safeJsonStringifyTruncated(value, prettyPrint);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function convertSlashCommentsToHash(str) {
|
|
218
|
+
return str.split("\n").map((line) => {
|
|
219
|
+
let state = "normal";
|
|
220
|
+
let result = "";
|
|
221
|
+
let i = 0;
|
|
222
|
+
while (i < line.length) {
|
|
223
|
+
const char = line[i];
|
|
224
|
+
const nextChar = line[i + 1];
|
|
225
|
+
const prevChar = i > 0 ? line[i - 1] : "";
|
|
226
|
+
switch (state) {
|
|
227
|
+
case "normal":
|
|
228
|
+
if (char === "'" && !/[a-zA-Z]/.test(prevChar)) {
|
|
229
|
+
state = "singleQuote";
|
|
230
|
+
result += char;
|
|
231
|
+
} else if (char === "\"") {
|
|
232
|
+
state = "doubleQuote";
|
|
233
|
+
result += char;
|
|
234
|
+
} else if (char === "/" && nextChar === "/") {
|
|
235
|
+
let tokenStart = 0;
|
|
236
|
+
for (let j = i - 1; j >= 0; j--) if (/\s/.test(line[j])) {
|
|
237
|
+
tokenStart = j + 1;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
if (line.slice(tokenStart, i + 2).includes("://")) {
|
|
241
|
+
result += char;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
let slashCount = 2;
|
|
245
|
+
while (i + slashCount < line.length && line[i + slashCount] === "/") slashCount++;
|
|
246
|
+
const hashes = "#".repeat(Math.floor(slashCount / 2));
|
|
247
|
+
return result + hashes + line.slice(i + slashCount);
|
|
248
|
+
} else result += char;
|
|
249
|
+
break;
|
|
250
|
+
case "singleQuote":
|
|
251
|
+
result += char;
|
|
252
|
+
if (char === "'" && prevChar !== "\\" && !/[a-zA-Z]/.test(nextChar)) state = "normal";
|
|
253
|
+
break;
|
|
254
|
+
case "doubleQuote":
|
|
255
|
+
result += char;
|
|
256
|
+
if (char === "\"" && prevChar !== "\\") state = "normal";
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
i++;
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
262
|
+
}).join("\n");
|
|
263
|
+
}
|
|
264
|
+
function extractJsonObjects(str) {
|
|
265
|
+
const jsonObjects = [];
|
|
266
|
+
const maxJsonLength = 1e5;
|
|
267
|
+
for (let i = 0; i < str.length; i++) if (str[i] === "{") {
|
|
268
|
+
let openBraces = 1;
|
|
269
|
+
let closeBraces = 0;
|
|
270
|
+
let j = i + 1;
|
|
271
|
+
while (j < Math.min(i + maxJsonLength, str.length) && openBraces > closeBraces) {
|
|
272
|
+
if (str[j] === "{") openBraces++;
|
|
273
|
+
if (str[j] === "}") closeBraces++;
|
|
274
|
+
j++;
|
|
275
|
+
if (openBraces === closeBraces || j === str.length || j === i + maxJsonLength) try {
|
|
276
|
+
let potentialJson = str.slice(i, j);
|
|
277
|
+
if (openBraces > closeBraces) potentialJson += "}".repeat(openBraces - closeBraces);
|
|
278
|
+
const processedJson = convertSlashCommentsToHash(potentialJson);
|
|
279
|
+
const parsedObj = js_yaml.default.load(processedJson, { json: true });
|
|
280
|
+
if (typeof parsedObj === "object" && parsedObj !== null) {
|
|
281
|
+
jsonObjects.push(parsedObj);
|
|
282
|
+
i = j - 1;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
} catch {
|
|
286
|
+
if (openBraces === closeBraces) break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return jsonObjects;
|
|
291
|
+
}
|
|
292
|
+
function extractFirstJsonObject(str) {
|
|
293
|
+
const jsonObjects = extractJsonObjects(str);
|
|
294
|
+
require_invariant.invariant(jsonObjects.length >= 1, `Expected a JSON object, but got ${JSON.stringify(str)}`);
|
|
295
|
+
return jsonObjects[0];
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Reorders the keys of an object based on a specified order, preserving any unspecified keys.
|
|
299
|
+
* Symbol keys are preserved and added at the end.
|
|
300
|
+
*
|
|
301
|
+
* @param obj - The object whose keys need to be reordered.
|
|
302
|
+
* @param order - An array specifying the desired order of keys.
|
|
303
|
+
* @returns A new object with keys reordered according to the specified order.
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* const obj = { c: 3, a: 1, b: 2 };
|
|
307
|
+
* const orderedObj = orderKeys(obj, ['a', 'b']);
|
|
308
|
+
* // Result: { a: 1, b: 2, c: 3 }
|
|
309
|
+
*/
|
|
310
|
+
function orderKeys(obj, order) {
|
|
311
|
+
const result = {};
|
|
312
|
+
for (const key of order) if (key in obj && obj[key] !== void 0) result[key] = obj[key];
|
|
313
|
+
for (const key in obj) if (!(key in result) && obj[key] !== void 0) result[key] = obj[key];
|
|
314
|
+
const symbolKeys = Object.getOwnPropertySymbols(obj);
|
|
315
|
+
for (const sym of symbolKeys) if (obj[sym] !== void 0) result[sym] = obj[sym];
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Creates a summary of an EvaluateResult for logging purposes, avoiding RangeError
|
|
320
|
+
* when stringifying large evaluation results.
|
|
321
|
+
*
|
|
322
|
+
* Extracts key information while truncating potentially large fields like response
|
|
323
|
+
* outputs and metadata values.
|
|
324
|
+
*
|
|
325
|
+
* @param result - The evaluation result to summarize
|
|
326
|
+
* @param maxOutputLength - Maximum length for response output before truncation. Default: 500
|
|
327
|
+
* @param includeMetadataKeys - Whether to include metadata keys in the summary. Default: true
|
|
328
|
+
* @returns A summarized version safe for JSON stringification
|
|
329
|
+
* @throws {TypeError} If result is null or undefined
|
|
330
|
+
*/
|
|
331
|
+
function summarizeEvaluateResultForLogging(result, maxOutputLength = 500, includeMetadataKeys = true) {
|
|
332
|
+
if (!result) throw new TypeError("EvaluateResult cannot be null or undefined");
|
|
333
|
+
const summary = {
|
|
334
|
+
id: result.id,
|
|
335
|
+
testIdx: result.testIdx,
|
|
336
|
+
promptIdx: result.promptIdx,
|
|
337
|
+
success: result.success,
|
|
338
|
+
score: result.score,
|
|
339
|
+
error: result.error,
|
|
340
|
+
failureReason: result.failureReason
|
|
341
|
+
};
|
|
342
|
+
if (result.provider) summary.provider = {
|
|
343
|
+
id: result.provider.id || "",
|
|
344
|
+
label: result.provider.label
|
|
345
|
+
};
|
|
346
|
+
if (result.response) {
|
|
347
|
+
summary.response = {
|
|
348
|
+
error: result.response.error,
|
|
349
|
+
cached: result.response.cached,
|
|
350
|
+
cost: result.response.cost,
|
|
351
|
+
tokenUsage: result.response.tokenUsage
|
|
352
|
+
};
|
|
353
|
+
if (result.response.output != null) {
|
|
354
|
+
const output = String(result.response.output);
|
|
355
|
+
summary.response.output = output.length > maxOutputLength ? output.substring(0, maxOutputLength) + "...[truncated]" : output;
|
|
356
|
+
}
|
|
357
|
+
if (result.response.metadata && includeMetadataKeys) summary.response.metadata = {
|
|
358
|
+
keys: Object.keys(result.response.metadata),
|
|
359
|
+
keyCount: Object.keys(result.response.metadata).length
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (result.testCase) summary.testCase = {
|
|
363
|
+
description: result.testCase.description,
|
|
364
|
+
vars: result.testCase.vars ? Object.keys(result.testCase.vars) : void 0
|
|
365
|
+
};
|
|
366
|
+
return summary;
|
|
367
|
+
}
|
|
368
|
+
//#endregion
|
|
369
|
+
//#region src/util/sanitizer.ts
|
|
370
|
+
/**
|
|
371
|
+
* Generic utility functions for sanitizing objects to prevent logging of secrets and credentials
|
|
372
|
+
* Uses a custom recursive approach for reliable deep object sanitization.
|
|
373
|
+
*/
|
|
374
|
+
const MAX_DEPTH = 4;
|
|
375
|
+
const DUMMY_BASE = "http://placeholder";
|
|
376
|
+
const REDACTED = "[REDACTED]";
|
|
377
|
+
/**
|
|
378
|
+
* Set of field names that should be redacted (case-insensitive, with hyphens/underscores normalized)
|
|
379
|
+
* Note: Keys are stored in their normalized form (lowercase, no hyphens/underscores)
|
|
380
|
+
*/
|
|
381
|
+
const SECRET_FIELD_NAMES = new Set([
|
|
382
|
+
"password",
|
|
383
|
+
"passwd",
|
|
384
|
+
"pwd",
|
|
385
|
+
"secret",
|
|
386
|
+
"secrets",
|
|
387
|
+
"secretkey",
|
|
388
|
+
"credentials",
|
|
389
|
+
"apikey",
|
|
390
|
+
"apisecret",
|
|
391
|
+
"token",
|
|
392
|
+
"accesstoken",
|
|
393
|
+
"refreshtoken",
|
|
394
|
+
"idtoken",
|
|
395
|
+
"bearertoken",
|
|
396
|
+
"authtoken",
|
|
397
|
+
"clientsecret",
|
|
398
|
+
"webhooksecret",
|
|
399
|
+
"anthropicapikey",
|
|
400
|
+
"awsbearertokenbedrock",
|
|
401
|
+
"authorization",
|
|
402
|
+
"auth",
|
|
403
|
+
"bearer",
|
|
404
|
+
"apikeyenvar",
|
|
405
|
+
"xapikey",
|
|
406
|
+
"xauthtoken",
|
|
407
|
+
"xaccesstoken",
|
|
408
|
+
"xauth",
|
|
409
|
+
"xsecret",
|
|
410
|
+
"xcsrftoken",
|
|
411
|
+
"xsessiondata",
|
|
412
|
+
"csrftoken",
|
|
413
|
+
"sessionid",
|
|
414
|
+
"session",
|
|
415
|
+
"cookie",
|
|
416
|
+
"setcookie",
|
|
417
|
+
"certificatepassword",
|
|
418
|
+
"keystorepassword",
|
|
419
|
+
"pfxpassword",
|
|
420
|
+
"privatekey",
|
|
421
|
+
"certkey",
|
|
422
|
+
"encryptionkey",
|
|
423
|
+
"signingkey",
|
|
424
|
+
"signature",
|
|
425
|
+
"sig",
|
|
426
|
+
"passphrase",
|
|
427
|
+
"certificatecontent",
|
|
428
|
+
"keystorecontent",
|
|
429
|
+
"pfx",
|
|
430
|
+
"pfxcontent",
|
|
431
|
+
"keycontent",
|
|
432
|
+
"certcontent"
|
|
433
|
+
]);
|
|
434
|
+
/**
|
|
435
|
+
* Normalize field names for comparison (lowercase, no hyphens/underscores)
|
|
436
|
+
*/
|
|
437
|
+
function normalizeFieldName(fieldName) {
|
|
438
|
+
return fieldName.toLowerCase().replace(/[-_]/g, "");
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Check if a field name should be redacted
|
|
442
|
+
*/
|
|
443
|
+
function isSecretField(fieldName) {
|
|
444
|
+
return SECRET_FIELD_NAMES.has(normalizeFieldName(fieldName));
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Check if a value looks like a secret based on common patterns.
|
|
448
|
+
* Detects API keys, tokens, and other credential patterns.
|
|
449
|
+
*/
|
|
450
|
+
function looksLikeSecret(value) {
|
|
451
|
+
if (typeof value !== "string") return false;
|
|
452
|
+
if (/^sk-[a-zA-Z0-9-_]{20,}/.test(value)) return true;
|
|
453
|
+
if (/^sk-proj-[a-zA-Z0-9-_]{20,}/.test(value)) return true;
|
|
454
|
+
if (/^sk-ant-[a-zA-Z0-9-_]{20,}/.test(value)) return true;
|
|
455
|
+
if (/^key-[a-zA-Z0-9]{20,}/.test(value)) return true;
|
|
456
|
+
if (/^Bearer\s+.{20,}/i.test(value)) return true;
|
|
457
|
+
if (/^Basic\s+.{20,}/i.test(value)) return true;
|
|
458
|
+
if (/^[a-zA-Z0-9+/=_-]{64,}$/.test(value)) return true;
|
|
459
|
+
if (/^AKIA[A-Z0-9]{16}/.test(value)) return true;
|
|
460
|
+
if (/^AIza[a-zA-Z0-9_-]{35}/.test(value)) return true;
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Detect class instances (objects with custom prototypes and methods)
|
|
465
|
+
*/
|
|
466
|
+
function isClassInstance(obj) {
|
|
467
|
+
const proto = Object.getPrototypeOf(obj);
|
|
468
|
+
if (!proto || proto === Object.prototype) return false;
|
|
469
|
+
return Object.getOwnPropertyNames(proto).some((prop) => prop !== "constructor" && typeof proto[prop] === "function");
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Parse and sanitize JSON strings, also check if the string looks like a secret
|
|
473
|
+
*/
|
|
474
|
+
function sanitizeJsonString(str, depth, maxDepth) {
|
|
475
|
+
try {
|
|
476
|
+
const parsed = JSON.parse(str);
|
|
477
|
+
if (parsed && typeof parsed === "object") {
|
|
478
|
+
const sanitized = recursiveSanitize(parsed, depth, maxDepth);
|
|
479
|
+
return JSON.stringify(sanitized);
|
|
480
|
+
}
|
|
481
|
+
} catch {
|
|
482
|
+
if (looksLikeSecret(str)) return REDACTED;
|
|
483
|
+
}
|
|
484
|
+
return str;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Sanitize plain object fields
|
|
488
|
+
*/
|
|
489
|
+
function sanitizePlainObject(obj, depth, maxDepth) {
|
|
490
|
+
const sanitized = {};
|
|
491
|
+
for (const [key, value] of Object.entries(obj)) if (key === "url" && typeof value === "string") sanitized[key] = sanitizeUrl(value);
|
|
492
|
+
else if (isSecretField(key)) sanitized[key] = REDACTED;
|
|
493
|
+
else if (typeof value === "string" && looksLikeSecret(value)) sanitized[key] = REDACTED;
|
|
494
|
+
else sanitized[key] = recursiveSanitize(value, depth + 1, maxDepth);
|
|
495
|
+
return sanitized;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Recursively sanitize an object, redacting secret fields at any depth
|
|
499
|
+
*/
|
|
500
|
+
function recursiveSanitize(obj, depth = 0, maxDepth = MAX_DEPTH) {
|
|
501
|
+
if (typeof obj === "function") return `[Function] ${obj.name}`;
|
|
502
|
+
if (typeof obj === "string") return sanitizeJsonString(obj, depth, maxDepth);
|
|
503
|
+
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
504
|
+
if (depth > maxDepth) return "[...]";
|
|
505
|
+
if (Array.isArray(obj)) return obj.map((item) => recursiveSanitize(item, depth + 1, maxDepth));
|
|
506
|
+
if (isClassInstance(obj)) return `[${obj.constructor?.name || "Object"} Instance]`;
|
|
507
|
+
return sanitizePlainObject(obj, depth, maxDepth);
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Generic function to sanitize any object by removing or redacting sensitive information
|
|
511
|
+
* @param obj - The object to sanitize
|
|
512
|
+
* @param options - Optional configuration
|
|
513
|
+
* @returns A sanitized copy of the object with secrets redacted
|
|
514
|
+
*/
|
|
515
|
+
function sanitizeObject(obj, options = {}) {
|
|
516
|
+
const { context = "object", throwOnError = false, maxDepth = MAX_DEPTH } = options;
|
|
517
|
+
try {
|
|
518
|
+
if (obj === null || obj === void 0) return obj;
|
|
519
|
+
if (typeof obj === "string") return sanitizeJsonString(obj, 0, maxDepth);
|
|
520
|
+
if (typeof obj !== "object") return obj;
|
|
521
|
+
return recursiveSanitize(JSON.parse((0, fast_safe_stringify.default)(obj, (_key, val) => {
|
|
522
|
+
if (val instanceof Error) return {
|
|
523
|
+
name: val.name,
|
|
524
|
+
message: val.message
|
|
525
|
+
};
|
|
526
|
+
return val;
|
|
527
|
+
}, void 0, {
|
|
528
|
+
depthLimit: Number.MAX_SAFE_INTEGER,
|
|
529
|
+
edgesLimit: Number.MAX_SAFE_INTEGER
|
|
530
|
+
})), 0, maxDepth);
|
|
531
|
+
} catch (error) {
|
|
532
|
+
if (throwOnError) throw error;
|
|
533
|
+
console.error(`Error sanitizing ${context}:`, error);
|
|
534
|
+
return obj;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function sanitizeUrl(url) {
|
|
538
|
+
try {
|
|
539
|
+
if (typeof url !== "string" || !url.trim()) return url;
|
|
540
|
+
if (url.includes("{{") && url.includes("}}")) return url;
|
|
541
|
+
const isPathOnly = url.startsWith("/") && !url.startsWith("//");
|
|
542
|
+
const parsedUrl = isPathOnly ? new URL(url, DUMMY_BASE) : new URL(url);
|
|
543
|
+
const sanitizedUrl = new URL(parsedUrl.href);
|
|
544
|
+
if (sanitizedUrl.username || sanitizedUrl.password) {
|
|
545
|
+
sanitizedUrl.username = "***";
|
|
546
|
+
sanitizedUrl.password = "***";
|
|
547
|
+
}
|
|
548
|
+
const sensitiveParams = /(api[_-]?key|token|password|secret|signature|sig|access[_-]?token|refresh[_-]?token|id[_-]?token|client[_-]?secret|authorization)/i;
|
|
549
|
+
try {
|
|
550
|
+
for (const key of Array.from(sanitizedUrl.searchParams.keys())) if (sensitiveParams.test(key)) sanitizedUrl.searchParams.set(key, "[REDACTED]");
|
|
551
|
+
} catch (paramError) {
|
|
552
|
+
console.warn(`Failed to sanitize URL parameters ${url}: ${paramError}`);
|
|
553
|
+
}
|
|
554
|
+
if (isPathOnly) return sanitizedUrl.pathname + sanitizedUrl.search + sanitizedUrl.hash;
|
|
555
|
+
return sanitizedUrl.toString();
|
|
556
|
+
} catch (error) {
|
|
557
|
+
console.warn(`Failed to sanitize URL ${url}: ${error}`);
|
|
558
|
+
return url;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/logger.ts
|
|
563
|
+
let globalLogCallback = null;
|
|
564
|
+
function setLogCallback(callback) {
|
|
565
|
+
globalLogCallback = callback;
|
|
566
|
+
}
|
|
567
|
+
const LOG_LEVELS = {
|
|
568
|
+
error: 0,
|
|
569
|
+
warn: 1,
|
|
570
|
+
info: 2,
|
|
571
|
+
debug: 3
|
|
572
|
+
};
|
|
573
|
+
let sourceMapSupportInitialized = false;
|
|
574
|
+
let sourceMapSupportInitializationPromise = null;
|
|
575
|
+
async function initializeSourceMapSupport() {
|
|
576
|
+
if (sourceMapSupportInitialized) return;
|
|
577
|
+
sourceMapSupportInitializationPromise ??= (async () => {
|
|
578
|
+
try {
|
|
579
|
+
(await import("source-map-support")).install();
|
|
580
|
+
sourceMapSupportInitialized = true;
|
|
581
|
+
} catch {} finally {
|
|
582
|
+
sourceMapSupportInitializationPromise = null;
|
|
583
|
+
}
|
|
584
|
+
})();
|
|
585
|
+
await sourceMapSupportInitializationPromise;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Gets the caller location (filename and line number)
|
|
589
|
+
* @returns String with file location information
|
|
590
|
+
*/
|
|
591
|
+
function getCallerLocation() {
|
|
592
|
+
try {
|
|
593
|
+
const callerLine = ((/* @__PURE__ */ new Error("stack trace capture")).stack?.split("\n") || [])[3];
|
|
594
|
+
if (callerLine) {
|
|
595
|
+
const matchParens = callerLine.match(/at (?:.*) \((.+):(\d+):(\d+)\)/);
|
|
596
|
+
const matchNormal = callerLine.match(/at (.+):(\d+):(\d+)/);
|
|
597
|
+
const match = matchParens || matchNormal;
|
|
598
|
+
if (match) {
|
|
599
|
+
const filePath = match[1];
|
|
600
|
+
const line = match[2];
|
|
601
|
+
return `[${path.default.basename(filePath)}:${line}]`;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
} catch {}
|
|
605
|
+
return "";
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Extracts the actual message string from potentially nested info objects
|
|
609
|
+
*/
|
|
610
|
+
function extractMessage(info) {
|
|
611
|
+
if (typeof info.message === "object" && info.message !== null && "message" in info.message) return typeof info.message.message === "string" ? info.message.message : String(info.message.message);
|
|
612
|
+
return typeof info.message === "string" ? info.message : JSON.stringify(info.message);
|
|
613
|
+
}
|
|
614
|
+
const consoleFormatter = winston.default.format.printf((info) => {
|
|
615
|
+
const message = extractMessage(info);
|
|
616
|
+
if (globalLogCallback) globalLogCallback(message);
|
|
617
|
+
const location = info.location ? `${info.location} ` : "";
|
|
618
|
+
if (info.level === "error") return `${location}${message}`;
|
|
619
|
+
else if (info.level === "warn") return `${location}${message}`;
|
|
620
|
+
else if (info.level === "info") return `${location}${message}`;
|
|
621
|
+
else if (info.level === "debug") return `${location}${message}`;
|
|
622
|
+
throw new Error(`Invalid log level: ${info.level}`);
|
|
623
|
+
});
|
|
624
|
+
winston.default.format.printf((info) => {
|
|
625
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
626
|
+
const location = info.location ? ` ${info.location}` : "";
|
|
627
|
+
const message = extractMessage(info);
|
|
628
|
+
return `${timestamp} [${info.level.toUpperCase()}]${location}: ${message}`;
|
|
629
|
+
});
|
|
630
|
+
const winstonLogger = winston.default.createLogger({
|
|
631
|
+
levels: LOG_LEVELS,
|
|
632
|
+
transports: [new winston.default.transports.Console({
|
|
633
|
+
level: getEnvString("LOG_LEVEL", "info"),
|
|
634
|
+
format: winston.default.format.combine(winston.default.format.simple(), consoleFormatter)
|
|
635
|
+
})]
|
|
636
|
+
});
|
|
637
|
+
function getLogLevel() {
|
|
638
|
+
return winstonLogger.transports[0].level;
|
|
639
|
+
}
|
|
640
|
+
function setLogLevel(level) {
|
|
641
|
+
if (level in LOG_LEVELS) {
|
|
642
|
+
winstonLogger.transports[0].level = level;
|
|
643
|
+
if (level === "debug") initializeSourceMapSupport();
|
|
644
|
+
} else throw new Error(`Invalid log level: ${level}`);
|
|
645
|
+
}
|
|
646
|
+
function isDebugEnabled() {
|
|
647
|
+
return getLogLevel() === "debug";
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Creates a logger method for the specified log level.
|
|
651
|
+
* Accepts either a string message or a structured object with a message field.
|
|
652
|
+
*/
|
|
653
|
+
function createLogMethod(level) {
|
|
654
|
+
return (input) => {
|
|
655
|
+
const location = level === "debug" ? getCallerLocation() : isDebugEnabled() ? getCallerLocation() : "";
|
|
656
|
+
if (level === "debug") initializeSourceMapSupport();
|
|
657
|
+
const message = typeof input === "string" ? input : input.message;
|
|
658
|
+
return winstonLogger[level]({
|
|
659
|
+
message,
|
|
660
|
+
location
|
|
661
|
+
});
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
let internalLogger = Object.assign({}, winstonLogger, {
|
|
665
|
+
error: createLogMethod("error"),
|
|
666
|
+
warn: createLogMethod("warn"),
|
|
667
|
+
info: createLogMethod("info"),
|
|
668
|
+
debug: createLogMethod("debug"),
|
|
669
|
+
add: winstonLogger.add.bind(winstonLogger),
|
|
670
|
+
remove: winstonLogger.remove.bind(winstonLogger),
|
|
671
|
+
transports: winstonLogger.transports
|
|
672
|
+
});
|
|
673
|
+
/**
|
|
674
|
+
* Sanitizes context object for logging using generic sanitization
|
|
675
|
+
*/
|
|
676
|
+
function sanitizeContext(context) {
|
|
677
|
+
const contextWithSanitizedUrls = {};
|
|
678
|
+
for (const [key, value] of Object.entries(context)) if (key === "url" && typeof value === "string") contextWithSanitizedUrls[key] = sanitizeUrl(value);
|
|
679
|
+
else contextWithSanitizedUrls[key] = value;
|
|
680
|
+
return sanitizeObject(contextWithSanitizedUrls, { context: "log context" });
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
* Creates a log method that accepts an optional context parameter.
|
|
684
|
+
* If context is provided, it will be sanitized and formatted.
|
|
685
|
+
*
|
|
686
|
+
* When structured logging is enabled (via setStructuredLogging(true)):
|
|
687
|
+
* - Passes { message, ...context } object to the logger
|
|
688
|
+
* - Ideal for cloud logging integrations that expect structured data
|
|
689
|
+
*
|
|
690
|
+
* When structured logging is disabled (default):
|
|
691
|
+
* - Formats context as JSON string appended to message
|
|
692
|
+
* - Suitable for CLI/console output
|
|
693
|
+
*/
|
|
694
|
+
function createLogMethodWithContext(level) {
|
|
695
|
+
return (message, context) => {
|
|
696
|
+
if (!context) {
|
|
697
|
+
internalLogger[level](message);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
const sanitized = sanitizeContext(context);
|
|
701
|
+
{
|
|
702
|
+
const contextStr = safeJsonStringify(sanitized, true);
|
|
703
|
+
internalLogger[level](`${message}\n${contextStr}`);
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
const logger = {
|
|
708
|
+
error: createLogMethodWithContext("error"),
|
|
709
|
+
warn: createLogMethodWithContext("warn"),
|
|
710
|
+
info: createLogMethodWithContext("info"),
|
|
711
|
+
debug: createLogMethodWithContext("debug"),
|
|
712
|
+
add: (transport) => internalLogger.add ? internalLogger.add(transport) : void 0,
|
|
713
|
+
remove: (transport) => internalLogger.remove ? internalLogger.remove(transport) : void 0,
|
|
714
|
+
get transports() {
|
|
715
|
+
return internalLogger.transports || [];
|
|
716
|
+
},
|
|
717
|
+
get level() {
|
|
718
|
+
return internalLogger.transports?.[0]?.level || "info";
|
|
719
|
+
},
|
|
720
|
+
set level(newLevel) {
|
|
721
|
+
if (internalLogger.transports?.[0]) internalLogger.transports[0].level = newLevel;
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
/**
|
|
725
|
+
* Logs request/response details in a formatted way
|
|
726
|
+
* @param url - Request URL
|
|
727
|
+
* @param requestBody - Request body object
|
|
728
|
+
* @param response - Response object (optional)
|
|
729
|
+
* @param error - Whether to log as error (true) or debug (false)
|
|
730
|
+
*/
|
|
731
|
+
async function logRequestResponse(options) {
|
|
732
|
+
const { url, requestBody, requestMethod, response, error } = options;
|
|
733
|
+
const logMethod = error ? logger.error : logger.debug;
|
|
734
|
+
let responseText = "";
|
|
735
|
+
if (response) try {
|
|
736
|
+
responseText = await response.clone().text();
|
|
737
|
+
} catch {
|
|
738
|
+
responseText = "Unable to read response";
|
|
739
|
+
}
|
|
740
|
+
logMethod("Api Request", {
|
|
741
|
+
message: "API request",
|
|
742
|
+
url: sanitizeUrl(url),
|
|
743
|
+
method: requestMethod,
|
|
744
|
+
requestBody: sanitizeObject(requestBody, { context: "request body" }),
|
|
745
|
+
...response && {
|
|
746
|
+
status: response.status,
|
|
747
|
+
statusText: response.statusText
|
|
748
|
+
},
|
|
749
|
+
...responseText && { response: responseText }
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
if (getEnvString("LOG_LEVEL", "info") === "debug") initializeSourceMapSupport();
|
|
753
|
+
//#endregion
|
|
754
|
+
Object.defineProperty(exports, "REDACTED", {
|
|
755
|
+
enumerable: true,
|
|
756
|
+
get: function() {
|
|
757
|
+
return REDACTED;
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
Object.defineProperty(exports, "__exportAll", {
|
|
761
|
+
enumerable: true,
|
|
762
|
+
get: function() {
|
|
763
|
+
return __exportAll;
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
Object.defineProperty(exports, "__toESM", {
|
|
767
|
+
enumerable: true,
|
|
768
|
+
get: function() {
|
|
769
|
+
return __toESM;
|
|
770
|
+
}
|
|
771
|
+
});
|
|
772
|
+
Object.defineProperty(exports, "extractFirstJsonObject", {
|
|
773
|
+
enumerable: true,
|
|
774
|
+
get: function() {
|
|
775
|
+
return extractFirstJsonObject;
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
Object.defineProperty(exports, "extractJsonObjects", {
|
|
779
|
+
enumerable: true,
|
|
780
|
+
get: function() {
|
|
781
|
+
return extractJsonObjects;
|
|
782
|
+
}
|
|
783
|
+
});
|
|
784
|
+
Object.defineProperty(exports, "getAjv", {
|
|
785
|
+
enumerable: true,
|
|
786
|
+
get: function() {
|
|
787
|
+
return getAjv;
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
Object.defineProperty(exports, "getConfigDirectoryPath", {
|
|
791
|
+
enumerable: true,
|
|
792
|
+
get: function() {
|
|
793
|
+
return getConfigDirectoryPath;
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
Object.defineProperty(exports, "getEnvBool", {
|
|
797
|
+
enumerable: true,
|
|
798
|
+
get: function() {
|
|
799
|
+
return getEnvBool;
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
Object.defineProperty(exports, "getEnvFloat", {
|
|
803
|
+
enumerable: true,
|
|
804
|
+
get: function() {
|
|
805
|
+
return getEnvFloat;
|
|
806
|
+
}
|
|
807
|
+
});
|
|
808
|
+
Object.defineProperty(exports, "getEnvInt", {
|
|
809
|
+
enumerable: true,
|
|
810
|
+
get: function() {
|
|
811
|
+
return getEnvInt;
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
Object.defineProperty(exports, "getEnvString", {
|
|
815
|
+
enumerable: true,
|
|
816
|
+
get: function() {
|
|
817
|
+
return getEnvString;
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
Object.defineProperty(exports, "getEvalTimeoutMs", {
|
|
821
|
+
enumerable: true,
|
|
822
|
+
get: function() {
|
|
823
|
+
return getEvalTimeoutMs;
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
Object.defineProperty(exports, "getLogLevel", {
|
|
827
|
+
enumerable: true,
|
|
828
|
+
get: function() {
|
|
829
|
+
return getLogLevel;
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
Object.defineProperty(exports, "getMaxEvalTimeMs", {
|
|
833
|
+
enumerable: true,
|
|
834
|
+
get: function() {
|
|
835
|
+
return getMaxEvalTimeMs;
|
|
836
|
+
}
|
|
837
|
+
});
|
|
838
|
+
Object.defineProperty(exports, "isCI", {
|
|
839
|
+
enumerable: true,
|
|
840
|
+
get: function() {
|
|
841
|
+
return isCI;
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
Object.defineProperty(exports, "isValidJson", {
|
|
845
|
+
enumerable: true,
|
|
846
|
+
get: function() {
|
|
847
|
+
return isValidJson;
|
|
848
|
+
}
|
|
849
|
+
});
|
|
850
|
+
Object.defineProperty(exports, "logRequestResponse", {
|
|
851
|
+
enumerable: true,
|
|
852
|
+
get: function() {
|
|
853
|
+
return logRequestResponse;
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
Object.defineProperty(exports, "logger", {
|
|
857
|
+
enumerable: true,
|
|
858
|
+
get: function() {
|
|
859
|
+
return logger;
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
Object.defineProperty(exports, "normalizeFieldName", {
|
|
863
|
+
enumerable: true,
|
|
864
|
+
get: function() {
|
|
865
|
+
return normalizeFieldName;
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
Object.defineProperty(exports, "orderKeys", {
|
|
869
|
+
enumerable: true,
|
|
870
|
+
get: function() {
|
|
871
|
+
return orderKeys;
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
Object.defineProperty(exports, "safeJsonStringify", {
|
|
875
|
+
enumerable: true,
|
|
876
|
+
get: function() {
|
|
877
|
+
return safeJsonStringify;
|
|
878
|
+
}
|
|
879
|
+
});
|
|
880
|
+
Object.defineProperty(exports, "sanitizeObject", {
|
|
881
|
+
enumerable: true,
|
|
882
|
+
get: function() {
|
|
883
|
+
return sanitizeObject;
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
Object.defineProperty(exports, "sanitizeUrl", {
|
|
887
|
+
enumerable: true,
|
|
888
|
+
get: function() {
|
|
889
|
+
return sanitizeUrl;
|
|
890
|
+
}
|
|
891
|
+
});
|
|
892
|
+
Object.defineProperty(exports, "setLogCallback", {
|
|
893
|
+
enumerable: true,
|
|
894
|
+
get: function() {
|
|
895
|
+
return setLogCallback;
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
Object.defineProperty(exports, "setLogLevel", {
|
|
899
|
+
enumerable: true,
|
|
900
|
+
get: function() {
|
|
901
|
+
return setLogLevel;
|
|
902
|
+
}
|
|
903
|
+
});
|
|
904
|
+
Object.defineProperty(exports, "state", {
|
|
905
|
+
enumerable: true,
|
|
906
|
+
get: function() {
|
|
907
|
+
return state;
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
Object.defineProperty(exports, "summarizeEvaluateResultForLogging", {
|
|
911
|
+
enumerable: true,
|
|
912
|
+
get: function() {
|
|
913
|
+
return summarizeEvaluateResultForLogging;
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
//# sourceMappingURL=logger-DyfK9PBt.cjs.map
|