@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,135 @@
|
|
|
1
|
+
const require_logger = require("./logger-DyfK9PBt.cjs");
|
|
2
|
+
let _slack_web_api = require("@slack/web-api");
|
|
3
|
+
//#region src/providers/slack.ts
|
|
4
|
+
var SlackProvider = class {
|
|
5
|
+
client;
|
|
6
|
+
options;
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
const token = options.config?.token || process.env.SLACK_BOT_TOKEN;
|
|
10
|
+
if (!token) throw new Error("Slack provider requires a token. Set SLACK_BOT_TOKEN or provide it in config.");
|
|
11
|
+
if (!options.config?.channel) throw new Error("Slack provider requires a channel ID");
|
|
12
|
+
this.client = new _slack_web_api.WebClient(token);
|
|
13
|
+
}
|
|
14
|
+
id() {
|
|
15
|
+
return this.options.id || "slack";
|
|
16
|
+
}
|
|
17
|
+
async callApi(prompt, _context, _options) {
|
|
18
|
+
const config = this.options.config;
|
|
19
|
+
const channel = config.channel;
|
|
20
|
+
const timeout = config.timeout || 6e4;
|
|
21
|
+
const responseStrategy = config.responseStrategy || "first";
|
|
22
|
+
try {
|
|
23
|
+
const messageText = config.formatMessage ? config.formatMessage(prompt) : prompt;
|
|
24
|
+
const startTime = Date.now();
|
|
25
|
+
const postResult = await this.client.chat.postMessage({
|
|
26
|
+
channel,
|
|
27
|
+
text: messageText,
|
|
28
|
+
thread_ts: config.threadTs,
|
|
29
|
+
mrkdwn: true
|
|
30
|
+
});
|
|
31
|
+
if (!postResult.ok || !postResult.ts) throw new Error("Failed to post message to Slack");
|
|
32
|
+
const messageTs = postResult.ts;
|
|
33
|
+
let responseText;
|
|
34
|
+
const responseMetadata = {
|
|
35
|
+
messageTs,
|
|
36
|
+
channel
|
|
37
|
+
};
|
|
38
|
+
switch (responseStrategy) {
|
|
39
|
+
case "timeout":
|
|
40
|
+
responseText = await this.collectResponsesUntilTimeout(channel, messageTs, timeout);
|
|
41
|
+
break;
|
|
42
|
+
case "user":
|
|
43
|
+
if (!config.waitForUser) throw new Error("waitForUser must be specified when using \"user\" response strategy");
|
|
44
|
+
responseText = await this.waitForUserResponse(channel, messageTs, config.waitForUser, timeout);
|
|
45
|
+
responseMetadata.waitForUser = config.waitForUser;
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
responseText = await this.waitForFirstResponse(channel, messageTs, timeout);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
if (config.includeThread) responseMetadata.threadTs = messageTs;
|
|
52
|
+
responseMetadata.responseTime = Date.now() - startTime;
|
|
53
|
+
return {
|
|
54
|
+
output: responseText,
|
|
55
|
+
metadata: responseMetadata
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
require_logger.logger.error(`Slack provider error: ${error}`);
|
|
59
|
+
if (error?.data?.error) {
|
|
60
|
+
const slackError = error.data.error;
|
|
61
|
+
switch (slackError) {
|
|
62
|
+
case "channel_not_found": return { error: `Channel ${channel} not found. Please check the channel ID.` };
|
|
63
|
+
case "not_in_channel": return { error: `Bot is not in channel ${channel}. Please invite the bot first.` };
|
|
64
|
+
case "missing_scope": return { error: "Bot token is missing required scopes. Please check permissions." };
|
|
65
|
+
case "ratelimited": return { error: "Slack API rate limit exceeded. Please try again later." };
|
|
66
|
+
default: return { error: `Slack API error: ${slackError}` };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { error: error instanceof Error ? error.message : "Unknown error" };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async waitForFirstResponse(channel, afterTs, timeout) {
|
|
73
|
+
const startTime = Date.now();
|
|
74
|
+
while (Date.now() - startTime < timeout) try {
|
|
75
|
+
const result = await this.client.conversations.history({
|
|
76
|
+
channel,
|
|
77
|
+
oldest: afterTs,
|
|
78
|
+
limit: 10
|
|
79
|
+
});
|
|
80
|
+
if (result.messages && result.messages.length > 0) {
|
|
81
|
+
const response = result.messages.filter((msg) => msg.ts !== afterTs && msg.type === "message" && !msg.bot_id).sort((a, b) => parseFloat(a.ts || "0") - parseFloat(b.ts || "0"))[0];
|
|
82
|
+
if (response && response.text) return response.text;
|
|
83
|
+
}
|
|
84
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
85
|
+
} catch (error) {
|
|
86
|
+
require_logger.logger.error(`Error fetching Slack messages: ${error}`);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
throw new Error(`Timeout waiting for Slack response after ${timeout}ms`);
|
|
90
|
+
}
|
|
91
|
+
async waitForUserResponse(channel, afterTs, userId, timeout) {
|
|
92
|
+
const startTime = Date.now();
|
|
93
|
+
while (Date.now() - startTime < timeout) try {
|
|
94
|
+
const result = await this.client.conversations.history({
|
|
95
|
+
channel,
|
|
96
|
+
oldest: afterTs,
|
|
97
|
+
limit: 20
|
|
98
|
+
});
|
|
99
|
+
if (result.messages && result.messages.length > 0) {
|
|
100
|
+
const response = result.messages.filter((msg) => msg.ts !== afterTs && msg.type === "message" && msg.user === userId).sort((a, b) => parseFloat(a.ts || "0") - parseFloat(b.ts || "0"))[0];
|
|
101
|
+
if (response && response.text) return response.text;
|
|
102
|
+
}
|
|
103
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
104
|
+
} catch (error) {
|
|
105
|
+
require_logger.logger.error(`Error fetching Slack messages: ${error}`);
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
throw new Error(`Timeout waiting for response from user ${userId} after ${timeout}ms`);
|
|
109
|
+
}
|
|
110
|
+
async collectResponsesUntilTimeout(channel, afterTs, timeout) {
|
|
111
|
+
const startTime = Date.now();
|
|
112
|
+
const responses = [];
|
|
113
|
+
const seenTimestamps = new Set([afterTs]);
|
|
114
|
+
while (Date.now() - startTime < timeout) try {
|
|
115
|
+
const result = await this.client.conversations.history({
|
|
116
|
+
channel,
|
|
117
|
+
oldest: afterTs,
|
|
118
|
+
limit: 50
|
|
119
|
+
});
|
|
120
|
+
if (result.messages && result.messages.length > 0) result.messages.filter((msg) => !seenTimestamps.has(msg.ts || "") && msg.type === "message" && !msg.bot_id).sort((a, b) => parseFloat(a.ts || "0") - parseFloat(b.ts || "0")).forEach((msg) => {
|
|
121
|
+
if (msg.ts) seenTimestamps.add(msg.ts);
|
|
122
|
+
if (msg.text) responses.push(msg.text);
|
|
123
|
+
});
|
|
124
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
125
|
+
} catch (error) {
|
|
126
|
+
require_logger.logger.error(`Error fetching Slack messages: ${error}`);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
return responses.join("\n\n");
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
//#endregion
|
|
133
|
+
exports.SlackProvider = SlackProvider;
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=slack-DSQ1yXVb.cjs.map
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
const require_logger = require("./logger-DyfK9PBt.cjs");
|
|
2
|
+
const require_tables = require("./tables-3Q2cL7So.cjs");
|
|
3
|
+
let drizzle_orm = require("drizzle-orm");
|
|
4
|
+
//#region src/tracing/store.ts
|
|
5
|
+
const SENSITIVE_ATTRIBUTE_KEYS = [
|
|
6
|
+
"authorization",
|
|
7
|
+
"cookie",
|
|
8
|
+
"set-cookie",
|
|
9
|
+
"token",
|
|
10
|
+
"api_key",
|
|
11
|
+
"apikey",
|
|
12
|
+
"secret",
|
|
13
|
+
"password",
|
|
14
|
+
"passphrase"
|
|
15
|
+
];
|
|
16
|
+
function sanitizeAttributes(attributes) {
|
|
17
|
+
if (!attributes) return {};
|
|
18
|
+
const sanitizeValue = (value) => {
|
|
19
|
+
if (typeof value === "string") return value.length > 400 ? `${value.slice(0, 400)}…` : value;
|
|
20
|
+
if (Array.isArray(value)) return value.map(sanitizeValue);
|
|
21
|
+
if (value && typeof value === "object") return sanitizeAttributes(value);
|
|
22
|
+
return value;
|
|
23
|
+
};
|
|
24
|
+
const sanitized = {};
|
|
25
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
26
|
+
const lowerKey = key.toLowerCase();
|
|
27
|
+
if (SENSITIVE_ATTRIBUTE_KEYS.some((sensitiveKey) => lowerKey.includes(sensitiveKey))) {
|
|
28
|
+
sanitized[key] = "<redacted>";
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
sanitized[key] = sanitizeValue(value);
|
|
32
|
+
}
|
|
33
|
+
return sanitized;
|
|
34
|
+
}
|
|
35
|
+
function computeDepth(span, spanMap, depthCache) {
|
|
36
|
+
if (depthCache.has(span.spanId)) return depthCache.get(span.spanId);
|
|
37
|
+
if (!span.parentSpanId || !spanMap.has(span.parentSpanId)) {
|
|
38
|
+
depthCache.set(span.spanId, 0);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
const currentDepth = computeDepth(spanMap.get(span.parentSpanId), spanMap, depthCache) + 1;
|
|
42
|
+
depthCache.set(span.spanId, currentDepth);
|
|
43
|
+
return currentDepth;
|
|
44
|
+
}
|
|
45
|
+
function deriveSpanKind(span) {
|
|
46
|
+
const attributes = span.attributes || {};
|
|
47
|
+
const attributeKind = attributes["span.kind"] || attributes["otel.span.kind"] || attributes["spanKind"];
|
|
48
|
+
if (typeof attributeKind === "string") return attributeKind.toLowerCase();
|
|
49
|
+
return "internal";
|
|
50
|
+
}
|
|
51
|
+
var TraceStore = class {
|
|
52
|
+
db = null;
|
|
53
|
+
getDatabase() {
|
|
54
|
+
if (!this.db) {
|
|
55
|
+
require_logger.logger.debug("[TraceStore] Initializing database connection");
|
|
56
|
+
this.db = require_tables.getDb();
|
|
57
|
+
}
|
|
58
|
+
return this.db;
|
|
59
|
+
}
|
|
60
|
+
async createTrace(trace) {
|
|
61
|
+
try {
|
|
62
|
+
require_logger.logger.debug(`[TraceStore] Creating trace ${trace.traceId} for evaluation ${trace.evaluationId}`);
|
|
63
|
+
await this.getDatabase().insert(require_tables.tracesTable).values({
|
|
64
|
+
id: crypto.randomUUID(),
|
|
65
|
+
traceId: trace.traceId,
|
|
66
|
+
evaluationId: trace.evaluationId,
|
|
67
|
+
testCaseId: trace.testCaseId,
|
|
68
|
+
metadata: trace.metadata
|
|
69
|
+
}).onConflictDoNothing({ target: require_tables.tracesTable.traceId });
|
|
70
|
+
require_logger.logger.debug(`[TraceStore] Successfully created or found existing trace ${trace.traceId}`);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
require_logger.logger.error(`[TraceStore] Failed to create trace: ${error}`);
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async addSpans(traceId, spans, options) {
|
|
77
|
+
try {
|
|
78
|
+
require_logger.logger.debug(`[TraceStore] Adding ${spans.length} spans to trace ${traceId}`);
|
|
79
|
+
const db = this.getDatabase();
|
|
80
|
+
if (options?.skipTraceCheck) require_logger.logger.debug(`[TraceStore] Skipping trace existence check for OTLP scenario`);
|
|
81
|
+
else {
|
|
82
|
+
require_logger.logger.debug(`[TraceStore] Verifying trace ${traceId} exists`);
|
|
83
|
+
if ((await db.select().from(require_tables.tracesTable).where((0, drizzle_orm.eq)(require_tables.tracesTable.traceId, traceId)).limit(1)).length === 0) {
|
|
84
|
+
require_logger.logger.warn(`[TraceStore] Trace ${traceId} not found, skipping ${spans.length} spans. This may indicate spans arrived before trace was created.`);
|
|
85
|
+
return {
|
|
86
|
+
stored: false,
|
|
87
|
+
reason: `Trace ${traceId} not found`
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
require_logger.logger.debug(`[TraceStore] Trace ${traceId} found, proceeding with span insertion`);
|
|
91
|
+
}
|
|
92
|
+
const spanRecords = spans.map((span) => {
|
|
93
|
+
require_logger.logger.debug(`[TraceStore] Preparing span ${span.spanId} (${span.name}) for insertion`);
|
|
94
|
+
return {
|
|
95
|
+
id: crypto.randomUUID(),
|
|
96
|
+
traceId,
|
|
97
|
+
spanId: span.spanId,
|
|
98
|
+
parentSpanId: span.parentSpanId,
|
|
99
|
+
name: span.name,
|
|
100
|
+
startTime: span.startTime,
|
|
101
|
+
endTime: span.endTime,
|
|
102
|
+
attributes: span.attributes,
|
|
103
|
+
statusCode: span.statusCode,
|
|
104
|
+
statusMessage: span.statusMessage
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
await db.insert(require_tables.spansTable).values(spanRecords);
|
|
108
|
+
require_logger.logger.debug(`[TraceStore] Successfully added ${spans.length} spans to trace ${traceId}`);
|
|
109
|
+
return { stored: true };
|
|
110
|
+
} catch (error) {
|
|
111
|
+
require_logger.logger.error(`[TraceStore] Failed to add spans: ${error}`);
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async getTracesByEvaluation(evaluationId) {
|
|
116
|
+
try {
|
|
117
|
+
require_logger.logger.debug(`[TraceStore] Fetching traces for evaluation ${evaluationId}`);
|
|
118
|
+
const db = this.getDatabase();
|
|
119
|
+
const traces = await db.select().from(require_tables.tracesTable).where((0, drizzle_orm.eq)(require_tables.tracesTable.evaluationId, evaluationId));
|
|
120
|
+
require_logger.logger.debug(`[TraceStore] Found ${traces.length} traces for evaluation ${evaluationId}`);
|
|
121
|
+
const tracesWithSpans = await Promise.all(traces.map(async (trace) => {
|
|
122
|
+
require_logger.logger.debug(`[TraceStore] Fetching spans for trace ${trace.traceId}`);
|
|
123
|
+
const spans = await db.select().from(require_tables.spansTable).where((0, drizzle_orm.eq)(require_tables.spansTable.traceId, trace.traceId));
|
|
124
|
+
require_logger.logger.debug(`[TraceStore] Found ${spans.length} spans for trace ${trace.traceId}`);
|
|
125
|
+
return {
|
|
126
|
+
...trace,
|
|
127
|
+
spans
|
|
128
|
+
};
|
|
129
|
+
}));
|
|
130
|
+
require_logger.logger.debug(`[TraceStore] Returning ${tracesWithSpans.length} traces with spans`);
|
|
131
|
+
return tracesWithSpans;
|
|
132
|
+
} catch (error) {
|
|
133
|
+
require_logger.logger.error(`[TraceStore] Failed to get traces for evaluation: ${error}`);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async getTrace(traceId) {
|
|
138
|
+
try {
|
|
139
|
+
require_logger.logger.debug(`[TraceStore] Fetching trace ${traceId}`);
|
|
140
|
+
const db = this.getDatabase();
|
|
141
|
+
const traces = await db.select().from(require_tables.tracesTable).where((0, drizzle_orm.eq)(require_tables.tracesTable.traceId, traceId)).limit(1);
|
|
142
|
+
if (traces.length === 0) {
|
|
143
|
+
require_logger.logger.debug(`[TraceStore] Trace ${traceId} not found`);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
const trace = traces[0];
|
|
147
|
+
require_logger.logger.debug(`[TraceStore] Found trace ${traceId}, fetching spans`);
|
|
148
|
+
const spans = await db.select().from(require_tables.spansTable).where((0, drizzle_orm.eq)(require_tables.spansTable.traceId, traceId));
|
|
149
|
+
require_logger.logger.debug(`[TraceStore] Found ${spans.length} spans for trace ${traceId}`);
|
|
150
|
+
return {
|
|
151
|
+
traceId: trace.traceId,
|
|
152
|
+
evaluationId: trace.evaluationId,
|
|
153
|
+
testCaseId: trace.testCaseId,
|
|
154
|
+
metadata: trace.metadata ?? void 0,
|
|
155
|
+
spans: spans.map((span) => ({
|
|
156
|
+
spanId: span.spanId,
|
|
157
|
+
parentSpanId: span.parentSpanId ?? void 0,
|
|
158
|
+
name: span.name,
|
|
159
|
+
startTime: span.startTime,
|
|
160
|
+
endTime: span.endTime ?? void 0,
|
|
161
|
+
attributes: span.attributes ?? void 0,
|
|
162
|
+
statusCode: span.statusCode ?? void 0,
|
|
163
|
+
statusMessage: span.statusMessage ?? void 0
|
|
164
|
+
}))
|
|
165
|
+
};
|
|
166
|
+
} catch (error) {
|
|
167
|
+
require_logger.logger.error(`[TraceStore] Failed to get trace: ${error}`);
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
async deleteOldTraces(retentionDays) {
|
|
172
|
+
try {
|
|
173
|
+
require_logger.logger.debug(`[TraceStore] Deleting traces older than ${retentionDays} days`);
|
|
174
|
+
const db = this.getDatabase();
|
|
175
|
+
const cutoffTime = Date.now() - retentionDays * 24 * 60 * 60 * 1e3;
|
|
176
|
+
await db.delete(require_tables.tracesTable).where((0, drizzle_orm.lt)(require_tables.tracesTable.createdAt, cutoffTime));
|
|
177
|
+
require_logger.logger.debug(`[TraceStore] Successfully deleted traces older than ${retentionDays} days`);
|
|
178
|
+
} catch (error) {
|
|
179
|
+
require_logger.logger.error(`[TraceStore] Failed to delete old traces: ${error}`);
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async getSpans(traceId, options = {}) {
|
|
184
|
+
const { earliestStartTime, maxSpans, maxDepth, includeInternalSpans = true, spanFilter, sanitizeAttributes: shouldSanitize = true } = options;
|
|
185
|
+
try {
|
|
186
|
+
require_logger.logger.debug(`[TraceStore] Fetching spans for trace ${traceId}`);
|
|
187
|
+
const rows = await this.getDatabase().select().from(require_tables.spansTable).where((0, drizzle_orm.eq)(require_tables.spansTable.traceId, traceId)).orderBy((0, drizzle_orm.asc)(require_tables.spansTable.startTime));
|
|
188
|
+
const spanMap = /* @__PURE__ */ new Map();
|
|
189
|
+
const depthCache = /* @__PURE__ */ new Map();
|
|
190
|
+
for (const row of rows) {
|
|
191
|
+
if (earliestStartTime && row.startTime < earliestStartTime) continue;
|
|
192
|
+
const rawAttributes = row.attributes ?? {};
|
|
193
|
+
const spanData = {
|
|
194
|
+
spanId: row.spanId,
|
|
195
|
+
parentSpanId: row.parentSpanId ?? void 0,
|
|
196
|
+
name: row.name,
|
|
197
|
+
startTime: row.startTime,
|
|
198
|
+
endTime: row.endTime ?? void 0,
|
|
199
|
+
attributes: shouldSanitize ? sanitizeAttributes(rawAttributes) : rawAttributes,
|
|
200
|
+
statusCode: row.statusCode ?? void 0,
|
|
201
|
+
statusMessage: row.statusMessage ?? void 0
|
|
202
|
+
};
|
|
203
|
+
const spanKind = deriveSpanKind({
|
|
204
|
+
...spanData,
|
|
205
|
+
attributes: rawAttributes
|
|
206
|
+
});
|
|
207
|
+
if (!includeInternalSpans && spanKind === "internal") continue;
|
|
208
|
+
if (spanFilter && spanFilter.length > 0) {
|
|
209
|
+
if (!spanFilter.some((filterName) => spanData.name.toLowerCase().includes(filterName.toLowerCase()))) continue;
|
|
210
|
+
}
|
|
211
|
+
spanMap.set(spanData.spanId, spanData);
|
|
212
|
+
}
|
|
213
|
+
let spans = Array.from(spanMap.values());
|
|
214
|
+
if (maxDepth !== void 0) spans = spans.filter((span) => computeDepth(span, spanMap, depthCache) < maxDepth);
|
|
215
|
+
if (maxSpans !== void 0) spans = spans.slice(0, maxSpans);
|
|
216
|
+
require_logger.logger.debug(`[TraceStore] Returning ${spans.length} spans for trace ${traceId}`);
|
|
217
|
+
return spans;
|
|
218
|
+
} catch (error) {
|
|
219
|
+
require_logger.logger.error(`[TraceStore] Failed to fetch spans for trace ${traceId}: ${error}`);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
let traceStore = null;
|
|
225
|
+
function getTraceStore() {
|
|
226
|
+
if (!traceStore) {
|
|
227
|
+
require_logger.logger.debug("[TraceStore] Creating new TraceStore instance");
|
|
228
|
+
traceStore = new TraceStore();
|
|
229
|
+
}
|
|
230
|
+
return traceStore;
|
|
231
|
+
}
|
|
232
|
+
//#endregion
|
|
233
|
+
Object.defineProperty(exports, "TraceStore", {
|
|
234
|
+
enumerable: true,
|
|
235
|
+
get: function() {
|
|
236
|
+
return TraceStore;
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
Object.defineProperty(exports, "getTraceStore", {
|
|
240
|
+
enumerable: true,
|
|
241
|
+
get: function() {
|
|
242
|
+
return getTraceStore;
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
//# sourceMappingURL=store-BwDDaBjb.cjs.map
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-DEq-mXcV.js";
|
|
2
|
+
import { r as logger } from "./logger-C40ZGil9.js";
|
|
3
|
+
import { f as tracesTable, p as getDb, u as spansTable } from "./tables-Bi2fjr4W.js";
|
|
4
|
+
import { asc, eq, lt } from "drizzle-orm";
|
|
5
|
+
//#region src/tracing/store.ts
|
|
6
|
+
var store_exports = /* @__PURE__ */ __exportAll({
|
|
7
|
+
TraceStore: () => TraceStore,
|
|
8
|
+
getTraceStore: () => getTraceStore
|
|
9
|
+
});
|
|
10
|
+
const SENSITIVE_ATTRIBUTE_KEYS = [
|
|
11
|
+
"authorization",
|
|
12
|
+
"cookie",
|
|
13
|
+
"set-cookie",
|
|
14
|
+
"token",
|
|
15
|
+
"api_key",
|
|
16
|
+
"apikey",
|
|
17
|
+
"secret",
|
|
18
|
+
"password",
|
|
19
|
+
"passphrase"
|
|
20
|
+
];
|
|
21
|
+
function sanitizeAttributes(attributes) {
|
|
22
|
+
if (!attributes) return {};
|
|
23
|
+
const sanitizeValue = (value) => {
|
|
24
|
+
if (typeof value === "string") return value.length > 400 ? `${value.slice(0, 400)}…` : value;
|
|
25
|
+
if (Array.isArray(value)) return value.map(sanitizeValue);
|
|
26
|
+
if (value && typeof value === "object") return sanitizeAttributes(value);
|
|
27
|
+
return value;
|
|
28
|
+
};
|
|
29
|
+
const sanitized = {};
|
|
30
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
31
|
+
const lowerKey = key.toLowerCase();
|
|
32
|
+
if (SENSITIVE_ATTRIBUTE_KEYS.some((sensitiveKey) => lowerKey.includes(sensitiveKey))) {
|
|
33
|
+
sanitized[key] = "<redacted>";
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
sanitized[key] = sanitizeValue(value);
|
|
37
|
+
}
|
|
38
|
+
return sanitized;
|
|
39
|
+
}
|
|
40
|
+
function computeDepth(span, spanMap, depthCache) {
|
|
41
|
+
if (depthCache.has(span.spanId)) return depthCache.get(span.spanId);
|
|
42
|
+
if (!span.parentSpanId || !spanMap.has(span.parentSpanId)) {
|
|
43
|
+
depthCache.set(span.spanId, 0);
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
const currentDepth = computeDepth(spanMap.get(span.parentSpanId), spanMap, depthCache) + 1;
|
|
47
|
+
depthCache.set(span.spanId, currentDepth);
|
|
48
|
+
return currentDepth;
|
|
49
|
+
}
|
|
50
|
+
function deriveSpanKind(span) {
|
|
51
|
+
const attributes = span.attributes || {};
|
|
52
|
+
const attributeKind = attributes["span.kind"] || attributes["otel.span.kind"] || attributes["spanKind"];
|
|
53
|
+
if (typeof attributeKind === "string") return attributeKind.toLowerCase();
|
|
54
|
+
return "internal";
|
|
55
|
+
}
|
|
56
|
+
var TraceStore = class {
|
|
57
|
+
db = null;
|
|
58
|
+
getDatabase() {
|
|
59
|
+
if (!this.db) {
|
|
60
|
+
logger.debug("[TraceStore] Initializing database connection");
|
|
61
|
+
this.db = getDb();
|
|
62
|
+
}
|
|
63
|
+
return this.db;
|
|
64
|
+
}
|
|
65
|
+
async createTrace(trace) {
|
|
66
|
+
try {
|
|
67
|
+
logger.debug(`[TraceStore] Creating trace ${trace.traceId} for evaluation ${trace.evaluationId}`);
|
|
68
|
+
await this.getDatabase().insert(tracesTable).values({
|
|
69
|
+
id: crypto.randomUUID(),
|
|
70
|
+
traceId: trace.traceId,
|
|
71
|
+
evaluationId: trace.evaluationId,
|
|
72
|
+
testCaseId: trace.testCaseId,
|
|
73
|
+
metadata: trace.metadata
|
|
74
|
+
}).onConflictDoNothing({ target: tracesTable.traceId });
|
|
75
|
+
logger.debug(`[TraceStore] Successfully created or found existing trace ${trace.traceId}`);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
logger.error(`[TraceStore] Failed to create trace: ${error}`);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async addSpans(traceId, spans, options) {
|
|
82
|
+
try {
|
|
83
|
+
logger.debug(`[TraceStore] Adding ${spans.length} spans to trace ${traceId}`);
|
|
84
|
+
const db = this.getDatabase();
|
|
85
|
+
if (options?.skipTraceCheck) logger.debug(`[TraceStore] Skipping trace existence check for OTLP scenario`);
|
|
86
|
+
else {
|
|
87
|
+
logger.debug(`[TraceStore] Verifying trace ${traceId} exists`);
|
|
88
|
+
if ((await db.select().from(tracesTable).where(eq(tracesTable.traceId, traceId)).limit(1)).length === 0) {
|
|
89
|
+
logger.warn(`[TraceStore] Trace ${traceId} not found, skipping ${spans.length} spans. This may indicate spans arrived before trace was created.`);
|
|
90
|
+
return {
|
|
91
|
+
stored: false,
|
|
92
|
+
reason: `Trace ${traceId} not found`
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
logger.debug(`[TraceStore] Trace ${traceId} found, proceeding with span insertion`);
|
|
96
|
+
}
|
|
97
|
+
const spanRecords = spans.map((span) => {
|
|
98
|
+
logger.debug(`[TraceStore] Preparing span ${span.spanId} (${span.name}) for insertion`);
|
|
99
|
+
return {
|
|
100
|
+
id: crypto.randomUUID(),
|
|
101
|
+
traceId,
|
|
102
|
+
spanId: span.spanId,
|
|
103
|
+
parentSpanId: span.parentSpanId,
|
|
104
|
+
name: span.name,
|
|
105
|
+
startTime: span.startTime,
|
|
106
|
+
endTime: span.endTime,
|
|
107
|
+
attributes: span.attributes,
|
|
108
|
+
statusCode: span.statusCode,
|
|
109
|
+
statusMessage: span.statusMessage
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
await db.insert(spansTable).values(spanRecords);
|
|
113
|
+
logger.debug(`[TraceStore] Successfully added ${spans.length} spans to trace ${traceId}`);
|
|
114
|
+
return { stored: true };
|
|
115
|
+
} catch (error) {
|
|
116
|
+
logger.error(`[TraceStore] Failed to add spans: ${error}`);
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async getTracesByEvaluation(evaluationId) {
|
|
121
|
+
try {
|
|
122
|
+
logger.debug(`[TraceStore] Fetching traces for evaluation ${evaluationId}`);
|
|
123
|
+
const db = this.getDatabase();
|
|
124
|
+
const traces = await db.select().from(tracesTable).where(eq(tracesTable.evaluationId, evaluationId));
|
|
125
|
+
logger.debug(`[TraceStore] Found ${traces.length} traces for evaluation ${evaluationId}`);
|
|
126
|
+
const tracesWithSpans = await Promise.all(traces.map(async (trace) => {
|
|
127
|
+
logger.debug(`[TraceStore] Fetching spans for trace ${trace.traceId}`);
|
|
128
|
+
const spans = await db.select().from(spansTable).where(eq(spansTable.traceId, trace.traceId));
|
|
129
|
+
logger.debug(`[TraceStore] Found ${spans.length} spans for trace ${trace.traceId}`);
|
|
130
|
+
return {
|
|
131
|
+
...trace,
|
|
132
|
+
spans
|
|
133
|
+
};
|
|
134
|
+
}));
|
|
135
|
+
logger.debug(`[TraceStore] Returning ${tracesWithSpans.length} traces with spans`);
|
|
136
|
+
return tracesWithSpans;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
logger.error(`[TraceStore] Failed to get traces for evaluation: ${error}`);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async getTrace(traceId) {
|
|
143
|
+
try {
|
|
144
|
+
logger.debug(`[TraceStore] Fetching trace ${traceId}`);
|
|
145
|
+
const db = this.getDatabase();
|
|
146
|
+
const traces = await db.select().from(tracesTable).where(eq(tracesTable.traceId, traceId)).limit(1);
|
|
147
|
+
if (traces.length === 0) {
|
|
148
|
+
logger.debug(`[TraceStore] Trace ${traceId} not found`);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const trace = traces[0];
|
|
152
|
+
logger.debug(`[TraceStore] Found trace ${traceId}, fetching spans`);
|
|
153
|
+
const spans = await db.select().from(spansTable).where(eq(spansTable.traceId, traceId));
|
|
154
|
+
logger.debug(`[TraceStore] Found ${spans.length} spans for trace ${traceId}`);
|
|
155
|
+
return {
|
|
156
|
+
traceId: trace.traceId,
|
|
157
|
+
evaluationId: trace.evaluationId,
|
|
158
|
+
testCaseId: trace.testCaseId,
|
|
159
|
+
metadata: trace.metadata ?? void 0,
|
|
160
|
+
spans: spans.map((span) => ({
|
|
161
|
+
spanId: span.spanId,
|
|
162
|
+
parentSpanId: span.parentSpanId ?? void 0,
|
|
163
|
+
name: span.name,
|
|
164
|
+
startTime: span.startTime,
|
|
165
|
+
endTime: span.endTime ?? void 0,
|
|
166
|
+
attributes: span.attributes ?? void 0,
|
|
167
|
+
statusCode: span.statusCode ?? void 0,
|
|
168
|
+
statusMessage: span.statusMessage ?? void 0
|
|
169
|
+
}))
|
|
170
|
+
};
|
|
171
|
+
} catch (error) {
|
|
172
|
+
logger.error(`[TraceStore] Failed to get trace: ${error}`);
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
async deleteOldTraces(retentionDays) {
|
|
177
|
+
try {
|
|
178
|
+
logger.debug(`[TraceStore] Deleting traces older than ${retentionDays} days`);
|
|
179
|
+
const db = this.getDatabase();
|
|
180
|
+
const cutoffTime = Date.now() - retentionDays * 24 * 60 * 60 * 1e3;
|
|
181
|
+
await db.delete(tracesTable).where(lt(tracesTable.createdAt, cutoffTime));
|
|
182
|
+
logger.debug(`[TraceStore] Successfully deleted traces older than ${retentionDays} days`);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
logger.error(`[TraceStore] Failed to delete old traces: ${error}`);
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async getSpans(traceId, options = {}) {
|
|
189
|
+
const { earliestStartTime, maxSpans, maxDepth, includeInternalSpans = true, spanFilter, sanitizeAttributes: shouldSanitize = true } = options;
|
|
190
|
+
try {
|
|
191
|
+
logger.debug(`[TraceStore] Fetching spans for trace ${traceId}`);
|
|
192
|
+
const rows = await this.getDatabase().select().from(spansTable).where(eq(spansTable.traceId, traceId)).orderBy(asc(spansTable.startTime));
|
|
193
|
+
const spanMap = /* @__PURE__ */ new Map();
|
|
194
|
+
const depthCache = /* @__PURE__ */ new Map();
|
|
195
|
+
for (const row of rows) {
|
|
196
|
+
if (earliestStartTime && row.startTime < earliestStartTime) continue;
|
|
197
|
+
const rawAttributes = row.attributes ?? {};
|
|
198
|
+
const spanData = {
|
|
199
|
+
spanId: row.spanId,
|
|
200
|
+
parentSpanId: row.parentSpanId ?? void 0,
|
|
201
|
+
name: row.name,
|
|
202
|
+
startTime: row.startTime,
|
|
203
|
+
endTime: row.endTime ?? void 0,
|
|
204
|
+
attributes: shouldSanitize ? sanitizeAttributes(rawAttributes) : rawAttributes,
|
|
205
|
+
statusCode: row.statusCode ?? void 0,
|
|
206
|
+
statusMessage: row.statusMessage ?? void 0
|
|
207
|
+
};
|
|
208
|
+
const spanKind = deriveSpanKind({
|
|
209
|
+
...spanData,
|
|
210
|
+
attributes: rawAttributes
|
|
211
|
+
});
|
|
212
|
+
if (!includeInternalSpans && spanKind === "internal") continue;
|
|
213
|
+
if (spanFilter && spanFilter.length > 0) {
|
|
214
|
+
if (!spanFilter.some((filterName) => spanData.name.toLowerCase().includes(filterName.toLowerCase()))) continue;
|
|
215
|
+
}
|
|
216
|
+
spanMap.set(spanData.spanId, spanData);
|
|
217
|
+
}
|
|
218
|
+
let spans = Array.from(spanMap.values());
|
|
219
|
+
if (maxDepth !== void 0) spans = spans.filter((span) => computeDepth(span, spanMap, depthCache) < maxDepth);
|
|
220
|
+
if (maxSpans !== void 0) spans = spans.slice(0, maxSpans);
|
|
221
|
+
logger.debug(`[TraceStore] Returning ${spans.length} spans for trace ${traceId}`);
|
|
222
|
+
return spans;
|
|
223
|
+
} catch (error) {
|
|
224
|
+
logger.error(`[TraceStore] Failed to fetch spans for trace ${traceId}: ${error}`);
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
let traceStore = null;
|
|
230
|
+
function getTraceStore() {
|
|
231
|
+
if (!traceStore) {
|
|
232
|
+
logger.debug("[TraceStore] Creating new TraceStore instance");
|
|
233
|
+
traceStore = new TraceStore();
|
|
234
|
+
}
|
|
235
|
+
return traceStore;
|
|
236
|
+
}
|
|
237
|
+
//#endregion
|
|
238
|
+
export { store_exports as n, getTraceStore as t };
|
|
239
|
+
|
|
240
|
+
//# sourceMappingURL=store-IGpqMIkv.js.map
|