@eeacms/volto-eea-chatbot 2.0.5 → 3.0.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/.github/workflows/betterleaks.yml +133 -0
- package/.gitleaks.toml +89 -0
- package/AGENTS.md +230 -0
- package/CHANGELOG.md +40 -0
- package/README.md +59 -0
- package/RELEASE.md +1 -1
- package/locales/de/LC_MESSAGES/volto.po +44 -0
- package/locales/en/LC_MESSAGES/volto.po +44 -0
- package/locales/it/LC_MESSAGES/volto.po +44 -0
- package/locales/ro/LC_MESSAGES/volto.po +44 -0
- package/locales/volto.pot +46 -2
- package/package.json +2 -1
- package/src/AISearchInput/AISearchInputEdit.jsx +37 -0
- package/src/AISearchInput/AISearchInputView.jsx +130 -0
- package/src/AISearchInput/components/DeepResearchToggle.jsx +35 -0
- package/src/AISearchInput/components/DisclaimerText.jsx +10 -0
- package/src/AISearchInput/components/IntroHeader.jsx +24 -0
- package/src/AISearchInput/components/PromptChips.jsx +22 -0
- package/src/AISearchInput/components/SearchInput.jsx +53 -0
- package/src/AISearchInput/index.js +32 -0
- package/src/AISearchInput/messages.js +38 -0
- package/src/AISearchInput/schema.jsx +215 -0
- package/src/AISearchInput/styles.less +320 -0
- package/src/ChatBlock/ChatBlockView.jsx +4 -0
- package/src/ChatBlock/chat/ChatWindow.tsx +23 -0
- package/src/ChatBlock/packets/MultiToolRenderer.tsx +20 -11
- package/src/ChatBlock/services/messageProcessor.ts +32 -14
- package/src/ChatBlock/style.less +41 -51
- package/src/halloumi/filtering.js +2 -2
- package/src/halloumi/generative.test.js +1 -1
- package/src/halloumi/middleware.js +2 -2
- package/src/halloumi/middleware.test.js +5 -5
- package/src/icons/sparkle.svg +3 -0
- package/src/index.js +2 -0
- package/src/middleware.js +2 -2
- package/src/middleware.test.js +11 -11
|
@@ -33,6 +33,7 @@ export class MessageProcessor {
|
|
|
33
33
|
private _errorContent: string = '';
|
|
34
34
|
private _documents: OnyxDocument[] = [];
|
|
35
35
|
private _citations = new Map<number, string>();
|
|
36
|
+
private _citationsAreFallback: boolean = false;
|
|
36
37
|
private _isComplete: boolean = false;
|
|
37
38
|
private _isFinalMessageComing: boolean = false;
|
|
38
39
|
|
|
@@ -208,20 +209,28 @@ export class MessageProcessor {
|
|
|
208
209
|
|
|
209
210
|
if (newDocuments) {
|
|
210
211
|
this._documents = Array.from(this.documentMap.values());
|
|
212
|
+
}
|
|
211
213
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
214
|
+
// If we have final_documents and no citations yet, create a fallback mapping
|
|
215
|
+
// This ensures the Sources tab shows up in v3 when citation_info is missing
|
|
216
|
+
if (
|
|
217
|
+
packet.obj.type === PacketType.MESSAGE_START &&
|
|
218
|
+
data.final_documents &&
|
|
219
|
+
this._citations.size === 0
|
|
220
|
+
) {
|
|
221
|
+
data.final_documents.forEach((doc: OnyxDocument, index: number) => {
|
|
222
|
+
if (doc.document_id) {
|
|
223
|
+
this._citations.set(index + 1, doc.document_id);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
this._citationsAreFallback = this._citations.size > 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private clearFallbackCitations(): void {
|
|
231
|
+
if (this._citationsAreFallback) {
|
|
232
|
+
this._citations.clear();
|
|
233
|
+
this._citationsAreFallback = false;
|
|
225
234
|
}
|
|
226
235
|
}
|
|
227
236
|
|
|
@@ -233,6 +242,7 @@ export class MessageProcessor {
|
|
|
233
242
|
if (packet.obj.type === PacketType.CITATION_INFO) {
|
|
234
243
|
const citationInfo = packet.obj as any;
|
|
235
244
|
if (citationInfo.citation_number && citationInfo.document_id) {
|
|
245
|
+
this.clearFallbackCitations();
|
|
236
246
|
this._citations.set(
|
|
237
247
|
citationInfo.citation_number,
|
|
238
248
|
citationInfo.document_id,
|
|
@@ -244,7 +254,14 @@ export class MessageProcessor {
|
|
|
244
254
|
return;
|
|
245
255
|
}
|
|
246
256
|
const citationDelta = packet.obj as CitationDelta;
|
|
247
|
-
citationDelta.citations
|
|
257
|
+
const explicitCitations = (citationDelta.citations || []).filter(
|
|
258
|
+
(citation: StreamingCitation) =>
|
|
259
|
+
citation.citation_num != null && Boolean(citation.document_id),
|
|
260
|
+
);
|
|
261
|
+
if (explicitCitations.length > 0) {
|
|
262
|
+
this.clearFallbackCitations();
|
|
263
|
+
}
|
|
264
|
+
explicitCitations.forEach((citation: StreamingCitation) => {
|
|
248
265
|
if (!this._citations.has(citation.citation_num)) {
|
|
249
266
|
this._citations.set(citation.citation_num, citation.document_id);
|
|
250
267
|
}
|
|
@@ -397,6 +414,7 @@ export class MessageProcessor {
|
|
|
397
414
|
this._errorContent = '';
|
|
398
415
|
this._documents = [];
|
|
399
416
|
this._citations.clear();
|
|
417
|
+
this._citationsAreFallback = false;
|
|
400
418
|
this._isComplete = false;
|
|
401
419
|
this._isFinalMessageComing = false;
|
|
402
420
|
}
|
package/src/ChatBlock/style.less
CHANGED
|
@@ -1604,14 +1604,6 @@ mark {
|
|
|
1604
1604
|
}
|
|
1605
1605
|
}
|
|
1606
1606
|
|
|
1607
|
-
.tool-icon-default {
|
|
1608
|
-
display: inline-block;
|
|
1609
|
-
width: 0.5rem;
|
|
1610
|
-
height: 0.5rem;
|
|
1611
|
-
border-radius: 50%;
|
|
1612
|
-
background-color: currentColor;
|
|
1613
|
-
}
|
|
1614
|
-
|
|
1615
1607
|
// Content column
|
|
1616
1608
|
.tool-content {
|
|
1617
1609
|
flex: 1;
|
|
@@ -1625,17 +1617,6 @@ mark {
|
|
|
1625
1617
|
display: flex;
|
|
1626
1618
|
}
|
|
1627
1619
|
|
|
1628
|
-
.tool-status {
|
|
1629
|
-
display: flex;
|
|
1630
|
-
align-items: center;
|
|
1631
|
-
border-radius: 12px;
|
|
1632
|
-
margin-bottom: 0.25rem;
|
|
1633
|
-
color: @teal;
|
|
1634
|
-
font-size: 0.875rem;
|
|
1635
|
-
font-weight: 500;
|
|
1636
|
-
gap: 0.25rem;
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
1620
|
.tool-text {
|
|
1640
1621
|
color: #6b7280;
|
|
1641
1622
|
font-size: 0.75rem;
|
|
@@ -1651,6 +1632,47 @@ mark {
|
|
|
1651
1632
|
.multi-tool-renderer {
|
|
1652
1633
|
margin-bottom: 1em;
|
|
1653
1634
|
|
|
1635
|
+
// Shared tool state styles
|
|
1636
|
+
.tool-icon-dot {
|
|
1637
|
+
display: inline-block;
|
|
1638
|
+
width: 0.5rem;
|
|
1639
|
+
height: 0.5rem;
|
|
1640
|
+
border-radius: 50%;
|
|
1641
|
+
background-color: currentColor;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
.tool-status {
|
|
1645
|
+
display: flex;
|
|
1646
|
+
align-items: center;
|
|
1647
|
+
border-radius: 12px;
|
|
1648
|
+
margin-bottom: 0.25rem;
|
|
1649
|
+
color: @teal;
|
|
1650
|
+
font-size: 0.875rem;
|
|
1651
|
+
font-weight: 500;
|
|
1652
|
+
gap: 0.25rem;
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
.tool-item-expanded.active .tool-icon-circle,
|
|
1656
|
+
.tool-item-collapsed.active .tool-collapsed-icon {
|
|
1657
|
+
color: @teal;
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
.active .tool-status {
|
|
1661
|
+
animation: shimmer 2.5s linear infinite;
|
|
1662
|
+
background: linear-gradient(
|
|
1663
|
+
90deg,
|
|
1664
|
+
@teal 0%,
|
|
1665
|
+
@teal 40%,
|
|
1666
|
+
rgba(0, 179, 174, 0.5) 50%,
|
|
1667
|
+
@teal 60%,
|
|
1668
|
+
@teal 100%
|
|
1669
|
+
);
|
|
1670
|
+
-webkit-background-clip: text;
|
|
1671
|
+
background-clip: text;
|
|
1672
|
+
background-size: 200% 100%;
|
|
1673
|
+
-webkit-text-fill-color: transparent;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1654
1676
|
// Common header styles for both collapsed and summary headers
|
|
1655
1677
|
.tools-collapsed-header,
|
|
1656
1678
|
.tools-summary-header {
|
|
@@ -1766,29 +1788,6 @@ mark {
|
|
|
1766
1788
|
}
|
|
1767
1789
|
}
|
|
1768
1790
|
|
|
1769
|
-
&.active {
|
|
1770
|
-
.tool-collapsed-icon {
|
|
1771
|
-
position: relative;
|
|
1772
|
-
color: @teal;
|
|
1773
|
-
}
|
|
1774
|
-
|
|
1775
|
-
.tool-collapsed-status {
|
|
1776
|
-
animation: shimmer 2.5s linear infinite;
|
|
1777
|
-
background: linear-gradient(
|
|
1778
|
-
90deg,
|
|
1779
|
-
@teal 0%,
|
|
1780
|
-
@teal 40%,
|
|
1781
|
-
rgba(0, 179, 174, 0.5) 50%,
|
|
1782
|
-
@teal 60%,
|
|
1783
|
-
@teal 100%
|
|
1784
|
-
);
|
|
1785
|
-
-webkit-background-clip: text;
|
|
1786
|
-
background-clip: text;
|
|
1787
|
-
background-size: 200% 100%;
|
|
1788
|
-
-webkit-text-fill-color: transparent;
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
|
|
1792
1791
|
.tool-collapsed-icon {
|
|
1793
1792
|
display: flex;
|
|
1794
1793
|
width: 1rem;
|
|
@@ -1798,17 +1797,8 @@ mark {
|
|
|
1798
1797
|
justify-content: center;
|
|
1799
1798
|
}
|
|
1800
1799
|
|
|
1801
|
-
.tool-icon-dot {
|
|
1802
|
-
display: inline-block;
|
|
1803
|
-
width: 6px;
|
|
1804
|
-
height: 6px;
|
|
1805
|
-
border-radius: 50%;
|
|
1806
|
-
background-color: currentColor;
|
|
1807
|
-
}
|
|
1808
|
-
|
|
1809
1800
|
.tool-collapsed-status {
|
|
1810
1801
|
flex: 1;
|
|
1811
|
-
font-weight: 500;
|
|
1812
1802
|
}
|
|
1813
1803
|
}
|
|
1814
1804
|
|
|
@@ -4,13 +4,13 @@ import fetch from 'node-fetch';
|
|
|
4
4
|
const log = debug('halloumi');
|
|
5
5
|
|
|
6
6
|
const LLMGW_URL = process.env.LLMGW_URL;
|
|
7
|
-
const LLMGW_API_KEY = process.env.LLMGW_TOKEN;
|
|
7
|
+
const LLMGW_API_KEY = process.env.LLMGW_TOKEN; //betterleaks:allow
|
|
8
8
|
const MIN_CONTEXT_SENTENCES_FOR_FILTERING = 75;
|
|
9
9
|
|
|
10
10
|
const filterModel = {
|
|
11
11
|
name: 'Inhouse-LLM/gpt-oss-120b',
|
|
12
12
|
apiUrl: `${LLMGW_URL}/chat/completions`,
|
|
13
|
-
apiKey: LLMGW_API_KEY,
|
|
13
|
+
apiKey: LLMGW_API_KEY, //betterleaks:allow
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
export async function callLLM(apiUrl, apiKey, requestBody, { ip } = {}) {
|
|
@@ -196,7 +196,7 @@ describe('halloumiGenerativeAPI via real fetch', () => {
|
|
|
196
196
|
const model = {
|
|
197
197
|
name: 'test-model',
|
|
198
198
|
apiUrl: 'http://test.com/api',
|
|
199
|
-
apiKey: 'test-key',
|
|
199
|
+
apiKey: 'test-key', //betterleaks:allow
|
|
200
200
|
};
|
|
201
201
|
const prompt = {
|
|
202
202
|
prompt: 'test prompt',
|
|
@@ -15,7 +15,7 @@ const ALLOWED_HALLOUMI_PATHS = [
|
|
|
15
15
|
];
|
|
16
16
|
|
|
17
17
|
const LLMGW_URL = process.env.LLMGW_URL;
|
|
18
|
-
const LLMGW_TOKEN = process.env.LLMGW_TOKEN;
|
|
18
|
+
const LLMGW_TOKEN = process.env.LLMGW_TOKEN; //betterleaks:allow
|
|
19
19
|
|
|
20
20
|
const generativeModel = {
|
|
21
21
|
name: 'Inhouse-LLM/HallOumi-8B',
|
|
@@ -57,7 +57,7 @@ export default async function middleware(req, res, next) {
|
|
|
57
57
|
|
|
58
58
|
const model = {
|
|
59
59
|
...(path === '/classify' ? classifyModel : generativeModel),
|
|
60
|
-
apiKey: LLMGW_TOKEN,
|
|
60
|
+
apiKey: LLMGW_TOKEN, //betterleaks:allow
|
|
61
61
|
};
|
|
62
62
|
const body = req.body;
|
|
63
63
|
|
|
@@ -42,7 +42,7 @@ describe('halloumi middleware', () => {
|
|
|
42
42
|
error: 'Invalid configuration: missing LLMGW_TOKEN or LLMGW_URL',
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
-
process.env.LLMGW_TOKEN = origToken;
|
|
45
|
+
process.env.LLMGW_TOKEN = origToken; //betterleaks:allow
|
|
46
46
|
process.env.LLMGW_URL = origUrl;
|
|
47
47
|
});
|
|
48
48
|
|
|
@@ -92,7 +92,7 @@ describe('halloumi middleware - dynamic import', () => {
|
|
|
92
92
|
it('sends response on successful getVerifyClaimResponse', async () => {
|
|
93
93
|
const origToken = process.env.LLMGW_TOKEN;
|
|
94
94
|
const origUrl = process.env.LLMGW_URL;
|
|
95
|
-
process.env.LLMGW_TOKEN = 'test-token';
|
|
95
|
+
process.env.LLMGW_TOKEN = 'test-token'; //betterleaks:allow
|
|
96
96
|
process.env.LLMGW_URL = 'http://test-url';
|
|
97
97
|
|
|
98
98
|
jest.resetModules();
|
|
@@ -116,14 +116,14 @@ describe('halloumi middleware - dynamic import', () => {
|
|
|
116
116
|
expect(res.set).toHaveBeenCalledWith('Content-Type', 'application/json');
|
|
117
117
|
expect(res.send).toHaveBeenCalledWith({ claims: [], segments: {} });
|
|
118
118
|
|
|
119
|
-
process.env.LLMGW_TOKEN = origToken;
|
|
119
|
+
process.env.LLMGW_TOKEN = origToken; //betterleaks:allow
|
|
120
120
|
process.env.LLMGW_URL = origUrl;
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
it('handles errors from getVerifyClaimResponse', async () => {
|
|
124
124
|
const origToken = process.env.LLMGW_TOKEN;
|
|
125
125
|
const origUrl = process.env.LLMGW_URL;
|
|
126
|
-
process.env.LLMGW_TOKEN = 'test-token';
|
|
126
|
+
process.env.LLMGW_TOKEN = 'test-token'; //betterleaks:allow
|
|
127
127
|
process.env.LLMGW_URL = 'http://test-url';
|
|
128
128
|
|
|
129
129
|
jest.resetModules();
|
|
@@ -148,7 +148,7 @@ describe('halloumi middleware - dynamic import', () => {
|
|
|
148
148
|
expect.objectContaining({ error: expect.stringContaining('LLM error') }),
|
|
149
149
|
);
|
|
150
150
|
|
|
151
|
-
process.env.LLMGW_TOKEN = origToken;
|
|
151
|
+
process.env.LLMGW_TOKEN = origToken; //betterleaks:allow
|
|
152
152
|
process.env.LLMGW_URL = origUrl;
|
|
153
153
|
});
|
|
154
154
|
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/>
|
|
3
|
+
</svg>
|
package/src/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import installChatBlock from './ChatBlock';
|
|
2
|
+
import installAISearchInputBlock from './AISearchInput';
|
|
2
3
|
import loadable from '@loadable/component';
|
|
3
4
|
|
|
4
5
|
const applyConfig = (config) => {
|
|
@@ -40,6 +41,7 @@ const applyConfig = (config) => {
|
|
|
40
41
|
};
|
|
41
42
|
|
|
42
43
|
installChatBlock(config);
|
|
44
|
+
installAISearchInputBlock(config);
|
|
43
45
|
|
|
44
46
|
return config;
|
|
45
47
|
};
|
package/src/middleware.js
CHANGED
|
@@ -289,7 +289,7 @@ export default async function middleware(req, res, next) {
|
|
|
289
289
|
|
|
290
290
|
const reqUrl = `${process.env.ONYX_URL || ''}/api${path}`;
|
|
291
291
|
|
|
292
|
-
const api_key = process.env.ONYX_API_KEY;
|
|
292
|
+
const api_key = process.env.ONYX_API_KEY; //betterleaks:allow
|
|
293
293
|
if (!api_key) {
|
|
294
294
|
res.statusCode = 500;
|
|
295
295
|
res.statusMessage = MSG_INVALID_CONFIGURATION;
|
|
@@ -300,7 +300,7 @@ export default async function middleware(req, res, next) {
|
|
|
300
300
|
try {
|
|
301
301
|
await send_onyx_request(req, res, {
|
|
302
302
|
url: reqUrl,
|
|
303
|
-
api_key: api_key,
|
|
303
|
+
api_key: api_key, //betterleaks:allow
|
|
304
304
|
is_related_question,
|
|
305
305
|
});
|
|
306
306
|
} catch (error) {
|
package/src/middleware.test.js
CHANGED
|
@@ -89,7 +89,7 @@ describe('src/middleware', () => {
|
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
it('proxies POST request with api_key and pipes response', async () => {
|
|
92
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
92
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
93
93
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
94
94
|
|
|
95
95
|
await middleware(req, res, next);
|
|
@@ -110,7 +110,7 @@ describe('src/middleware', () => {
|
|
|
110
110
|
});
|
|
111
111
|
|
|
112
112
|
it('handles related question paths', async () => {
|
|
113
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
113
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
114
114
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
115
115
|
req.url = '/_rq/chat/send-message';
|
|
116
116
|
|
|
@@ -124,7 +124,7 @@ describe('src/middleware', () => {
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
it('sends error response when fetch throws', async () => {
|
|
127
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
127
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
128
128
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
129
129
|
|
|
130
130
|
nodeFetch.mockRejectedValueOnce(
|
|
@@ -145,7 +145,7 @@ describe('src/middleware', () => {
|
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
it('handles error without response text', async () => {
|
|
148
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
148
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
149
149
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
150
150
|
|
|
151
151
|
nodeFetch.mockRejectedValueOnce(new Error('No response'));
|
|
@@ -162,7 +162,7 @@ describe('src/middleware', () => {
|
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
it('handles GET requests without body', async () => {
|
|
165
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
165
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
166
166
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
167
167
|
req.method = 'GET';
|
|
168
168
|
req.url = '/_da/persona/1';
|
|
@@ -175,7 +175,7 @@ describe('src/middleware', () => {
|
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
it('uses mock create-chat-session when MOCK_LLM_FILE_PATH is set', async () => {
|
|
178
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
178
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
179
179
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
180
180
|
process.env.MOCK_LLM_FILE_PATH = '/tmp/mock.jsonl';
|
|
181
181
|
req.url = '/_da/chat/create-chat-session';
|
|
@@ -189,7 +189,7 @@ describe('src/middleware', () => {
|
|
|
189
189
|
});
|
|
190
190
|
|
|
191
191
|
it('uses mock send-message with stream when MOCK_LLM_FILE_PATH is set', async () => {
|
|
192
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
192
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
193
193
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
194
194
|
process.env.MOCK_LLM_FILE_PATH = '/tmp/mock.jsonl';
|
|
195
195
|
req.url = '/_da/chat/send-message';
|
|
@@ -223,7 +223,7 @@ describe('src/middleware', () => {
|
|
|
223
223
|
});
|
|
224
224
|
|
|
225
225
|
it('dumps LLM response when DUMP_LLM_FILE_PATH is set', async () => {
|
|
226
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
226
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
227
227
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
228
228
|
process.env.DUMP_LLM_FILE_PATH = '/tmp/dumped_response.jsonl';
|
|
229
229
|
|
|
@@ -236,7 +236,7 @@ describe('src/middleware', () => {
|
|
|
236
236
|
});
|
|
237
237
|
|
|
238
238
|
it('rejects disallowed paths with 404', async () => {
|
|
239
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
239
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
240
240
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
241
241
|
req.url = '/_da/admin/users/delete';
|
|
242
242
|
req.method = 'POST';
|
|
@@ -249,7 +249,7 @@ describe('src/middleware', () => {
|
|
|
249
249
|
});
|
|
250
250
|
|
|
251
251
|
it('rejects allowed path with wrong HTTP method', async () => {
|
|
252
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
252
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
253
253
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
254
254
|
req.url = '/_da/persona';
|
|
255
255
|
req.method = 'DELETE';
|
|
@@ -262,7 +262,7 @@ describe('src/middleware', () => {
|
|
|
262
262
|
});
|
|
263
263
|
|
|
264
264
|
it('rejects path traversal attempts', async () => {
|
|
265
|
-
process.env.ONYX_API_KEY = 'test-key';
|
|
265
|
+
process.env.ONYX_API_KEY = 'test-key'; //betterleaks:allow
|
|
266
266
|
process.env.ONYX_URL = 'http://localhost:3000';
|
|
267
267
|
req.url = '/_da/../../etc/passwd';
|
|
268
268
|
req.method = 'GET';
|