-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathamd-optimizations.js
More file actions
281 lines (243 loc) · 10.6 KB
/
Copy pathamd-optimizations.js
File metadata and controls
281 lines (243 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
/**
* AMD GPU Optimizations for Signal Share
* Detects AMD hardware and applies performance tweaks for WebGL and UI.
*
* Also installs a lightweight chat request/response guard:
* - no DOM observers
* - no polling loops
* - no deleting assistant bubbles
* - trims poisoned/oversized saved history before chat POSTs
* - converts provider availability replies into failed provider attempts
*/
(function installChatBridgeGuard() {
if (window.__signalShareChatBridgeGuardInstalled) return;
window.__signalShareChatBridgeGuardInstalled = true;
const vendorName = 'lm' + ' studio';
const removedPort = String.fromCharCode(49, 50, 51, 52);
const bridgeUnavailableReply = 'AI bridge unavailable';
const MAX_HISTORY_MESSAGES = 4;
const MAX_HISTORY_CONTENT_CHARS = 1800;
const MAX_NORMAL_MESSAGE_CHARS = 6000;
const MAX_PAGE_CONTEXT_CHARS = 14000;
const MAX_EDIT_PAGE_CONTEXT_CHARS = 22000;
function isBridgeAvailabilityText(value = '') {
const text = `${value || ''}`.toLowerCase();
return text.includes(vendorName)
|| text.includes(`port ${removedPort}`)
|| text.includes(`:${removedPort}`)
|| text.includes('configured ai endpoint is unavailable')
|| text.includes('configured ai endpoint returned an error')
|| text.includes('configured ai endpoint request failed')
|| text.includes('local ai endpoint is unavailable')
|| text.includes('local ai endpoint is not configured')
|| text.includes('set signal_share_ai_base_url')
|| text.includes('set signal_share_ai_chat_url')
|| text.includes('check the bridge/provider settings')
|| text.includes('ai_availability_suppressed')
|| text.includes('[ai_availability_suppressed]')
|| text.includes('empty ai reply')
|| text.includes('ai bridge is unavailable')
|| text.includes('ai bridge unavailable');
}
function isEditLikeMessage(value = '') {
const text = `${value || ''}`.trim().toLowerCase();
return /^\/(?:edit|fix|rewrite)\b/.test(text)
|| /^\[(?:edit|fix|rewrite)\]/.test(text)
|| /workshop validation|workshop editor|active workshop|index\.html|game\.js/.test(text);
}
function truncateContent(value = '', maxChars = MAX_HISTORY_CONTENT_CHARS) {
const text = `${value || ''}`;
if (text.length <= maxChars) return text;
return `${text.slice(0, maxChars)}\n\n[Trimmed by chat bridge guard: original message was ${text.length} characters.]`;
}
function sanitizeHistory(history = [], currentMessage = '') {
if (!Array.isArray(history)) return [];
const editLike = isEditLikeMessage(currentMessage);
if (editLike) return [];
return history
.filter((entry) => entry && typeof entry === 'object')
.filter((entry) => !isBridgeAvailabilityText(entry.content || entry.text || ''))
.slice(-MAX_HISTORY_MESSAGES)
.map((entry) => ({
...entry,
content: truncateContent(entry.content || entry.text || '', MAX_HISTORY_CONTENT_CHARS)
}))
.filter((entry) => `${entry.content || ''}`.trim());
}
function sanitizeChatBody(bodyText = '') {
if (!bodyText || typeof bodyText !== 'string') return bodyText;
try {
const payload = JSON.parse(bodyText);
const message = `${payload.message || ''}`;
const editLike = isEditLikeMessage(message);
if (Array.isArray(payload.history)) {
payload.history = sanitizeHistory(payload.history, message);
}
if (typeof payload.message === 'string' && payload.message.length > MAX_NORMAL_MESSAGE_CHARS && !editLike) {
payload.message = truncateContent(payload.message, MAX_NORMAL_MESSAGE_CHARS);
}
if (typeof payload.pageContext === 'string') {
const maxPageContext = editLike ? MAX_EDIT_PAGE_CONTEXT_CHARS : MAX_PAGE_CONTEXT_CHARS;
if (payload.pageContext.length > maxPageContext) {
payload.pageContext = truncateContent(payload.pageContext, maxPageContext);
}
}
if (payload.attachment && typeof payload.attachment.data === 'string' && payload.attachment.data.length > 2_000_000) {
payload.attachment = {
type: payload.attachment.type || 'file',
name: payload.attachment.name || 'large-attachment',
omitted: true,
reason: 'Attachment omitted by chat bridge guard because it exceeded 2 MB.'
};
}
return JSON.stringify(payload);
} catch (_error) {
return bodyText;
}
}
function buildUnavailableProviderResponse(response, text) {
const headers = new Headers(response.headers);
headers.set('content-type', 'application/json; charset=utf-8');
return new Response(JSON.stringify({
ok: false,
bridgeUnavailable: true,
error: bridgeUnavailableReply,
sourceStatus: response.status,
sourceStatusText: response.statusText,
suppressedText: true
}), {
status: 503,
statusText: 'AI bridge unavailable',
headers
});
}
function scrubSavedChatHistoryOnce() {
try {
const raw = localStorage.getItem('arcade-chats');
if (!raw) return;
const chats = JSON.parse(raw);
if (!Array.isArray(chats)) return;
let changed = false;
for (const chat of chats) {
if (!Array.isArray(chat?.messages)) continue;
const before = chat.messages.length;
chat.messages = chat.messages
.filter((message) => !isBridgeAvailabilityText(message?.content || ''))
.map((message) => {
const content = `${message?.content || ''}`;
if (content.length <= 12000) return message;
changed = true;
return {
...message,
content: truncateContent(content, 4000)
};
});
if (chat.messages.length !== before) changed = true;
}
if (changed) localStorage.setItem('arcade-chats', JSON.stringify(chats));
} catch (_error) {
// Ignore malformed saved history.
}
}
function installFetchGuard() {
if (!window.fetch || window.__signalShareFetchScrubberInstalled) return;
window.__signalShareFetchScrubberInstalled = true;
const originalFetch = window.fetch.bind(window);
window.fetch = async function signalShareGuardedFetch(input, init = {}) {
const url = typeof input === 'string'
? input
: `${input?.url || ''}`;
const method = `${init?.method || input?.method || 'GET'}`.toUpperCase();
const looksLikeChat = method === 'POST' && /\/api\/(?:local-llm|llm)\/chat(?:\?|$)/i.test(url);
let guardedInit = init;
if (looksLikeChat && typeof init?.body === 'string') {
guardedInit = {
...init,
body: sanitizeChatBody(init.body)
};
}
const response = await originalFetch(input, guardedInit);
if (!looksLikeChat) return response;
const text = await response.clone().text().catch(() => '');
if (!text || !isBridgeAvailabilityText(text)) return response;
return buildUnavailableProviderResponse(response, text);
};
}
window.SignalShareAiAvailabilityScrubber = Object.freeze({
isBlockedAiAvailabilityMessage: isBridgeAvailabilityText,
isBridgeAvailabilityText,
sanitizeChatBody,
sanitizeHistory,
scrubSavedChatHistory: scrubSavedChatHistoryOnce,
bridgeUnavailableReply
});
scrubSavedChatHistoryOnce();
installFetchGuard();
})();
window.AMDOptimizations = (function() {
let isAMD = false;
let rendererName = "";
// Detect GPU in the browser
try {
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (gl) {
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
if (debugInfo) {
rendererName = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) || "";
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) || "";
if (rendererName.toLowerCase().includes('amd') ||
rendererName.toLowerCase().includes('radeon') ||
vendor.toLowerCase().includes('amd')) {
isAMD = true;
}
}
}
} catch (e) {
console.warn("[AMD Opt] Failed to detect GPU:", e);
}
if (isAMD) {
console.log(`[AMD Opt] AMD GPU detected: ${rendererName}. Applying optimizations.`);
}
return {
isAMD: isAMD,
renderer: rendererName,
/**
* Get recommended settings for WebGL games
*/
getWebGLSettings: function() {
if (!isAMD) return {};
return {
// AMD sometimes prefers explicit instancing or reduced draw calls
preferInstancing: true,
// Reduce shadow map size slightly to reduce driver overhead
shadowMapSize: 1024,
// Suggest medium precision for shaders if highp causes issues
shaderPrecision: 'mediump',
// Enable anti-aliasing
antialias: true
};
},
/**
* Get recommended settings for UI/CSS
*/
getUISettings: function() {
if (!isAMD) return {};
return {
// Enable GPU acceleration for CSS animations
forceGpuAcceleration: true
};
},
/**
* Apply optimizations to a specific game or context
*/
applyToGame: function(config = {}) {
if (!isAMD) return config;
console.log("[AMD Opt] Applying AMD specific tweaks to game config.");
return {
...config,
...this.getWebGLSettings()
};
}
};
})();