zerochat 7.3.0__py3-none-any.whl

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.
Files changed (130) hide show
  1. zerochat-7.3.0.dist-info/METADATA +70 -0
  2. zerochat-7.3.0.dist-info/RECORD +130 -0
  3. zerochat-7.3.0.dist-info/WHEEL +5 -0
  4. zerochat-7.3.0.dist-info/entry_points.txt +2 -0
  5. zerochat-7.3.0.dist-info/licenses/LICENSE +34 -0
  6. zerochat-7.3.0.dist-info/top_level.txt +2 -0
  7. zerochat.py +2004 -0
  8. zerochat_runtime/__init__.py +1 -0
  9. zerochat_runtime/assets/css/base.css +199 -0
  10. zerochat_runtime/assets/css/components/composer.css +1258 -0
  11. zerochat_runtime/assets/css/components/debug.css +777 -0
  12. zerochat_runtime/assets/css/components/header.css +97 -0
  13. zerochat_runtime/assets/css/components/icons.css +39 -0
  14. zerochat_runtime/assets/css/components/markdown.css +685 -0
  15. zerochat_runtime/assets/css/components/messages.css +473 -0
  16. zerochat_runtime/assets/css/components/modals.css +1319 -0
  17. zerochat_runtime/assets/css/components/sidebar.css +622 -0
  18. zerochat_runtime/assets/css/components/tools.css +1223 -0
  19. zerochat_runtime/assets/css/layout.css +171 -0
  20. zerochat_runtime/assets/css/print.css +120 -0
  21. zerochat_runtime/assets/css/styles.css +18 -0
  22. zerochat_runtime/assets/css/theme-overrides.css +555 -0
  23. zerochat_runtime/assets/css/tokens.css +165 -0
  24. zerochat_runtime/assets/help/architecture.html +247 -0
  25. zerochat_runtime/assets/help/composer.html +134 -0
  26. zerochat_runtime/assets/help/conversations.html +105 -0
  27. zerochat_runtime/assets/help/debug.html +108 -0
  28. zerochat_runtime/assets/help/en/architecture.html +247 -0
  29. zerochat_runtime/assets/help/en/composer.html +134 -0
  30. zerochat_runtime/assets/help/en/conversations.html +104 -0
  31. zerochat_runtime/assets/help/en/debug.html +105 -0
  32. zerochat_runtime/assets/help/en/gemini-free.html +39 -0
  33. zerochat_runtime/assets/help/en/index.html +191 -0
  34. zerochat_runtime/assets/help/en/learning.html +71 -0
  35. zerochat_runtime/assets/help/en/mcp.html +143 -0
  36. zerochat_runtime/assets/help/en/openrouter-free.html +39 -0
  37. zerochat_runtime/assets/help/en/profiles.html +173 -0
  38. zerochat_runtime/assets/help/en/rag.html +130 -0
  39. zerochat_runtime/assets/help/en/reasoning-telemetry.html +108 -0
  40. zerochat_runtime/assets/help/en/tools-agent.html +133 -0
  41. zerochat_runtime/assets/help/en/webllm.html +355 -0
  42. zerochat_runtime/assets/help/gemini-free.html +39 -0
  43. zerochat_runtime/assets/help/help.css +604 -0
  44. zerochat_runtime/assets/help/help.js +51 -0
  45. zerochat_runtime/assets/help/index.html +194 -0
  46. zerochat_runtime/assets/help/learning.html +71 -0
  47. zerochat_runtime/assets/help/mcp.html +143 -0
  48. zerochat_runtime/assets/help/openrouter-free.html +39 -0
  49. zerochat_runtime/assets/help/profiles.html +174 -0
  50. zerochat_runtime/assets/help/rag.html +130 -0
  51. zerochat_runtime/assets/help/reasoning-telemetry.html +111 -0
  52. zerochat_runtime/assets/help/tools-agent.html +133 -0
  53. zerochat_runtime/assets/help/webllm.html +359 -0
  54. zerochat_runtime/assets/js/agent-core.js +1553 -0
  55. zerochat_runtime/assets/js/api.js +844 -0
  56. zerochat_runtime/assets/js/app.js +2558 -0
  57. zerochat_runtime/assets/js/attachments.js +220 -0
  58. zerochat_runtime/assets/js/charts.js +338 -0
  59. zerochat_runtime/assets/js/chat-engine.js +566 -0
  60. zerochat_runtime/assets/js/config-store.js +207 -0
  61. zerochat_runtime/assets/js/context-manager.js +584 -0
  62. zerochat_runtime/assets/js/conversation-service.js +484 -0
  63. zerochat_runtime/assets/js/cookies.js +688 -0
  64. zerochat_runtime/assets/js/data-reset-service.js +136 -0
  65. zerochat_runtime/assets/js/debug.js +508 -0
  66. zerochat_runtime/assets/js/defaults.js +16 -0
  67. zerochat_runtime/assets/js/export.js +179 -0
  68. zerochat_runtime/assets/js/file-parser.js +2088 -0
  69. zerochat_runtime/assets/js/generation-controller.js +417 -0
  70. zerochat_runtime/assets/js/i18n.js +1483 -0
  71. zerochat_runtime/assets/js/icons.js +156 -0
  72. zerochat_runtime/assets/js/ingestionEngine.js +436 -0
  73. zerochat_runtime/assets/js/markdown.js +588 -0
  74. zerochat_runtime/assets/js/mcp.js +1271 -0
  75. zerochat_runtime/assets/js/message-turns.js +62 -0
  76. zerochat_runtime/assets/js/profile-backup.js +118 -0
  77. zerochat_runtime/assets/js/profile-export-bundle.js +481 -0
  78. zerochat_runtime/assets/js/profile-repository.js +213 -0
  79. zerochat_runtime/assets/js/providers-webllm.js +486 -0
  80. zerochat_runtime/assets/js/providers.js +1560 -0
  81. zerochat_runtime/assets/js/rag-index.js +295 -0
  82. zerochat_runtime/assets/js/rag-service.js +530 -0
  83. zerochat_runtime/assets/js/rag-ui.js +997 -0
  84. zerochat_runtime/assets/js/ragStorage.js +676 -0
  85. zerochat_runtime/assets/js/sandbox.js +449 -0
  86. zerochat_runtime/assets/js/state.js +704 -0
  87. zerochat_runtime/assets/js/storage-db.js +144 -0
  88. zerochat_runtime/assets/js/tool-cards.js +330 -0
  89. zerochat_runtime/assets/js/tool-security.js +653 -0
  90. zerochat_runtime/assets/js/tools/README.md +50 -0
  91. zerochat_runtime/assets/js/tools/builtin/agent-checkpoint.tool.js +212 -0
  92. zerochat_runtime/assets/js/tools/builtin/download-pdf.tool.js +111 -0
  93. zerochat_runtime/assets/js/tools/builtin/execute-javascript.tool.js +219 -0
  94. zerochat_runtime/assets/js/tools/builtin/fetch-web-page.tool.js +112 -0
  95. zerochat_runtime/assets/js/tools/builtin/list-documents.tool.js +117 -0
  96. zerochat_runtime/assets/js/tools/builtin/read-knowledge-chunk.tool.js +129 -0
  97. zerochat_runtime/assets/js/tools/builtin/read-knowledge-image.tool.js +95 -0
  98. zerochat_runtime/assets/js/tools/builtin/render-chart.tool.js +90 -0
  99. zerochat_runtime/assets/js/tools/builtin/search-knowledge-base.tool.js +124 -0
  100. zerochat_runtime/assets/js/tools/builtin/search-web.tool.js +125 -0
  101. zerochat_runtime/assets/js/tools/tool-manifest.js +53 -0
  102. zerochat_runtime/assets/js/tools/tool-runtime.js +77 -0
  103. zerochat_runtime/assets/js/ui-composer.js +319 -0
  104. zerochat_runtime/assets/js/ui-conversation.js +655 -0
  105. zerochat_runtime/assets/js/ui-dialogs.js +132 -0
  106. zerochat_runtime/assets/js/ui-generation-status.js +119 -0
  107. zerochat_runtime/assets/js/ui-inspector.js +804 -0
  108. zerochat_runtime/assets/js/ui-mcp.js +604 -0
  109. zerochat_runtime/assets/js/ui-profiles.js +824 -0
  110. zerochat_runtime/assets/js/ui-reasoning.js +146 -0
  111. zerochat_runtime/assets/js/ui-settings.js +825 -0
  112. zerochat_runtime/assets/js/ui-shell.js +215 -0
  113. zerochat_runtime/assets/js/ui-sidebar.js +429 -0
  114. zerochat_runtime/assets/js/ui-telemetry.js +404 -0
  115. zerochat_runtime/assets/js/ui-transfer.js +262 -0
  116. zerochat_runtime/assets/js/utils.js +216 -0
  117. zerochat_runtime/assets/js/vendor/orama.browser.js +11 -0
  118. zerochat_runtime/assets/js/web-browser.js +569 -0
  119. zerochat_runtime/assets/js/web-search.js +519 -0
  120. zerochat_runtime/assets/manifest.webmanifest +20 -0
  121. zerochat_runtime/assets/services/dummy_mcp/dummy_mcp_server.py +47 -0
  122. zerochat_runtime/assets/services/dummy_mcp/service.json +22 -0
  123. zerochat_runtime/assets/services/lsp/installer.json +9 -0
  124. zerochat_runtime/assets/services/lsp/service.json +22 -0
  125. zerochat_runtime/assets/services/memory/installer.json +9 -0
  126. zerochat_runtime/assets/services/memory/service.json +24 -0
  127. zerochat_runtime/assets/services/playwright/installer.json +10 -0
  128. zerochat_runtime/assets/services/playwright/service.json +39 -0
  129. zerochat_runtime/assets/sw.js +164 -0
  130. zerochat_runtime/assets/zerochat.html +671 -0
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Servicio de Borrado Global de Datos y Parada Previa de Operaciones para ZeroChat.
3
+ * Detiene generaciones en curso, confirma con el usuario vía ChatDialogs y limpia
4
+ * IndexedDB, cachés de modelos y almacenamiento web de forma segura.
5
+ */
6
+ (function (root, factory) {
7
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
8
+ module.exports = factory();
9
+ } else {
10
+ root.ChatDataResetService = factory();
11
+ }
12
+ }(typeof self !== 'undefined' ? self : this, function () {
13
+ 'use strict';
14
+
15
+ function resolveDep(globalName, relPath) {
16
+ if (typeof window !== 'undefined' && window[globalName]) return window[globalName];
17
+ if (typeof globalThis !== 'undefined' && globalThis[globalName]) return globalThis[globalName];
18
+ if (typeof require !== 'undefined') {
19
+ try { return require(relPath); } catch (_) {}
20
+ }
21
+ return null;
22
+ }
23
+
24
+ function getI18n() { return resolveDep('ChatI18n', './i18n.js'); }
25
+ function getDialogs() { return resolveDep('ChatDialogs', './ui-dialogs.js'); }
26
+ function getStorage() { return resolveDep('ChatStorage', './cookies.js'); }
27
+ function getProviders() { return resolveDep('ChatProviders', './providers.js'); }
28
+
29
+ function t(key, params) {
30
+ const I18n = getI18n();
31
+ return I18n?.t?.(key, params) || key;
32
+ }
33
+
34
+ async function requestResetConfirmation() {
35
+ const Dialogs = getDialogs();
36
+ if (Dialogs && typeof Dialogs.confirm === 'function') {
37
+ return await Dialogs.confirm(t('confirm_clear_all_data'));
38
+ }
39
+ return true;
40
+ }
41
+
42
+ /**
43
+ * Ejecuta el proceso de borrado global:
44
+ * 1. Detiene cualquier controlador de aborto activo.
45
+ * 2. Pide confirmación al usuario (salvo que skipConfirm sea true).
46
+ * 3. Desactiva proveedores locales activos (WebLLM, etc.).
47
+ * 4. Invoca la limpieza completa de almacenamiento con ChatStorage.clearAllStorage().
48
+ * 5. Notifica el resultado y recarga la página o invoca onComplete.
49
+ *
50
+ * @param {Object} options
51
+ * @param {AbortController|Function} [options.abortController]
52
+ * @param {boolean} [options.skipConfirm=false]
53
+ * @param {boolean} [options.reload=true]
54
+ * @param {Function} [options.onComplete]
55
+ * @returns {Promise<{ confirmed: boolean, success: boolean, error?: string }>}
56
+ */
57
+ async function resetAllData(options = {}) {
58
+ const {
59
+ abortController = null,
60
+ skipConfirm = false,
61
+ reload = true,
62
+ onComplete = null
63
+ } = options;
64
+
65
+ if (!skipConfirm) {
66
+ const confirmed = await requestResetConfirmation();
67
+ if (!confirmed) {
68
+ return { confirmed: false, success: false };
69
+ }
70
+ }
71
+
72
+ // 1. Detener cualquier generación activa
73
+ try {
74
+ if (typeof abortController === 'function') {
75
+ abortController();
76
+ } else if (abortController && typeof abortController.abort === 'function') {
77
+ abortController.abort();
78
+ }
79
+ } catch (abortErr) {
80
+ console.warn('Error al detener operaciones previas al borrado:', abortErr);
81
+ }
82
+
83
+ // 2. Desactivar proveedores locales si están registrados
84
+ try {
85
+ const providers = getProviders();
86
+ await providers?.registry?.get?.('webllm')?.deactivate?.();
87
+ } catch (providerErr) {
88
+ console.warn('Error al desactivar proveedor previo al borrado:', providerErr);
89
+ }
90
+
91
+ // 3. Limpiar almacenamiento
92
+ const Storage = getStorage();
93
+ let success = true;
94
+ let error = null;
95
+
96
+ try {
97
+ if (Storage && typeof Storage.clearAllStorage === 'function') {
98
+ success = await Storage.clearAllStorage();
99
+ if (!success && typeof Storage.getLastClearAllStorageError === 'function') {
100
+ error = Storage.getLastClearAllStorageError();
101
+ }
102
+ } else {
103
+ success = false;
104
+ error = 'ChatStorage.clearAllStorage is unavailable.';
105
+ }
106
+ } catch (storageErr) {
107
+ success = false;
108
+ error = storageErr?.message || String(storageErr);
109
+ console.error('Error durante la limpieza de almacenamiento:', storageErr);
110
+ }
111
+
112
+ // 4. Notificar o alertar
113
+ if (typeof onComplete === 'function') {
114
+ await onComplete({ success, error });
115
+ } else if (!success) {
116
+ const Dialogs = getDialogs();
117
+ if (Dialogs && typeof Dialogs.alert === 'function') {
118
+ const msg = error ? t('clear_all_data_failed_detail', { detail: error }) : t('clear_all_data_failed');
119
+ await Dialogs.alert(msg, { type: 'error' });
120
+ }
121
+ }
122
+
123
+ // 5. Recargar si fue exitoso y se solicitó
124
+ if (success && reload && typeof window !== 'undefined' && window.location && typeof window.location.reload === 'function') {
125
+ window.location.reload();
126
+ }
127
+
128
+ return { confirmed: true, success, error };
129
+ }
130
+
131
+ return {
132
+ requestResetConfirmation,
133
+ resetAllData,
134
+ reset: resetAllData
135
+ };
136
+ }));
@@ -0,0 +1,508 @@
1
+ /**
2
+ * Módulo de Depuración, Logs e Interceptor de Mensajes (ChatDebug) para ZeroChat.
3
+ * Gestiona el panel de logs, el filtrado por pestañas (Todo, Pensamiento, Herramientas, Red, Raw),
4
+ * el formateo de marcas temporales y la ventana emergente de depuración de payloads salientes.
5
+ */
6
+ (function (root, factory) {
7
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
8
+ module.exports = factory();
9
+ } else {
10
+ root.ChatDebug = factory();
11
+ }
12
+ }(typeof self !== 'undefined' ? self : this, function () {
13
+ 'use strict';
14
+
15
+ function getMarkdown() {
16
+ return (typeof window !== 'undefined' && window.ChatMarkdown) ? window.ChatMarkdown : {
17
+ escapeHtml: (str) => String(str || '')
18
+ };
19
+ }
20
+
21
+ function getI18n() {
22
+ return (typeof window !== 'undefined' && window.ChatI18n) ? window.ChatI18n : {
23
+ t: (k) => k
24
+ };
25
+ }
26
+
27
+ function t(key, params) {
28
+ const i18n = getI18n();
29
+ return i18n.t ? i18n.t(key, params) : key;
30
+ }
31
+
32
+ let dom = {};
33
+ let isAutoscroll = true;
34
+ let activeFilter = 'all';
35
+ let activeThinkingBlock = null;
36
+ let rawLogsEnabled = true;
37
+ const MAX_RAW_ENTRIES = 2000;
38
+
39
+ function setElements(elements) {
40
+ dom = elements || {};
41
+ }
42
+
43
+ function setRawLogsEnabled(enabled) {
44
+ rawLogsEnabled = Boolean(enabled);
45
+ }
46
+
47
+ function isRawLogsEnabled() {
48
+ return rawLogsEnabled;
49
+ }
50
+
51
+ function getFormattedTime() {
52
+ const now = new Date();
53
+ return now.toTimeString().split(' ')[0];
54
+ }
55
+
56
+ function toggleAutoscroll() {
57
+ isAutoscroll = !isAutoscroll;
58
+ if (dom.btnToggleAutoscroll) {
59
+ dom.btnToggleAutoscroll.classList.toggle('active', isAutoscroll);
60
+ }
61
+ return isAutoscroll;
62
+ }
63
+
64
+ function togglePanel(forceOpen) {
65
+ if (!dom.debugPanel) return;
66
+ const isVisible = dom.debugPanel.style.display !== 'none';
67
+ const shouldOpen = (forceOpen !== undefined) ? forceOpen : !isVisible;
68
+
69
+ if (shouldOpen) {
70
+ dom.debugPanel.style.display = 'flex';
71
+ dom.debugPanel.setAttribute('aria-hidden', 'false');
72
+ if (dom.btnToggleDebug) {
73
+ dom.btnToggleDebug.classList.add('active');
74
+ dom.btnToggleDebug.setAttribute('aria-expanded', 'true');
75
+ }
76
+ if (isAutoscroll && dom.debugLogContent) {
77
+ dom.debugLogContent.scrollTop = dom.debugLogContent.scrollHeight;
78
+ }
79
+ } else {
80
+ dom.debugPanel.style.display = 'none';
81
+ dom.debugPanel.setAttribute('aria-hidden', 'true');
82
+ if (dom.btnToggleDebug) {
83
+ dom.btnToggleDebug.classList.remove('active');
84
+ dom.btnToggleDebug.setAttribute('aria-expanded', 'false');
85
+ }
86
+ }
87
+ }
88
+
89
+ function setStatus(status, text) {
90
+ if (!dom.debugStatusIndicator) return;
91
+ dom.debugStatusIndicator.className = `debug-status-indicator ${status || 'idle'}`;
92
+ let label = text;
93
+ if (!label) {
94
+ if (status === 'streaming') label = t('debug_status_streaming');
95
+ else if (status === 'done') label = t('debug_status_done');
96
+ else if (status === 'error') label = t('debug_status_error');
97
+ else label = t('debug_status_idle');
98
+ }
99
+ dom.debugStatusIndicator.textContent = label;
100
+ }
101
+
102
+ function clearLogs() {
103
+ if (!dom.debugLogContent) return;
104
+ dom.debugLogContent.innerHTML = `
105
+ <div class="debug-entry debug-entry-system" data-type="system">
106
+ <span class="debug-time">[${getFormattedTime()}]</span>
107
+ <span class="debug-tag system">[${t('debug_tag_system')}]</span>
108
+ <span class="debug-msg">${t('debug_sys_cleared')}</span>
109
+ </div>
110
+ `;
111
+ activeThinkingBlock = null;
112
+ }
113
+
114
+ async function copyLogs() {
115
+ if (!dom.debugLogContent || !dom.btnCopyDebug) return false;
116
+ try {
117
+ const text = dom.debugLogContent.innerText;
118
+ if (typeof navigator !== 'undefined' && navigator.clipboard) {
119
+ await navigator.clipboard.writeText(text);
120
+ }
121
+ const originalHtml = dom.btnCopyDebug.innerHTML;
122
+ dom.btnCopyDebug.innerHTML = '<svg class="ui-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>';
123
+ setTimeout(() => {
124
+ dom.btnCopyDebug.innerHTML = originalHtml;
125
+ }, 1500);
126
+ return true;
127
+ } catch (e) {
128
+ console.error('ChatDebug: Error al copiar logs:', e);
129
+ return false;
130
+ }
131
+ }
132
+
133
+ function getDoc() {
134
+ if (typeof document !== 'undefined') return document;
135
+ if (typeof window !== 'undefined' && window.document) return window.document;
136
+ return null;
137
+ }
138
+
139
+ function addLog(type, text, rawData) {
140
+ if (!dom.debugLogContent) return;
141
+ const doc = getDoc();
142
+ if (!doc || typeof doc.createElement !== 'function') return;
143
+ const Markdown = getMarkdown();
144
+
145
+ // 1. Logs RAW
146
+ if (type === 'raw') {
147
+ if (!rawLogsEnabled) return;
148
+
149
+ const entry = doc.createElement('div');
150
+ const isOutgoing = (rawData && rawData.subtype === 'outgoing') || String(text).startsWith('>>>');
151
+ entry.className = `debug-entry debug-entry-raw ${isOutgoing ? 'raw-outgoing' : 'raw-incoming'}`;
152
+ entry.setAttribute('data-type', 'raw');
153
+
154
+ entry.innerHTML = `
155
+ <div class="debug-entry-header">
156
+ <span class="debug-time">[${getFormattedTime()}]</span>
157
+ <span class="debug-tag raw">${isOutgoing ? 'RAW OUT' : 'RAW IN'}</span>
158
+ </div>
159
+ <div class="debug-msg">${Markdown.escapeHtml(text)}</div>
160
+ `;
161
+
162
+ if (activeFilter !== 'raw') {
163
+ entry.style.display = 'none';
164
+ }
165
+
166
+ dom.debugLogContent.appendChild(entry);
167
+
168
+ // Limitar el número de entradas raw para evitar acumulación excesiva en memoria
169
+ const rawEntries = dom.debugLogContent.querySelectorAll('[data-type="raw"]');
170
+ if (rawEntries.length > MAX_RAW_ENTRIES) {
171
+ rawEntries[0].remove();
172
+ }
173
+
174
+ if (isAutoscroll) {
175
+ dom.debugLogContent.scrollTop = dom.debugLogContent.scrollHeight;
176
+ }
177
+ return;
178
+ }
179
+
180
+ // 2. Logs de Razonamiento / Thinking
181
+ if (type === 'thinking') {
182
+ if (!activeThinkingBlock) {
183
+ const entry = doc.createElement('div');
184
+ entry.className = 'debug-entry debug-entry-thinking';
185
+ entry.setAttribute('data-type', 'thinking');
186
+ entry.innerHTML = `
187
+ <div class="debug-entry-header">
188
+ <span class="debug-time">[${getFormattedTime()}]</span>
189
+ <span class="debug-tag thinking">${t('debug_tag_thinking')}</span>
190
+ </div>
191
+ <div class="debug-msg"></div>
192
+ `;
193
+ dom.debugLogContent.appendChild(entry);
194
+ activeThinkingBlock = entry.querySelector('.debug-msg');
195
+
196
+ if (activeFilter !== 'all' && activeFilter !== 'thinking') {
197
+ entry.style.display = 'none';
198
+ }
199
+ }
200
+
201
+ if (activeThinkingBlock) {
202
+ activeThinkingBlock.textContent += text;
203
+ }
204
+
205
+ if (isAutoscroll) {
206
+ dom.debugLogContent.scrollTop = dom.debugLogContent.scrollHeight;
207
+ }
208
+ return;
209
+ }
210
+
211
+ // 3. Otros tipos (network, tool, stats, error, system, info)
212
+ activeThinkingBlock = null;
213
+
214
+ const entry = doc.createElement('div');
215
+ entry.className = `debug-entry debug-entry-${type || 'info'}`;
216
+ entry.setAttribute('data-type', type || 'info');
217
+
218
+ let tagLabel = t('debug_tag_info');
219
+ if (type === 'network') tagLabel = t('debug_tag_network');
220
+ else if (type === 'tool') tagLabel = t('debug_tag_tool');
221
+ else if (type === 'stats') tagLabel = t('debug_tag_stats');
222
+ else if (type === 'error') tagLabel = t('debug_tag_error');
223
+ else if (type === 'warning') tagLabel = t('debug_tag_warning');
224
+ else if (type === 'system') tagLabel = t('debug_tag_system');
225
+
226
+ entry.innerHTML = `
227
+ <div class="debug-entry-header">
228
+ <span class="debug-time">[${getFormattedTime()}]</span>
229
+ <span class="debug-tag ${type || 'info'}">[${tagLabel}]</span>
230
+ </div>
231
+ <div class="debug-msg">${Markdown.escapeHtml(text)}</div>
232
+ `;
233
+
234
+ if (activeFilter === 'raw') {
235
+ entry.style.display = 'none';
236
+ } else if (activeFilter !== 'all') {
237
+ const match = (activeFilter === type) ||
238
+ (activeFilter === 'tool' && type === 'tool') ||
239
+ (activeFilter === 'network' && (type === 'network' || type === 'stats' || type === 'error' || type === 'warning'));
240
+ if (!match) entry.style.display = 'none';
241
+ }
242
+
243
+ dom.debugLogContent.appendChild(entry);
244
+ if (isAutoscroll) {
245
+ dom.debugLogContent.scrollTop = dom.debugLogContent.scrollHeight;
246
+ }
247
+ }
248
+
249
+ function filterLogs(tabId) {
250
+ activeFilter = tabId;
251
+ if (!dom.debugLogContent) return;
252
+
253
+ const entries = dom.debugLogContent.querySelectorAll('.debug-entry');
254
+ entries.forEach(entry => {
255
+ const type = entry.getAttribute('data-type');
256
+ if (tabId === 'all') {
257
+ entry.style.display = (type === 'raw') ? 'none' : 'flex';
258
+ } else if (tabId === 'thinking') {
259
+ entry.style.display = (type === 'thinking') ? 'flex' : 'none';
260
+ } else if (tabId === 'tool') {
261
+ entry.style.display = (type === 'tool') ? 'flex' : 'none';
262
+ } else if (tabId === 'network') {
263
+ entry.style.display = (type === 'network' || type === 'stats' || type === 'error' || type === 'warning') ? 'flex' : 'none';
264
+ } else if (tabId === 'raw') {
265
+ entry.style.display = (type === 'raw') ? 'flex' : 'none';
266
+ }
267
+ });
268
+ }
269
+
270
+ function openInterceptorModal({ endpoint, headers, payload, onSyncDebugState }) {
271
+ ensureDialogMarkup();
272
+ return new Promise((resolve) => {
273
+ if (!dom.debugInterceptorDialog) {
274
+ return resolve({ cancel: false, modifiedPayload: null });
275
+ }
276
+
277
+ let isMaximized = false;
278
+ const MAXIMIZE_SVG = '<svg class="ui-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>';
279
+ const RESTORE_SVG = '<svg class="ui-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 14 10 14 10 20"></polyline><polyline points="20 10 14 10 14 4"></polyline><line x1="14" y1="10" x2="21" y2="3"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>';
280
+
281
+ if (dom.btnMaximizeDebugModal) {
282
+ dom.btnMaximizeDebugModal.innerHTML = MAXIMIZE_SVG;
283
+ }
284
+
285
+ if (dom.debugModalEndpointBadge) {
286
+ dom.debugModalEndpointBadge.textContent = `POST ${endpoint}`;
287
+ }
288
+ if (dom.txtDebugPayload) {
289
+ dom.txtDebugPayload.value = JSON.stringify(payload, null, 2);
290
+ }
291
+ if (dom.debugJsonError) {
292
+ dom.debugJsonError.style.display = 'none';
293
+ dom.debugJsonError.textContent = '';
294
+ }
295
+
296
+ function cleanup() {
297
+ if (dom.debugInterceptorDialog.open) {
298
+ dom.debugInterceptorDialog.close();
299
+ }
300
+ dom.debugInterceptorDialog.classList.remove('maximized');
301
+ if (dom.btnMaximizeDebugModal) dom.btnMaximizeDebugModal.onclick = null;
302
+ if (dom.btnDebugSend) dom.btnDebugSend.onclick = null;
303
+ if (dom.btnDebugSendDisable) dom.btnDebugSendDisable.onclick = null;
304
+ if (dom.btnCloseDebugModal) dom.btnCloseDebugModal.onclick = null;
305
+ if (dom.btnFormatDebugJson) dom.btnFormatDebugJson.onclick = null;
306
+ if (dom.btnCopyDebugJson) dom.btnCopyDebugJson.onclick = null;
307
+ }
308
+
309
+ if (dom.btnMaximizeDebugModal) {
310
+ dom.btnMaximizeDebugModal.onclick = () => {
311
+ isMaximized = !isMaximized;
312
+ dom.debugInterceptorDialog.classList.toggle('maximized', isMaximized);
313
+ dom.btnMaximizeDebugModal.innerHTML = isMaximized ? RESTORE_SVG : MAXIMIZE_SVG;
314
+ };
315
+ }
316
+
317
+ if (dom.btnFormatDebugJson) {
318
+ dom.btnFormatDebugJson.onclick = () => {
319
+ try {
320
+ const parsed = JSON.parse(dom.txtDebugPayload.value);
321
+ dom.txtDebugPayload.value = JSON.stringify(parsed, null, 2);
322
+ if (dom.debugJsonError) dom.debugJsonError.style.display = 'none';
323
+ } catch (err) {
324
+ if (dom.debugJsonError) {
325
+ dom.debugJsonError.textContent = t('debug_json_error_invalid', { error: err.message });
326
+ dom.debugJsonError.style.display = 'block';
327
+ }
328
+ }
329
+ };
330
+ }
331
+
332
+ if (dom.btnCopyDebugJson) {
333
+ dom.btnCopyDebugJson.onclick = async () => {
334
+ try {
335
+ await navigator.clipboard.writeText(dom.txtDebugPayload.value);
336
+ const span = dom.btnCopyDebugJson.querySelector('span');
337
+ if (span) {
338
+ const old = span.textContent;
339
+ span.textContent = 'Copiado';
340
+ setTimeout(() => { span.textContent = old; }, 1500);
341
+ }
342
+ } catch (e) {}
343
+ };
344
+ }
345
+
346
+ function handleSend(disableDebug = false) {
347
+ let editedJson = null;
348
+ const raw = dom.txtDebugPayload.value.trim();
349
+ if (raw) {
350
+ try {
351
+ editedJson = JSON.parse(raw);
352
+ } catch (err) {
353
+ if (dom.debugJsonError) {
354
+ dom.debugJsonError.textContent = t('debug_json_error_invalid', { error: err.message });
355
+ dom.debugJsonError.style.display = 'block';
356
+ }
357
+ return;
358
+ }
359
+ }
360
+
361
+ if (disableDebug && typeof onSyncDebugState === 'function') {
362
+ onSyncDebugState(false);
363
+ }
364
+
365
+ cleanup();
366
+ resolve({ cancel: false, modifiedPayload: editedJson });
367
+ }
368
+
369
+ if (dom.btnDebugSend) {
370
+ dom.btnDebugSend.onclick = () => handleSend(false);
371
+ }
372
+ if (dom.btnDebugSendDisable) {
373
+ dom.btnDebugSendDisable.onclick = () => handleSend(true);
374
+ }
375
+ if (dom.btnCloseDebugModal) {
376
+ dom.btnCloseDebugModal.onclick = () => {
377
+ cleanup();
378
+ resolve({ cancel: true });
379
+ };
380
+ }
381
+ dom.debugInterceptorDialog.showModal();
382
+ if (dom.txtDebugPayload) {
383
+ dom.txtDebugPayload.focus();
384
+ }
385
+ });
386
+ }
387
+
388
+ function getDebugInterceptorDialogHTML() {
389
+ return `<div class="modal-header">
390
+ <div class="modal-title">
391
+ <h3 data-i18n="debug_modal_title">Debug</h3>
392
+ </div>
393
+ <div class="modal-header-actions">
394
+ <div class="debug-modal-send-actions">
395
+ <button type="button" id="btn-debug-send-disable" class="btn-debug-header-action btn-debug-header-stop" data-i18n="btn_send_and_stop_debug"><svg class="ui-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-stop"></use></svg><span>Enviar y parar debug</span></button>
396
+ <button type="button" id="btn-debug-send" class="btn-debug-header-action btn-debug-header-send" data-i18n="btn_send"><svg class="ui-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-send"></use></svg><span>Enviar</span></button>
397
+ </div>
398
+ <button type="button" id="btn-maximize-debug-modal" class="modal-btn-action" data-i18n-title="btn_maximize_title" title="Maximizar / Restaurar">
399
+ <svg class="ui-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-shuffle"></use></svg>
400
+ </button>
401
+ <button type="button" id="btn-close-debug-modal" class="modal-btn-close" data-i18n-title="btn_cancel" title="Cancelar envío"><svg class="ui-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-close"></use></svg></button>
402
+ </div>
403
+ </div>
404
+
405
+ <div class="debug-modal-body">
406
+ <div class="debug-modal-info">
407
+ <p data-i18n="debug_modal_desc">
408
+ Revisa o modifica el payload JSON antes de enviarlo al servidor. Puedes editar cualquier mensaje, parámetros o herramientas.
409
+ </p>
410
+ </div>
411
+
412
+ <div class="debug-editor-wrapper">
413
+ <div class="debug-editor-header">
414
+ <span id="debug-modal-endpoint-badge" class="debug-endpoint-badge">POST /v1/chat/completions</span>
415
+ <div class="debug-editor-actions">
416
+ <button type="button" id="btn-format-debug-json" class="btn-secondary btn-debug-editor-action" title="Formatear JSON">
417
+ <svg class="ui-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-sparkles"></use></svg>
418
+ <span data-i18n="btn_format_json">Formatear</span>
419
+ </button>
420
+ <button type="button" id="btn-copy-debug-json" class="btn-secondary btn-debug-editor-action" title="Copiar todo al portapapeles">
421
+ <svg class="ui-icon" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor"><use href="#icon-copy"></use></svg>
422
+ <span data-i18n="btn_copy_all">Copiar todo</span>
423
+ </button>
424
+ </div>
425
+ </div>
426
+ <textarea id="txt-debug-payload" class="debug-payload-textarea" spellcheck="false" wrap="off"></textarea>
427
+ <div id="debug-json-error" class="debug-json-error" style="display: none;"></div>
428
+ </div>
429
+
430
+ </div>`;
431
+ }
432
+
433
+ function ensureDialogMarkup() {
434
+ if (typeof document === 'undefined') return;
435
+ const dialog = document.getElementById('debug-interceptor-dialog');
436
+ if (dialog && !dialog.firstElementChild) {
437
+ dialog.innerHTML = getDebugInterceptorDialogHTML();
438
+ }
439
+ if (!dialog) return;
440
+ dom.debugInterceptorDialog = dialog;
441
+ dom.btnMaximizeDebugModal = dialog.querySelector('#btn-maximize-debug-modal');
442
+ dom.debugModalEndpointBadge = dialog.querySelector('#debug-modal-endpoint-badge');
443
+ dom.btnFormatDebugJson = dialog.querySelector('#btn-format-debug-json');
444
+ dom.btnCopyDebugJson = dialog.querySelector('#btn-copy-debug-json');
445
+ dom.txtDebugPayload = dialog.querySelector('#txt-debug-payload');
446
+ dom.debugJsonError = dialog.querySelector('#debug-json-error');
447
+ dom.btnCloseDebugModal = dialog.querySelector('#btn-close-debug-modal');
448
+ dom.btnDebugSendDisable = dialog.querySelector('#btn-debug-send-disable');
449
+ dom.btnDebugSend = dialog.querySelector('#btn-debug-send');
450
+ }
451
+
452
+ let globalHandlersRegistered = false;
453
+
454
+ function registerGlobalErrorHandlers(targetWindow = (typeof window !== 'undefined' ? window : null)) {
455
+ if (!targetWindow || typeof targetWindow.addEventListener !== 'function') return false;
456
+ const isDefaultWindow = typeof window !== 'undefined' && targetWindow === window;
457
+ if (isDefaultWindow) {
458
+ if (globalHandlersRegistered) return true;
459
+ globalHandlersRegistered = true;
460
+ }
461
+
462
+ targetWindow.addEventListener('unhandledrejection', (event) => {
463
+ try {
464
+ const reason = event?.reason;
465
+ if (reason && (reason.name === 'AbortError' || (typeof reason.message === 'string' && reason.message.includes('aborted')))) {
466
+ return;
467
+ }
468
+ const text = reason?.stack || reason?.message || String(reason || 'Unknown unhandled rejection');
469
+ addLog('error', `[Unhandled Promise] ${text}`);
470
+ } catch (_) {}
471
+ });
472
+
473
+ targetWindow.addEventListener('error', (event) => {
474
+ try {
475
+ if (event?.error && (event.error.name === 'AbortError' || (typeof event.error.message === 'string' && event.error.message.includes('aborted')))) {
476
+ return;
477
+ }
478
+ const msg = event?.message || event?.error?.message || 'Runtime error';
479
+ const source = event?.filename ? ` at ${event.filename}:${event.lineno || 0}` : '';
480
+ addLog('error', `[Runtime Error] ${msg}${source}`);
481
+ } catch (_) {}
482
+ });
483
+
484
+ return true;
485
+ }
486
+
487
+ if (typeof window !== 'undefined') {
488
+ registerGlobalErrorHandlers(window);
489
+ }
490
+
491
+ return {
492
+ setElements,
493
+ setRawLogsEnabled,
494
+ isRawLogsEnabled,
495
+ getFormattedTime,
496
+ toggleAutoscroll,
497
+ togglePanel,
498
+ setStatus,
499
+ clearLogs,
500
+ copyLogs,
501
+ addLog,
502
+ filterLogs,
503
+ openInterceptorModal,
504
+ ensureDialogMarkup,
505
+ getDebugInterceptorDialogHTML,
506
+ registerGlobalErrorHandlers
507
+ };
508
+ }));
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Valores predeterminados compartidos por el arranque y la configuración.
3
+ */
4
+ (function (root, factory) {
5
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
6
+ module.exports = factory();
7
+ } else {
8
+ root.ChatDefaults = factory();
9
+ }
10
+ })(typeof self !== 'undefined' ? self : this, function () {
11
+ 'use strict';
12
+
13
+ return Object.freeze({
14
+ DEFAULT_THEME: 'dark'
15
+ });
16
+ });