wu-framework 1.2.1 → 2.1.0
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/README.md +99 -18
- package/dist/adapters/alpine/index.js +2 -0
- package/dist/adapters/alpine/index.js.map +1 -0
- package/dist/adapters/angular/index.js +2 -0
- package/dist/adapters/angular/index.js.map +1 -0
- package/dist/adapters/htmx/index.js +2 -0
- package/dist/adapters/htmx/index.js.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/lit/index.js +44 -0
- package/dist/adapters/lit/index.js.map +1 -0
- package/dist/adapters/preact/index.js +2 -0
- package/dist/adapters/preact/index.js.map +1 -0
- package/dist/adapters/qwik/index.js +2 -0
- package/dist/adapters/qwik/index.js.map +1 -0
- package/dist/adapters/react/index.js +2 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/shared.js +2 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/solid/index.js +2 -0
- package/dist/adapters/solid/index.js.map +1 -0
- package/dist/adapters/stencil/index.js +2 -0
- package/dist/adapters/stencil/index.js.map +1 -0
- package/dist/adapters/stimulus/index.js +2 -0
- package/dist/adapters/stimulus/index.js.map +1 -0
- package/dist/adapters/svelte/index.js +2 -0
- package/dist/adapters/svelte/index.js.map +1 -0
- package/dist/adapters/vanilla/index.js +2 -0
- package/dist/adapters/vanilla/index.js.map +1 -0
- package/dist/adapters/vue/index.js +2 -0
- package/dist/adapters/vue/index.js.map +1 -0
- package/dist/ai/wu-ai.js +2 -0
- package/dist/ai/wu-ai.js.map +1 -0
- package/dist/core/wu-mcp-bridge.js +2 -0
- package/dist/core/wu-mcp-bridge.js.map +1 -0
- package/{src → dist}/index.d.ts +445 -317
- package/dist/wu-ai-browser-primitives-BDKXJlwc.js +2 -0
- package/dist/wu-ai-browser-primitives-BDKXJlwc.js.map +1 -0
- package/dist/wu-framework.cjs.js +2 -2
- package/dist/wu-framework.cjs.js.map +1 -1
- package/dist/wu-framework.dev.js +2640 -9197
- package/dist/wu-framework.dev.js.map +1 -1
- package/dist/wu-framework.esm.js +2 -2
- package/dist/wu-framework.esm.js.map +1 -1
- package/dist/wu-framework.umd.js +2 -2
- package/dist/wu-framework.umd.js.map +1 -1
- package/dist/wu-html-parser.js +2 -0
- package/dist/wu-html-parser.js.map +1 -0
- package/dist/wu-iframe-sandbox.js +2 -0
- package/dist/wu-iframe-sandbox.js.map +1 -0
- package/dist/wu-logger-fJfUHBGA.js +2 -0
- package/dist/wu-logger-fJfUHBGA.js.map +1 -0
- package/dist/wu-script-executor.js +2 -0
- package/dist/wu-script-executor.js.map +1 -0
- package/package.json +43 -34
- package/src/adapters/alpine/index.js +0 -231
- package/src/adapters/alpine.js +0 -3
- package/src/adapters/angular/ai.js +0 -30
- package/src/adapters/angular/index.js +0 -932
- package/src/adapters/angular.js +0 -3
- package/src/adapters/htmx/index.js +0 -242
- package/src/adapters/htmx.js +0 -3
- package/src/adapters/index.js +0 -225
- package/src/adapters/lit/ai.js +0 -20
- package/src/adapters/lit/index.js +0 -721
- package/src/adapters/lit.js +0 -3
- package/src/adapters/preact/ai.js +0 -33
- package/src/adapters/preact/index.js +0 -661
- package/src/adapters/preact.js +0 -3
- package/src/adapters/qwik/index.js +0 -108
- package/src/adapters/qwik.js +0 -3
- package/src/adapters/react/ai.js +0 -135
- package/src/adapters/react/index.js +0 -695
- package/src/adapters/react.js +0 -3
- package/src/adapters/shared.js +0 -64
- package/src/adapters/solid/ai.js +0 -32
- package/src/adapters/solid/index.js +0 -586
- package/src/adapters/solid.js +0 -3
- package/src/adapters/stencil/index.js +0 -228
- package/src/adapters/stencil.js +0 -3
- package/src/adapters/stimulus/index.js +0 -255
- package/src/adapters/stimulus.js +0 -3
- package/src/adapters/svelte/ai.js +0 -31
- package/src/adapters/svelte/index.js +0 -798
- package/src/adapters/svelte.js +0 -3
- package/src/adapters/vanilla/ai.js +0 -30
- package/src/adapters/vanilla/index.js +0 -785
- package/src/adapters/vanilla.js +0 -3
- package/src/adapters/vue/ai.js +0 -52
- package/src/adapters/vue/index.js +0 -618
- package/src/adapters/vue.js +0 -3
- package/src/ai/wu-ai-actions.js +0 -261
- package/src/ai/wu-ai-agent.js +0 -546
- package/src/ai/wu-ai-browser-primitives.js +0 -354
- package/src/ai/wu-ai-browser.js +0 -380
- package/src/ai/wu-ai-context.js +0 -332
- package/src/ai/wu-ai-conversation.js +0 -613
- package/src/ai/wu-ai-orchestrate.js +0 -1021
- package/src/ai/wu-ai-permissions.js +0 -381
- package/src/ai/wu-ai-provider.js +0 -700
- package/src/ai/wu-ai-schema.js +0 -225
- package/src/ai/wu-ai-triggers.js +0 -396
- package/src/ai/wu-ai.js +0 -804
- package/src/core/wu-app.js +0 -236
- package/src/core/wu-cache.js +0 -498
- package/src/core/wu-core.js +0 -1412
- package/src/core/wu-error-boundary.js +0 -396
- package/src/core/wu-event-bus.js +0 -390
- package/src/core/wu-hooks.js +0 -350
- package/src/core/wu-html-parser.js +0 -199
- package/src/core/wu-iframe-sandbox.js +0 -328
- package/src/core/wu-loader.js +0 -450
- package/src/core/wu-logger.js +0 -143
- package/src/core/wu-manifest.js +0 -533
- package/src/core/wu-mcp-bridge.js +0 -432
- package/src/core/wu-overrides.js +0 -510
- package/src/core/wu-performance.js +0 -228
- package/src/core/wu-plugin.js +0 -401
- package/src/core/wu-prefetch.js +0 -414
- package/src/core/wu-proxy-sandbox.js +0 -477
- package/src/core/wu-sandbox.js +0 -779
- package/src/core/wu-script-executor.js +0 -161
- package/src/core/wu-sentinel-client.js +0 -311
- package/src/core/wu-snapshot-sandbox.js +0 -227
- package/src/core/wu-store.js +0 -307
- package/src/core/wu-strategies.js +0 -256
- package/src/core/wu-style-bridge.js +0 -477
- package/src/index.js +0 -234
- package/src/utils/dependency-resolver.js +0 -328
- /package/{src → dist}/adapters/alpine/index.d.ts +0 -0
- /package/{src → dist}/adapters/alpine.d.ts +0 -0
- /package/{src → dist}/adapters/angular/index.d.ts +0 -0
- /package/{src → dist}/adapters/angular.d.ts +0 -0
- /package/{src → dist}/adapters/htmx/index.d.ts +0 -0
- /package/{src → dist}/adapters/htmx.d.ts +0 -0
- /package/{src → dist}/adapters/lit/index.d.ts +0 -0
- /package/{src → dist}/adapters/lit.d.ts +0 -0
- /package/{src → dist}/adapters/preact/index.d.ts +0 -0
- /package/{src → dist}/adapters/preact.d.ts +0 -0
- /package/{src → dist}/adapters/qwik/index.d.ts +0 -0
- /package/{src → dist}/adapters/qwik.d.ts +0 -0
- /package/{src → dist}/adapters/react/index.d.ts +0 -0
- /package/{src → dist}/adapters/react.d.ts +0 -0
- /package/{src → dist}/adapters/solid/index.d.ts +0 -0
- /package/{src → dist}/adapters/solid.d.ts +0 -0
- /package/{src → dist}/adapters/stencil/index.d.ts +0 -0
- /package/{src → dist}/adapters/stencil.d.ts +0 -0
- /package/{src → dist}/adapters/stimulus/index.d.ts +0 -0
- /package/{src → dist}/adapters/stimulus.d.ts +0 -0
- /package/{src → dist}/adapters/svelte/index.d.ts +0 -0
- /package/{src → dist}/adapters/svelte.d.ts +0 -0
- /package/{src → dist}/adapters/vanilla/index.d.ts +0 -0
- /package/{src → dist}/adapters/vanilla.d.ts +0 -0
- /package/{src → dist}/adapters/vue/index.d.ts +0 -0
- /package/{src → dist}/adapters/vue.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/adapters/vanilla/ai.js","../../../src/adapters/vanilla/index.js"],"sourcesContent":["/**\r\n * WU-FRAMEWORK VANILLA JS AI INTEGRATION\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n return window.wu || window.parent?.wu || window.top?.wu || null;\r\n}\r\n\r\nexport function useWuAI(options = {}) {\r\n const { namespace = 'default' } = options;\r\n const state = { messages: [], isStreaming: false, error: null };\r\n return {\r\n async send(text) {\r\n if (!text?.trim()) return null;\r\n const wu = getWuInstance();\r\n if (!wu?.ai) { state.error = 'Wu AI not available'; return null; }\r\n state.messages.push({ id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now() });\r\n state.isStreaming = true; state.error = null;\r\n try {\r\n const res = await wu.ai.send(text, { namespace });\r\n state.messages.push({ id: `assistant-${Date.now()}`, role: 'assistant', content: res.content, timestamp: Date.now() });\r\n state.isStreaming = false; return res;\r\n } catch (err) { state.error = err.message; state.isStreaming = false; return null; }\r\n },\r\n clear() { state.messages.length = 0; state.error = null; },\r\n getMessages() { return [...state.messages]; },\r\n getError() { return state.error; },\r\n isStreaming() { return state.isStreaming; },\r\n };\r\n}\r\n","/**\r\n * 🚀 WU-FRAMEWORK VANILLA JS ADAPTER\r\n *\r\n * El adapter más simple - Para JavaScript puro sin frameworks.\r\n * Ideal para microfrontends ligeros o legacy code.\r\n *\r\n * @example\r\n * // Microfrontend (main.js)\r\n * import { wuVanilla } from 'wu-framework/adapters/vanilla';\r\n *\r\n * wuVanilla.register('my-app', {\r\n * render: (container) => {\r\n * container.innerHTML = '<h1>Hello World</h1>';\r\n * }\r\n * });\r\n *\r\n * @example\r\n * // Con clase\r\n * class MyApp {\r\n * constructor(container) {\r\n * this.container = container;\r\n * }\r\n * render() {\r\n * this.container.innerHTML = '<h1>My App</h1>';\r\n * }\r\n * destroy() {\r\n * this.container.innerHTML = '';\r\n * }\r\n * }\r\n *\r\n * wuVanilla.registerClass('my-app', MyApp);\r\n */\r\n\r\n// Estado global del adapter\r\nconst adapterState = {\r\n apps: new Map(),\r\n instances: new Map()\r\n};\r\n\r\n/**\r\n * Obtiene la instancia de Wu Framework\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n\r\n return window.wu\r\n || window.parent?.wu\r\n || window.top?.wu\r\n || null;\r\n}\r\n\r\n/**\r\n * Espera a que Wu Framework esté disponible\r\n */\r\nfunction waitForWu(timeout = 5000) {\r\n return new Promise((resolve, reject) => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n\r\n const handleWuReady = () => {\r\n cleanup();\r\n resolve(getWuInstance());\r\n };\r\n\r\n window.addEventListener('wu:ready', handleWuReady);\r\n window.addEventListener('wu:app:ready', handleWuReady);\r\n\r\n const checkInterval = setInterval(() => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n cleanup();\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n if (Date.now() - startTime > timeout) {\r\n cleanup();\r\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\r\n }\r\n }, 200);\r\n\r\n function cleanup() {\r\n clearInterval(checkInterval);\r\n window.removeEventListener('wu:ready', handleWuReady);\r\n window.removeEventListener('wu:app:ready', handleWuReady);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Registra una app Vanilla JS como microfrontend\r\n *\r\n * @param {string} appName - Nombre único del microfrontend\r\n * @param {Object} config - Configuración de la app\r\n * @param {Function} config.render - Función para renderizar (recibe container)\r\n * @param {Function} [config.destroy] - Función para limpiar (recibe container)\r\n * @param {Function} [config.init] - Función de inicialización (recibe container)\r\n * @param {Object} [config.state] - Estado inicial\r\n * @param {Object} options - Opciones adicionales\r\n *\r\n * @example\r\n * wuVanilla.register('counter', {\r\n * state: { count: 0 },\r\n * init: (container) => {\r\n * console.log('Initializing...');\r\n * },\r\n * render: (container, state) => {\r\n * container.innerHTML = `\r\n * <div>\r\n * <h1>Count: ${state.count}</h1>\r\n * <button id=\"increment\">+</button>\r\n * </div>\r\n * `;\r\n * container.querySelector('#increment').onclick = () => {\r\n * state.count++;\r\n * // Re-render\r\n * };\r\n * },\r\n * destroy: (container) => {\r\n * container.innerHTML = '';\r\n * }\r\n * });\r\n */\r\nasync function register(appName, config, options = {}) {\r\n const {\r\n render,\r\n destroy = null,\r\n init = null,\r\n state = {}\r\n } = config;\r\n\r\n const {\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#app'\r\n } = options;\r\n\r\n if (!render || typeof render !== 'function') {\r\n throw new Error(`[WuVanilla] render function is required for ${appName}`);\r\n }\r\n\r\n // Estado local de la app\r\n const appState = { ...state };\r\n\r\n // Función de mount\r\n const mountApp = (container) => {\r\n if (!container) {\r\n console.error(`[WuVanilla] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.apps.has(appName)) {\r\n console.warn(`[WuVanilla] ${appName} already mounted, unmounting first`);\r\n unmountApp();\r\n }\r\n\r\n try {\r\n // Limpiar container\r\n container.innerHTML = '';\r\n\r\n // Ejecutar init si existe\r\n if (init && typeof init === 'function') {\r\n init(container, appState);\r\n }\r\n\r\n // Renderizar\r\n render(container, appState);\r\n\r\n // Guardar referencia\r\n adapterState.apps.set(appName, {\r\n container,\r\n config,\r\n state: appState\r\n });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, appState);\r\n }\r\n } catch (error) {\r\n console.error(`[WuVanilla] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount\r\n const unmountApp = (container) => {\r\n const appData = adapterState.apps.get(appName);\r\n\r\n if (appData) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(appData.container, appData.state);\r\n }\r\n\r\n // Ejecutar destroy si existe\r\n if (destroy && typeof destroy === 'function') {\r\n destroy(appData.container, appData.state);\r\n } else {\r\n // Cleanup por defecto\r\n appData.container.innerHTML = '';\r\n }\r\n\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuVanilla] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuVanilla] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuVanilla] Running ${appName} in standalone mode`);\r\n mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Registra una clase como microfrontend\r\n *\r\n * @param {string} appName - Nombre único del microfrontend\r\n * @param {Function} AppClass - Clase con constructor(container) y métodos render/destroy\r\n * @param {Object} options - Opciones adicionales\r\n *\r\n * @example\r\n * class TodoApp {\r\n * constructor(container) {\r\n * this.container = container;\r\n * this.todos = [];\r\n * }\r\n *\r\n * render() {\r\n * this.container.innerHTML = `\r\n * <ul>${this.todos.map(t => `<li>${t}</li>`).join('')}</ul>\r\n * `;\r\n * }\r\n *\r\n * addTodo(text) {\r\n * this.todos.push(text);\r\n * this.render();\r\n * }\r\n *\r\n * destroy() {\r\n * this.container.innerHTML = '';\r\n * this.todos = [];\r\n * }\r\n * }\r\n *\r\n * wuVanilla.registerClass('todo-app', TodoApp);\r\n */\r\nasync function registerClass(appName, AppClass, options = {}) {\r\n const {\r\n constructorArgs = [],\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#app'\r\n } = options;\r\n\r\n // Función de mount\r\n const mountApp = (container) => {\r\n if (!container) {\r\n console.error(`[WuVanilla] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.instances.has(appName)) {\r\n console.warn(`[WuVanilla] ${appName} already mounted, unmounting first`);\r\n unmountApp();\r\n }\r\n\r\n try {\r\n container.innerHTML = '';\r\n\r\n // Crear instancia de la clase\r\n const instance = new AppClass(container, ...constructorArgs);\r\n\r\n // Llamar render si existe\r\n if (instance.render && typeof instance.render === 'function') {\r\n instance.render();\r\n }\r\n\r\n // Guardar instancia\r\n adapterState.instances.set(appName, {\r\n instance,\r\n container\r\n });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (class) mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, instance);\r\n }\r\n } catch (error) {\r\n console.error(`[WuVanilla] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount\r\n const unmountApp = (container) => {\r\n const appData = adapterState.instances.get(appName);\r\n\r\n if (appData) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(appData.container, appData.instance);\r\n }\r\n\r\n // Llamar destroy si existe\r\n if (appData.instance.destroy && typeof appData.instance.destroy === 'function') {\r\n appData.instance.destroy();\r\n } else {\r\n appData.container.innerHTML = '';\r\n }\r\n\r\n adapterState.instances.delete(appName);\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (class) unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuVanilla] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (class) registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuVanilla] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n console.log(`[WuVanilla] Running ${appName} in standalone mode`);\r\n mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Registra un template HTML como microfrontend\r\n *\r\n * @param {string} appName - Nombre único del microfrontend\r\n * @param {string|Function} template - HTML string o función que retorna HTML\r\n * @param {Object} options - Opciones adicionales\r\n *\r\n * @example\r\n * // Template estático\r\n * wuVanilla.registerTemplate('header', '<header><h1>My Header</h1></header>');\r\n *\r\n * // Template dinámico\r\n * wuVanilla.registerTemplate('greeting', (data) => `<h1>Hello ${data.name}!</h1>`, {\r\n * data: { name: 'World' }\r\n * });\r\n */\r\nasync function registerTemplate(appName, template, options = {}) {\r\n const {\r\n data = {},\r\n scripts = [],\r\n styles = [],\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#app'\r\n } = options;\r\n\r\n const mountApp = (container) => {\r\n if (!container) {\r\n console.error(`[WuVanilla] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n try {\r\n container.innerHTML = '';\r\n\r\n // Inyectar estilos\r\n if (styles.length > 0) {\r\n const styleEl = document.createElement('style');\r\n styleEl.textContent = styles.join('\\n');\r\n styleEl.setAttribute('data-wu-app', appName);\r\n container.appendChild(styleEl);\r\n }\r\n\r\n // Crear wrapper\r\n const wrapper = document.createElement('div');\r\n wrapper.setAttribute('data-wu-template', appName);\r\n\r\n // Renderizar template\r\n if (typeof template === 'function') {\r\n wrapper.innerHTML = template(data);\r\n } else {\r\n wrapper.innerHTML = template;\r\n }\r\n\r\n container.appendChild(wrapper);\r\n\r\n // Ejecutar scripts\r\n scripts.forEach(scriptFn => {\r\n if (typeof scriptFn === 'function') {\r\n scriptFn(container, data);\r\n }\r\n });\r\n\r\n adapterState.apps.set(appName, { container, template, data });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (template) mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, data);\r\n }\r\n } catch (error) {\r\n console.error(`[WuVanilla] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n const unmountApp = (container) => {\r\n const appData = adapterState.apps.get(appName);\r\n\r\n if (appData) {\r\n if (onUnmount) {\r\n onUnmount(appData.container, appData.data);\r\n }\r\n\r\n appData.container.innerHTML = '';\r\n adapterState.apps.delete(appName);\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (template) unmounted successfully`);\r\n }\r\n\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n console.log(`[WuVanilla] ✅ ${appName} (template) registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n console.warn(`[WuVanilla] Wu Framework not available for ${appName}`);\r\n\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n if (containerElement) {\r\n console.log(`[WuVanilla] Running ${appName} in standalone mode`);\r\n mountApp(containerElement);\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Helper para crear un componente reactivo simple\r\n *\r\n * @param {Object} config - Configuración del componente\r\n * @returns {Object} Componente con métodos de estado\r\n *\r\n * @example\r\n * const Counter = wuVanilla.createComponent({\r\n * state: { count: 0 },\r\n * template: (state) => `\r\n * <div>\r\n * <h1>Count: ${state.count}</h1>\r\n * <button data-action=\"increment\">+</button>\r\n * <button data-action=\"decrement\">-</button>\r\n * </div>\r\n * `,\r\n * actions: {\r\n * increment: (state) => ({ count: state.count + 1 }),\r\n * decrement: (state) => ({ count: state.count - 1 })\r\n * }\r\n * });\r\n *\r\n * wuVanilla.register('counter', Counter);\r\n */\r\nfunction createComponent(config) {\r\n const { state: initialState = {}, template, actions = {}, onInit, onDestroy } = config;\r\n\r\n let currentState = { ...initialState };\r\n let container = null;\r\n let mounted = false;\r\n\r\n const setState = (newState) => {\r\n currentState = { ...currentState, ...newState };\r\n if (mounted && container) {\r\n render(container, currentState);\r\n }\r\n };\r\n\r\n const render = (cont, state) => {\r\n const html = template(state);\r\n\r\n // Preservar focus si es posible\r\n const activeId = document.activeElement?.id;\r\n\r\n cont.innerHTML = html;\r\n\r\n // Restaurar focus\r\n if (activeId) {\r\n const el = cont.querySelector(`#${activeId}`);\r\n if (el) el.focus();\r\n }\r\n\r\n // Bind actions\r\n cont.querySelectorAll('[data-action]').forEach(el => {\r\n const actionName = el.getAttribute('data-action');\r\n if (actions[actionName]) {\r\n el.addEventListener('click', () => {\r\n const result = actions[actionName](currentState, el);\r\n if (result) {\r\n setState(result);\r\n }\r\n });\r\n }\r\n });\r\n };\r\n\r\n return {\r\n state: currentState,\r\n\r\n init: (cont) => {\r\n container = cont;\r\n if (onInit) onInit(cont, currentState);\r\n },\r\n\r\n render: (cont, state) => {\r\n container = cont;\r\n currentState = state || currentState;\r\n mounted = true;\r\n render(cont, currentState);\r\n },\r\n\r\n destroy: (cont) => {\r\n if (onDestroy) onDestroy(cont, currentState);\r\n mounted = false;\r\n container = null;\r\n cont.innerHTML = '';\r\n },\r\n\r\n // Exponer setState para uso externo\r\n setState,\r\n getState: () => currentState\r\n };\r\n}\r\n\r\n/**\r\n * Helper para usar eventos de Wu Framework\r\n */\r\nfunction useWuEvents() {\r\n const subscriptions = [];\r\n\r\n return {\r\n emit: (event, data, options) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.emit(event, data, options);\r\n }\r\n },\r\n\r\n on: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n const unsubscribe = wu.eventBus.on(event, callback);\r\n subscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n return () => {};\r\n },\r\n\r\n once: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n return wu.eventBus.once(event, callback);\r\n }\r\n return () => {};\r\n },\r\n\r\n off: (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.off(event, callback);\r\n }\r\n },\r\n\r\n cleanup: () => {\r\n subscriptions.forEach(unsub => unsub());\r\n subscriptions.length = 0;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Helper para usar el Store de Wu Framework\r\n */\r\nfunction useWuStore(namespace = '') {\r\n return {\r\n get: (path = '') => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const fullPath = namespace ? (path ? `${namespace}.${path}` : namespace) : path;\r\n return wu.store.get(fullPath);\r\n }\r\n return null;\r\n },\r\n\r\n set: (path, value) => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const fullPath = namespace ? `${namespace}.${path}` : path;\r\n wu.store.set(fullPath, value);\r\n }\r\n },\r\n\r\n onChange: (pattern, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const fullPattern = namespace ? `${namespace}.${pattern}` : pattern;\r\n return wu.store.on(fullPattern, callback);\r\n }\r\n return () => {};\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Crea un WuSlot en JavaScript puro\r\n */\r\nfunction createWuSlot(target, props) {\r\n const { name, url, fallbackText = null, onLoad = null, onError = null } = props;\r\n\r\n const container = document.createElement('div');\r\n container.className = 'wu-slot';\r\n container.style.cssText = 'min-height: 100px; position: relative;';\r\n container.setAttribute('data-wu-app', name);\r\n container.setAttribute('data-wu-url', url);\r\n\r\n // Loading state\r\n container.innerHTML = `\r\n <div style=\"display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;\">\r\n ${fallbackText || `Loading ${name}...`}\r\n </div>\r\n `;\r\n\r\n target.appendChild(container);\r\n\r\n let appInstance = null;\r\n\r\n const mount = async () => {\r\n try {\r\n const wu = getWuInstance();\r\n if (!wu) throw new Error('Wu Framework not initialized');\r\n\r\n const containerId = `wu-slot-${name}-${Date.now()}`;\r\n const innerContainer = document.createElement('div');\r\n innerContainer.id = containerId;\r\n innerContainer.style.cssText = 'width: 100%; height: 100%;';\r\n\r\n container.innerHTML = '';\r\n container.appendChild(innerContainer);\r\n\r\n const app = wu.app(name, {\r\n url,\r\n container: `#${containerId}`,\r\n autoInit: true\r\n });\r\n\r\n appInstance = app;\r\n await app.mount();\r\n\r\n if (onLoad) onLoad({ name, url });\r\n\r\n } catch (err) {\r\n container.innerHTML = `\r\n <div style=\"padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;\">\r\n <strong>Error loading ${name}</strong>\r\n <p style=\"margin: 0.5rem 0 0 0;\">${err.message}</p>\r\n </div>\r\n `;\r\n if (onError) onError(err);\r\n }\r\n };\r\n\r\n const destroy = async () => {\r\n if (appInstance) {\r\n try {\r\n await appInstance.unmount();\r\n } catch (e) {}\r\n appInstance = null;\r\n }\r\n container.remove();\r\n };\r\n\r\n mount();\r\n\r\n return { container, destroy };\r\n}\r\n\r\n// ============================================\r\n// AI INTEGRATION\r\n// ============================================\r\nimport { useWuAI } from './ai.js';\r\n\r\n// API pública del adapter\r\nexport const wuVanilla = {\r\n register,\r\n registerClass,\r\n registerTemplate,\r\n createComponent,\r\n createWuSlot,\r\n useWuEvents,\r\n useWuStore,\r\n useWuAI,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport {\r\n register,\r\n registerClass,\r\n registerTemplate,\r\n createComponent,\r\n createWuSlot,\r\n useWuEvents,\r\n useWuStore,\r\n useWuAI,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport default wuVanilla;\r\n"],"names":["useWuAI","options","namespace","state","messages","isStreaming","error","send","text","trim","wu","window","parent","top","ai","push","id","Date","now","role","content","timestamp","res","err","message","clear","length","getMessages","getError","adapterState","apps","Map","instances","getWuInstance","waitForWu","timeout","Promise","resolve","reject","startTime","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","async","register","appName","config","render","destroy","init","onMount","onUnmount","standalone","standaloneContainer","appState","mountApp","container","has","console","warn","unmountApp","innerHTML","set","log","appData","get","delete","define","mount","unmount","containerElement","document","querySelector","registerClass","AppClass","constructorArgs","instance","registerTemplate","template","data","scripts","styles","styleEl","createElement","textContent","join","setAttribute","appendChild","wrapper","forEach","scriptFn","createComponent","initialState","actions","onInit","onDestroy","currentState","mounted","setState","newState","cont","html","activeId","activeElement","el","focus","querySelectorAll","actionName","getAttribute","result","getState","useWuEvents","subscriptions","emit","event","eventBus","on","callback","unsubscribe","once","off","unsub","useWuStore","path","store","fullPath","value","onChange","pattern","fullPattern","createWuSlot","target","props","name","url","fallbackText","onLoad","onError","className","style","cssText","appInstance","containerId","innerContainer","app","autoInit","e","remove","wuVanilla"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=new class{constructor(){this.isDevelopment=this.detectEnvironment(),this.logLevel=this.isDevelopment?"warn":"error",this.levels={debug:0,info:1,warn:2,error:3,silent:4}}detectEnvironment(){if("undefined"!=typeof window&&!0===window.WU_DEBUG)return!0;if("undefined"!=typeof window&&!1===window.WU_DEBUG)return!1;if("undefined"!=typeof process&&"production"===process.env?.NODE_ENV)return!1;if("undefined"!=typeof process&&"development"===process.env?.NODE_ENV)return!0;if("undefined"!=typeof window&&window.location){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e||"[::1]"===e)return!0;try{if(new URLSearchParams(window.location.search).has("wu-debug"))return!0}catch{}}return!1}setLevel(e){return this.logLevel=e,this}setDevelopment(e){return this.isDevelopment=e,this.logLevel=e?"debug":"error",this}shouldLog(e){return this.levels[e]>=this.levels[this.logLevel]}debug(...e){this.shouldLog("debug")&&console.log(...e)}info(...e){this.shouldLog("info")&&console.info(...e)}warn(...e){this.shouldLog("warn")&&console.warn(...e)}error(...e){this.shouldLog("error")&&console.error(...e)}wu(e,...n){if(this.shouldLog(e)){console["debug"===e?"log":e]("[Wu]",...n)}}wuDebug(...e){this.wu("debug",...e)}wuInfo(...e){this.wu("info",...e)}wuWarn(...e){this.wu("warn",...e)}wuError(...e){this.wu("error",...e)}};function n(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function t(e){const{ref:t}=e;return function(e={}){const{namespace:o="default"}=e,r=t([]),a=t(!1),i=t(null);return{messages:r,isStreaming:a,error:i,send:async function(e){if(!e?.trim())return;const t=n();if(t?.ai){r.value=[...r.value,{id:`user-${Date.now()}`,role:"user",content:e,timestamp:Date.now()}],i.value=null,a.value=!0;try{const n=await t.ai.send(e,{namespace:o});r.value=[...r.value,{id:`assistant-${Date.now()}`,role:"assistant",content:n.content,timestamp:Date.now()}]}catch(e){i.value=e.message||"AI request failed"}a.value=!1}else i.value="Wu AI not available"},clear:function(){r.value=[],i.value=null}}}}function o(e={}){const{namespace:t="default"}=e,o={messages:[],isStreaming:!1,error:null};return{...o,async send(e){if(!e?.trim())return null;const r=n();if(!r?.ai)return o.error="Wu AI not available",null;o.messages.push({id:`user-${Date.now()}`,role:"user",content:e,timestamp:Date.now()}),o.isStreaming=!0,o.error=null;try{const n=await r.ai.send(e,{namespace:t});return o.messages.push({id:`assistant-${Date.now()}`,role:"assistant",content:n.content,timestamp:Date.now()}),o.isStreaming=!1,n}catch(e){return o.error=e.message,o.isStreaming=!1,null}},clear(){o.messages.length=0,o.error=null}}}const r={apps:new Map,Vue:null,createApp:null,initialized:!1};function a(){return"undefined"==typeof window?null:window.wu||window.parent?.wu||window.top?.wu||null}function i(e=5e3){return new Promise((n,t)=>{const o=a();if(o)return void n(o);const r=Date.now(),i=()=>{s(),n(a())};window.addEventListener("wu:ready",i),window.addEventListener("wu:app:ready",i);const u=setInterval(()=>{const o=a();if(o)return s(),void n(o);Date.now()-r>e&&(s(),t(new Error(`Wu Framework not found after ${e}ms`)))},200);function s(){clearInterval(u),window.removeEventListener("wu:ready",i),window.removeEventListener("wu:app:ready",i)}})}async function u(n,t,o={}){const{setup:u=null,props:s={},onMount:l=null,onUnmount:c=null,standalone:d=!0,standaloneContainer:p="#app"}=o;if(!await async function(){if(r.initialized)return!0;try{if("undefined"!=typeof window&&window.Vue)return r.Vue=window.Vue,r.createApp=window.Vue.createApp,r.initialized=!0,!0;const e=await import("vue");return r.Vue=e,r.createApp=e.createApp,r.initialized=!0,!0}catch(e){return console.error("[WuVue] Failed to load Vue:",e),!1}}())return console.error(`[WuVue] Cannot register ${n}: Vue not available`),!1;const{createApp:w}=r,f=o=>{if(o){r.apps.has(n)&&(e.warn(`[WuVue] ${n} already mounted, unmounting first`),m());try{let i=null,c=o;for(;c&&c!==document.body;){if(c.getRootNode&&c.getRootNode()instanceof ShadowRoot){i=c.getRootNode();break}c=c.parentElement||c.host}const d=w(t,s);u&&"function"==typeof u&&u(d),d.config.errorHandler=(e,t,o)=>{console.error(`[WuVue] ${n} error in ${o}:`,e)},d.config.warnHandler=(e,t,o)=>{console.warn(`[WuVue] ${n} warn:`,e)},d.provide("wuAppName",n),d.provide("wuInstance",a()),d.mount(o),i&&setTimeout(()=>{document.querySelectorAll('style[data-vite-dev-id*="/'+n+'/"], style[data-vite-dev-id*="\\'+n+'\\"]').forEach(n=>{const t=n.getAttribute("data-vite-dev-id");if(t&&!i.querySelector(`style[data-vite-dev-id="${t}"]`)){const o=n.cloneNode(!0);i.insertBefore(o,i.firstChild),e.debug(`[WuVue] ✅ Injected style into Shadow DOM: ${t}`)}});document.querySelectorAll("style[data-vite-dev-id]").forEach(t=>{const o=t.getAttribute("data-vite-dev-id");if(o&&(o.includes(`/${n}/`)||o.includes(`\\${n}\\`))&&!i.querySelector(`style[data-vite-dev-id="${o}"]`)){const n=t.cloneNode(!0);i.insertBefore(n,i.firstChild),e.debug(`[WuVue] ✅ Injected app style into Shadow DOM: ${o}`)}})},100),r.apps.set(n,{app:d,container:o}),e.debug(`[WuVue] ✅ ${n} mounted successfully`),l&&l(o,d)}catch(e){throw console.error(`[WuVue] Mount error for ${n}:`,e),e}}else console.error(`[WuVue] Mount failed for ${n}: container is null`)},m=t=>{const o=r.apps.get(n);if(o)try{c&&c(o.container,o.app),o.app.unmount(),r.apps.delete(n),e.debug(`[WuVue] ✅ ${n} unmounted successfully`)}catch(e){console.error(`[WuVue] Unmount error for ${n}:`,e)}t&&(t.innerHTML="")};try{return(await i(3e3)).define(n,{mount:f,unmount:m}),e.debug(`[WuVue] ✅ ${n} registered with Wu Framework`),!0}catch(t){if(e.warn(`[WuVue] Wu Framework not available for ${n}`),d){const t=document.querySelector(p);if(t)return e.debug(`[WuVue] Running ${n} in standalone mode`),f(t),!0;e.warn(`[WuVue] Standalone container ${p} not found`)}return!1}}const s={name:"WuSlot",props:{name:{type:String,required:!0},url:{type:String,required:!0},appName:{type:String,default:null},fallbackText:{type:String,default:"Loading..."}},emits:["load","error","mount","unmount"],data:()=>({loading:!0,error:null,appInstance:null,containerId:null}),computed:{actualAppName(){return this.appName||this.name}},async mounted(){await this.mountMicrofrontend()},beforeUnmount(){this.unmountMicrofrontend()},methods:{async mountMicrofrontend(){try{this.loading=!0,this.error=null;const e=a();if(!e)throw new Error("Wu Framework not initialized");this.containerId=`wu-slot-${this.actualAppName}-${Date.now()}`;const n=document.createElement("div");n.id=this.containerId,n.style.width="100%",n.style.height="100%",this.$refs.container.innerHTML="",this.$refs.container.appendChild(n);const t=e.app(this.actualAppName,{url:this.url,container:`#${this.containerId}`,autoInit:!0});this.appInstance=t,await t.mount(),this.loading=!1,this.$emit("load",{name:this.actualAppName,url:this.url}),this.$emit("mount",{name:this.actualAppName,container:n})}catch(e){console.error(`[WuSlot] Error loading ${this.actualAppName}:`,e),this.error=e.message||"Failed to load microfrontend",this.loading=!1,this.$emit("error",e)}},async unmountMicrofrontend(){if(this.appInstance){this.$emit("unmount",{name:this.actualAppName});try{await this.appInstance.unmount()}catch(n){e.warn(`[WuSlot] Error unmounting ${this.actualAppName}:`,n)}this.appInstance=null}}},template:'\n <div\n ref="container"\n class="wu-slot"\n :class="{ \'wu-slot-loading\': loading, \'wu-slot-error\': error }"\n :data-wu-app="actualAppName"\n :data-wu-url="url"\n style="min-height: 100px; position: relative;"\n >\n <div v-if="error" class="wu-slot-error-message" style="padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;">\n <strong>Error loading {{ name }}</strong>\n <p style="margin: 0.5rem 0 0 0;">{{ error }}</p>\n </div>\n <div v-else-if="loading" class="wu-slot-loading-message" style="display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;">\n {{ fallbackText || \'Loading \' + name + \'...\' }}\n </div>\n </div>\n '};function l(){const n=[];return{emit:(n,t,o)=>{const r=a();r?.eventBus?r.eventBus.emit(n,t,o):e.warn("[useWuEvents] Wu Framework not available")},on:(t,o)=>{const r=a();if(r?.eventBus){const e=r.eventBus.on(t,o);return n.push(e),e}return e.warn("[useWuEvents] Wu Framework not available"),()=>{}},once:(n,t)=>{const o=a();return o?.eventBus?o.eventBus.once(n,t):(e.warn("[useWuEvents] Wu Framework not available"),()=>{})},off:(e,n)=>{const t=a();t?.eventBus&&t.eventBus.off(e,n)},cleanup:()=>{n.forEach(e=>e()),n.length=0}}}function c(e=""){const n=r.Vue;let t,o=null;if(n?.ref){const r=a(),i=r?.store?.get(e)||null;if(t=n.ref(i),r?.store){const n=e?`${e}.*`:"*";o=r.store.on(n,()=>{t.value=r.store.get(e)})}}else t={value:null};return{state:t,setState:(n,t)=>{const o=a();if(o?.store){const r=e?`${e}.${n}`:n;o.store.set(r,t)}},getState:(n="")=>{const t=a();if(t?.store){const o=e?n?`${e}.${n}`:e:n;return t.store.get(o)}return null},cleanup:()=>{o&&(o(),o=null)}}}const d={install(n,t={}){n.component("WuSlot",s),n.provide("wu",a()),n.config.globalProperties.$wu=a(),n.config.globalProperties.$wuEvents=l(),n.config.globalProperties.$wuStore=e=>c(e),e.debug("[WuVue] Plugin installed")}},p={register:u,WuSlot:s,useWuEvents:l,useWuStore:c,wuVuePlugin:d,createUseWuAI:t,useWuAI:o,getWuInstance:a,waitForWu:i};export{s as WuSlot,t as createUseWuAI,p as default,a as getWuInstance,u as register,o as useWuAI,l as useWuEvents,c as useWuStore,i as waitForWu,p as wuVue,d as wuVuePlugin};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/core/wu-logger.js","../../../src/adapters/vue/ai.js","../../../src/adapters/vue/index.js"],"sourcesContent":["/**\r\n * 📝 WU-LOGGER: Sistema de logging inteligente para entornos\r\n * Controla los logs automáticamente según el entorno\r\n */\r\n\r\nexport class WuLogger {\r\n constructor() {\r\n // Detectar entorno automáticamente\r\n this.isDevelopment = this.detectEnvironment();\r\n // En desarrollo: warn (menos ruido), en producción: error\r\n this.logLevel = this.isDevelopment ? 'warn' : 'error';\r\n\r\n this.levels = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n silent: 4\r\n };\r\n }\r\n\r\n /**\r\n * Detectar si estamos en desarrollo\r\n */\r\n detectEnvironment() {\r\n // 1. Explicit flag takes priority\r\n if (typeof window !== 'undefined' && window.WU_DEBUG === true) return true;\r\n if (typeof window !== 'undefined' && window.WU_DEBUG === false) return false;\r\n\r\n // 2. NODE_ENV check (works in bundlers and Node)\r\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') return false;\r\n if (typeof process !== 'undefined' && process.env?.NODE_ENV === 'development') return true;\r\n\r\n // 3. Browser heuristics (only if window exists)\r\n if (typeof window !== 'undefined' && window.location) {\r\n const hostname = window.location.hostname;\r\n if (hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]') return true;\r\n\r\n // URL param override\r\n try {\r\n if (new URLSearchParams(window.location.search).has('wu-debug')) return true;\r\n } catch {}\r\n }\r\n\r\n // 4. Default: assume production\r\n return false;\r\n }\r\n\r\n /**\r\n * Configurar nivel de logging\r\n */\r\n setLevel(level) {\r\n this.logLevel = level;\r\n return this;\r\n }\r\n\r\n /**\r\n * Habilitar/deshabilitar development mode\r\n */\r\n setDevelopment(isDev) {\r\n this.isDevelopment = isDev;\r\n this.logLevel = isDev ? 'debug' : 'error';\r\n return this;\r\n }\r\n\r\n /**\r\n * Verificar si debemos mostrar el log\r\n */\r\n shouldLog(level) {\r\n return this.levels[level] >= this.levels[this.logLevel];\r\n }\r\n\r\n /**\r\n * Logging methods\r\n */\r\n debug(...args) {\r\n if (this.shouldLog('debug')) {\r\n console.log(...args);\r\n }\r\n }\r\n\r\n info(...args) {\r\n if (this.shouldLog('info')) {\r\n console.info(...args);\r\n }\r\n }\r\n\r\n warn(...args) {\r\n if (this.shouldLog('warn')) {\r\n console.warn(...args);\r\n }\r\n }\r\n\r\n error(...args) {\r\n if (this.shouldLog('error')) {\r\n console.error(...args);\r\n }\r\n }\r\n\r\n /**\r\n * Logging con contexto Wu\r\n */\r\n wu(level, ...args) {\r\n if (this.shouldLog(level)) {\r\n const method = level === 'debug' ? 'log' : level;\r\n console[method]('[Wu]', ...args);\r\n }\r\n }\r\n\r\n /**\r\n * Helper methods específicos para Wu\r\n */\r\n wuDebug(...args) { this.wu('debug', ...args); }\r\n wuInfo(...args) { this.wu('info', ...args); }\r\n wuWarn(...args) { this.wu('warn', ...args); }\r\n wuError(...args) { this.wu('error', ...args); }\r\n}\r\n\r\n// Singleton instance\r\nexport const logger = new WuLogger();\r\n\r\n// Helper para compatibilidad con logs existentes\r\nexport const wuLog = {\r\n debug: (...args) => logger.wuDebug(...args),\r\n info: (...args) => logger.wuInfo(...args),\r\n warn: (...args) => logger.wuWarn(...args),\r\n error: (...args) => logger.wuError(...args)\r\n};\r\n\r\n/**\r\n * 🔇 Silenciar todos los logs de Wu Framework\r\n * Útil en producción para eliminar todo el ruido\r\n */\r\nexport function silenceAllLogs() {\r\n logger.setLevel('silent');\r\n}\r\n\r\n/**\r\n * 🔊 Restaurar logs (nivel debug)\r\n */\r\nexport function enableAllLogs() {\r\n logger.setLevel('debug');\r\n}","/**\r\n * WU-FRAMEWORK VUE AI INTEGRATION\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n return window.wu || window.parent?.wu || window.top?.wu || null;\r\n}\r\n\r\nexport function createUseWuAI(Vue) {\r\n const { ref } = Vue;\r\n return function useWuAI(options = {}) {\r\n const { namespace = 'default' } = options;\r\n const messages = ref([]);\r\n const isStreaming = ref(false);\r\n const error = ref(null);\r\n async function send(text) {\r\n if (!text?.trim()) return;\r\n const wu = getWuInstance();\r\n if (!wu?.ai) { error.value = 'Wu AI not available'; return; }\r\n messages.value = [...messages.value, { id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now() }];\r\n error.value = null; isStreaming.value = true;\r\n try {\r\n const res = await wu.ai.send(text, { namespace });\r\n messages.value = [...messages.value, { id: `assistant-${Date.now()}`, role: 'assistant', content: res.content, timestamp: Date.now() }];\r\n } catch (err) { error.value = err.message || 'AI request failed'; }\r\n isStreaming.value = false;\r\n }\r\n function clear() { messages.value = []; error.value = null; }\r\n return { messages, isStreaming, error, send, clear };\r\n };\r\n}\r\n\r\nexport function useWuAI(options = {}) {\r\n const { namespace = 'default' } = options;\r\n const state = { messages: [], isStreaming: false, error: null };\r\n return {\r\n ...state,\r\n async send(text) {\r\n if (!text?.trim()) return null;\r\n const wu = getWuInstance();\r\n if (!wu?.ai) { state.error = 'Wu AI not available'; return null; }\r\n state.messages.push({ id: `user-${Date.now()}`, role: 'user', content: text, timestamp: Date.now() });\r\n state.isStreaming = true; state.error = null;\r\n try {\r\n const res = await wu.ai.send(text, { namespace });\r\n state.messages.push({ id: `assistant-${Date.now()}`, role: 'assistant', content: res.content, timestamp: Date.now() });\r\n state.isStreaming = false; return res;\r\n } catch (err) { state.error = err.message; state.isStreaming = false; return null; }\r\n },\r\n clear() { state.messages.length = 0; state.error = null; },\r\n };\r\n}\r\n","/**\r\n * 🚀 WU-FRAMEWORK VUE ADAPTER\r\n *\r\n * Simplifica la integración de Vue 3 con Wu Framework.\r\n * Convierte componentes Vue en microfrontends con UNA línea de código.\r\n *\r\n * @example\r\n * // Microfrontend (main.ts)\r\n * import { wuVue } from 'wu-framework/adapters/vue';\r\n * import App from './App.vue';\r\n *\r\n * wuVue.register('my-app', App);\r\n *\r\n * @example\r\n * // Shell (cargar microfrontend)\r\n * import { WuSlot } from 'wu-framework/adapters/vue';\r\n *\r\n * <WuSlot name=\"my-app\" url=\"http://localhost:3001\" />\r\n */\r\n\r\nimport { logger } from '../../core/wu-logger.js';\r\n\r\n// Estado global del adapter\r\nconst adapterState = {\r\n apps: new Map(),\r\n Vue: null,\r\n createApp: null,\r\n initialized: false\r\n};\r\n\r\n/**\r\n * Detecta y obtiene Vue del contexto global o lo importa\r\n */\r\nasync function ensureVue() {\r\n if (adapterState.initialized) return true;\r\n\r\n try {\r\n // Intentar obtener de window\r\n if (typeof window !== 'undefined' && window.Vue) {\r\n adapterState.Vue = window.Vue;\r\n adapterState.createApp = window.Vue.createApp;\r\n adapterState.initialized = true;\r\n return true;\r\n }\r\n\r\n // Intentar import dinámico\r\n const Vue = await import('vue');\r\n adapterState.Vue = Vue;\r\n adapterState.createApp = Vue.createApp;\r\n adapterState.initialized = true;\r\n return true;\r\n\r\n } catch (error) {\r\n console.error('[WuVue] Failed to load Vue:', error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Obtiene la instancia de Wu Framework\r\n */\r\nfunction getWuInstance() {\r\n if (typeof window === 'undefined') return null;\r\n\r\n return window.wu\r\n || window.parent?.wu\r\n || window.top?.wu\r\n || null;\r\n}\r\n\r\n/**\r\n * Espera a que Wu Framework esté disponible\r\n */\r\nfunction waitForWu(timeout = 5000) {\r\n return new Promise((resolve, reject) => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n const startTime = Date.now();\r\n\r\n const handleWuReady = () => {\r\n cleanup();\r\n resolve(getWuInstance());\r\n };\r\n\r\n window.addEventListener('wu:ready', handleWuReady);\r\n window.addEventListener('wu:app:ready', handleWuReady);\r\n\r\n const checkInterval = setInterval(() => {\r\n const wu = getWuInstance();\r\n if (wu) {\r\n cleanup();\r\n resolve(wu);\r\n return;\r\n }\r\n\r\n if (Date.now() - startTime > timeout) {\r\n cleanup();\r\n reject(new Error(`Wu Framework not found after ${timeout}ms`));\r\n }\r\n }, 200);\r\n\r\n function cleanup() {\r\n clearInterval(checkInterval);\r\n window.removeEventListener('wu:ready', handleWuReady);\r\n window.removeEventListener('wu:app:ready', handleWuReady);\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Registra un componente Vue como microfrontend\r\n *\r\n * @param {string} appName - Nombre único del microfrontend (debe coincidir con wu.json)\r\n * @param {Object} RootComponent - Componente Vue principal (App.vue)\r\n * @param {Object} options - Opciones adicionales\r\n * @param {Function} options.setup - Función para configurar la app Vue (plugins, router, etc.)\r\n * @param {Object} options.props - Props iniciales para el componente\r\n * @param {Function} options.onMount - Callback después de montar\r\n * @param {Function} options.onUnmount - Callback antes de desmontar\r\n * @param {boolean} options.standalone - Permitir ejecución standalone (default: true)\r\n * @param {string} options.standaloneContainer - Selector para modo standalone (default: '#app')\r\n *\r\n * @example\r\n * // Básico\r\n * wuVue.register('my-app', App);\r\n *\r\n * @example\r\n * // Con plugins (Pinia, Router, etc.)\r\n * wuVue.register('my-app', App, {\r\n * setup: (app) => {\r\n * app.use(createPinia());\r\n * app.use(router);\r\n * app.component('MyGlobal', MyComponent);\r\n * }\r\n * });\r\n */\r\nasync function register(appName, RootComponent, options = {}) {\r\n const {\r\n setup = null,\r\n props = {},\r\n onMount = null,\r\n onUnmount = null,\r\n standalone = true,\r\n standaloneContainer = '#app'\r\n } = options;\r\n\r\n // Asegurar que Vue está disponible\r\n const hasVue = await ensureVue();\r\n if (!hasVue) {\r\n console.error(`[WuVue] Cannot register ${appName}: Vue not available`);\r\n return false;\r\n }\r\n\r\n const { createApp } = adapterState;\r\n\r\n // Función de mount interna\r\n const mountApp = (container) => {\r\n if (!container) {\r\n console.error(`[WuVue] Mount failed for ${appName}: container is null`);\r\n return;\r\n }\r\n\r\n // Evitar doble mount\r\n if (adapterState.apps.has(appName)) {\r\n logger.warn(`[WuVue] ${appName} already mounted, unmounting first`);\r\n unmountApp();\r\n }\r\n\r\n try {\r\n // Detectar si el container está dentro de un Shadow DOM\r\n let shadowRoot = null;\r\n let element = container;\r\n while (element && element !== document.body) {\r\n if (element.getRootNode && element.getRootNode() instanceof ShadowRoot) {\r\n shadowRoot = element.getRootNode();\r\n break;\r\n }\r\n element = element.parentElement || element.host;\r\n }\r\n\r\n // Crear la aplicación Vue\r\n const app = createApp(RootComponent, props);\r\n\r\n // Ejecutar setup personalizado (plugins, router, etc.)\r\n if (setup && typeof setup === 'function') {\r\n setup(app);\r\n }\r\n\r\n // Error handlers for debugging\r\n app.config.errorHandler = (err, instance, info) => {\r\n console.error(`[WuVue] ${appName} error in ${info}:`, err);\r\n };\r\n app.config.warnHandler = (msg, instance, trace) => {\r\n console.warn(`[WuVue] ${appName} warn:`, msg);\r\n };\r\n\r\n // Proveer información del contexto Wu\r\n app.provide('wuAppName', appName);\r\n app.provide('wuInstance', getWuInstance());\r\n\r\n // Montar\r\n app.mount(container);\r\n\r\n // Si está en Shadow DOM, copiar estilos de Vue al Shadow DOM\r\n if (shadowRoot) {\r\n // Esperar un poco para que Vue inyecte los estilos en el head\r\n setTimeout(() => {\r\n const vueStyles = document.querySelectorAll('style[data-vite-dev-id*=\"/' + appName + '/\"], style[data-vite-dev-id*=\"\\\\' + appName + '\\\\\"]');\r\n vueStyles.forEach(style => {\r\n // Verificar que no esté ya en el Shadow DOM\r\n const viteId = style.getAttribute('data-vite-dev-id');\r\n if (viteId && !shadowRoot.querySelector(`style[data-vite-dev-id=\"${viteId}\"]`)) {\r\n const clonedStyle = style.cloneNode(true);\r\n shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);\r\n logger.debug(`[WuVue] ✅ Injected style into Shadow DOM: ${viteId}`);\r\n }\r\n });\r\n\r\n // También copiar estilos que contengan rutas del app en el viteId\r\n const allStyles = document.querySelectorAll('style[data-vite-dev-id]');\r\n allStyles.forEach(style => {\r\n const viteId = style.getAttribute('data-vite-dev-id');\r\n if (viteId && (viteId.includes(`/${appName}/`) || viteId.includes(`\\\\${appName}\\\\`))) {\r\n if (!shadowRoot.querySelector(`style[data-vite-dev-id=\"${viteId}\"]`)) {\r\n const clonedStyle = style.cloneNode(true);\r\n shadowRoot.insertBefore(clonedStyle, shadowRoot.firstChild);\r\n logger.debug(`[WuVue] ✅ Injected app style into Shadow DOM: ${viteId}`);\r\n }\r\n }\r\n });\r\n }, 100);\r\n }\r\n\r\n // Guardar referencia\r\n adapterState.apps.set(appName, { app, container });\r\n\r\n logger.debug(`[WuVue] ✅ ${appName} mounted successfully`);\r\n\r\n if (onMount) {\r\n onMount(container, app);\r\n }\r\n } catch (error) {\r\n console.error(`[WuVue] Mount error for ${appName}:`, error);\r\n throw error;\r\n }\r\n };\r\n\r\n // Función de unmount interna\r\n const unmountApp = (container) => {\r\n const instance = adapterState.apps.get(appName);\r\n\r\n if (instance) {\r\n try {\r\n if (onUnmount) {\r\n onUnmount(instance.container, instance.app);\r\n }\r\n\r\n instance.app.unmount();\r\n adapterState.apps.delete(appName);\r\n\r\n logger.debug(`[WuVue] ✅ ${appName} unmounted successfully`);\r\n } catch (error) {\r\n console.error(`[WuVue] Unmount error for ${appName}:`, error);\r\n }\r\n }\r\n\r\n // Limpiar container si se proporciona\r\n if (container) {\r\n container.innerHTML = '';\r\n }\r\n };\r\n\r\n // Intentar registrar con Wu Framework\r\n try {\r\n const wu = await waitForWu(3000);\r\n\r\n wu.define(appName, {\r\n mount: mountApp,\r\n unmount: unmountApp\r\n });\r\n\r\n logger.debug(`[WuVue] ✅ ${appName} registered with Wu Framework`);\r\n return true;\r\n\r\n } catch (error) {\r\n logger.warn(`[WuVue] Wu Framework not available for ${appName}`);\r\n\r\n // Modo standalone si está habilitado\r\n if (standalone) {\r\n const containerElement = document.querySelector(standaloneContainer);\r\n\r\n if (containerElement) {\r\n logger.debug(`[WuVue] Running ${appName} in standalone mode`);\r\n mountApp(containerElement);\r\n return true;\r\n } else {\r\n logger.warn(`[WuVue] Standalone container ${standaloneContainer} not found`);\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Crea un componente Vue para cargar microfrontends (para el Shell)\r\n *\r\n * @example\r\n * <script setup>\r\n * import { WuSlot } from 'wu-framework/adapters/vue';\r\n * </script>\r\n *\r\n * <template>\r\n * <WuSlot name=\"my-app\" url=\"http://localhost:3001\" />\r\n * </template>\r\n */\r\nconst WuSlot = {\r\n name: 'WuSlot',\r\n\r\n props: {\r\n name: {\r\n type: String,\r\n required: true\r\n },\r\n url: {\r\n type: String,\r\n required: true\r\n },\r\n appName: {\r\n type: String,\r\n default: null\r\n },\r\n fallbackText: {\r\n type: String,\r\n default: 'Loading...'\r\n }\r\n },\r\n\r\n emits: ['load', 'error', 'mount', 'unmount'],\r\n\r\n data() {\r\n return {\r\n loading: true,\r\n error: null,\r\n appInstance: null,\r\n containerId: null\r\n };\r\n },\r\n\r\n computed: {\r\n actualAppName() {\r\n return this.appName || this.name;\r\n }\r\n },\r\n\r\n async mounted() {\r\n await this.mountMicrofrontend();\r\n },\r\n\r\n beforeUnmount() {\r\n this.unmountMicrofrontend();\r\n },\r\n\r\n methods: {\r\n async mountMicrofrontend() {\r\n try {\r\n this.loading = true;\r\n this.error = null;\r\n\r\n const wu = getWuInstance();\r\n if (!wu) {\r\n throw new Error('Wu Framework not initialized');\r\n }\r\n\r\n // Crear container único\r\n this.containerId = `wu-slot-${this.actualAppName}-${Date.now()}`;\r\n const innerContainer = document.createElement('div');\r\n innerContainer.id = this.containerId;\r\n innerContainer.style.width = '100%';\r\n innerContainer.style.height = '100%';\r\n\r\n this.$refs.container.innerHTML = '';\r\n this.$refs.container.appendChild(innerContainer);\r\n\r\n // Crear y montar la app\r\n const app = wu.app(this.actualAppName, {\r\n url: this.url,\r\n container: `#${this.containerId}`,\r\n autoInit: true\r\n });\r\n\r\n this.appInstance = app;\r\n await app.mount();\r\n\r\n this.loading = false;\r\n this.$emit('load', { name: this.actualAppName, url: this.url });\r\n this.$emit('mount', { name: this.actualAppName, container: innerContainer });\r\n\r\n } catch (err) {\r\n console.error(`[WuSlot] Error loading ${this.actualAppName}:`, err);\r\n this.error = err.message || 'Failed to load microfrontend';\r\n this.loading = false;\r\n this.$emit('error', err);\r\n }\r\n },\r\n\r\n async unmountMicrofrontend() {\r\n if (this.appInstance) {\r\n this.$emit('unmount', { name: this.actualAppName });\r\n\r\n try {\r\n await this.appInstance.unmount();\r\n } catch (err) {\r\n logger.warn(`[WuSlot] Error unmounting ${this.actualAppName}:`, err);\r\n }\r\n\r\n this.appInstance = null;\r\n }\r\n }\r\n },\r\n\r\n template: `\r\n <div\r\n ref=\"container\"\r\n class=\"wu-slot\"\r\n :class=\"{ 'wu-slot-loading': loading, 'wu-slot-error': error }\"\r\n :data-wu-app=\"actualAppName\"\r\n :data-wu-url=\"url\"\r\n style=\"min-height: 100px; position: relative;\"\r\n >\r\n <div v-if=\"error\" class=\"wu-slot-error-message\" style=\"padding: 1rem; border: 1px solid #f5c6cb; border-radius: 4px; background: #f8d7da; color: #721c24;\">\r\n <strong>Error loading {{ name }}</strong>\r\n <p style=\"margin: 0.5rem 0 0 0;\">{{ error }}</p>\r\n </div>\r\n <div v-else-if=\"loading\" class=\"wu-slot-loading-message\" style=\"display: flex; align-items: center; justify-content: center; padding: 2rem; color: #666;\">\r\n {{ fallbackText || 'Loading ' + name + '...' }}\r\n </div>\r\n </div>\r\n `\r\n};\r\n\r\n/**\r\n * Composable para usar el EventBus de Wu Framework en Vue 3\r\n *\r\n * @example\r\n * <script setup>\r\n * import { useWuEvents } from 'wu-framework/adapters/vue';\r\n *\r\n * const { emit, on } = useWuEvents();\r\n *\r\n * onMounted(() => {\r\n * on('user:login', (data) => logger.debug(data));\r\n * });\r\n * </script>\r\n */\r\nfunction useWuEvents() {\r\n const subscriptions = [];\r\n\r\n const emit = (event, data, options) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.emit(event, data, options);\r\n } else {\r\n logger.warn('[useWuEvents] Wu Framework not available');\r\n }\r\n };\r\n\r\n const on = (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n const unsubscribe = wu.eventBus.on(event, callback);\r\n subscriptions.push(unsubscribe);\r\n return unsubscribe;\r\n }\r\n logger.warn('[useWuEvents] Wu Framework not available');\r\n return () => {};\r\n };\r\n\r\n const once = (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n return wu.eventBus.once(event, callback);\r\n }\r\n logger.warn('[useWuEvents] Wu Framework not available');\r\n return () => {};\r\n };\r\n\r\n const off = (event, callback) => {\r\n const wu = getWuInstance();\r\n if (wu?.eventBus) {\r\n wu.eventBus.off(event, callback);\r\n }\r\n };\r\n\r\n // Cleanup - llamar en onUnmounted\r\n const cleanup = () => {\r\n subscriptions.forEach(unsub => unsub());\r\n subscriptions.length = 0;\r\n };\r\n\r\n return { emit, on, once, off, cleanup };\r\n}\r\n\r\n/**\r\n * Composable para usar el Store de Wu Framework en Vue 3\r\n *\r\n * @example\r\n * <script setup>\r\n * import { useWuStore } from 'wu-framework/adapters/vue';\r\n *\r\n * const { state, setState, getState } = useWuStore('user');\r\n *\r\n * // state es reactivo!\r\n * logger.debug(state.value);\r\n * </script>\r\n */\r\nfunction useWuStore(namespace = '') {\r\n // Importar ref y watch de Vue si están disponibles\r\n const Vue = adapterState.Vue;\r\n let state;\r\n let unsubscribe = null;\r\n\r\n // Crear estado reactivo si Vue está disponible\r\n if (Vue?.ref) {\r\n const wu = getWuInstance();\r\n const initialValue = wu?.store?.get(namespace) || null;\r\n state = Vue.ref(initialValue);\r\n\r\n // Suscribirse a cambios\r\n if (wu?.store) {\r\n const pattern = namespace ? `${namespace}.*` : '*';\r\n unsubscribe = wu.store.on(pattern, () => {\r\n state.value = wu.store.get(namespace);\r\n });\r\n }\r\n } else {\r\n // Fallback sin reactividad\r\n state = { value: null };\r\n }\r\n\r\n const setState = (path, value) => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const fullPath = namespace ? `${namespace}.${path}` : path;\r\n wu.store.set(fullPath, value);\r\n }\r\n };\r\n\r\n const getState = (path = '') => {\r\n const wu = getWuInstance();\r\n if (wu?.store) {\r\n const fullPath = namespace ? (path ? `${namespace}.${path}` : namespace) : path;\r\n return wu.store.get(fullPath);\r\n }\r\n return null;\r\n };\r\n\r\n const cleanup = () => {\r\n if (unsubscribe) {\r\n unsubscribe();\r\n unsubscribe = null;\r\n }\r\n };\r\n\r\n return { state, setState, getState, cleanup };\r\n}\r\n\r\n/**\r\n * Plugin de Vue para instalar Wu Framework globalmente\r\n *\r\n * @example\r\n * import { createApp } from 'vue';\r\n * import { wuVuePlugin } from 'wu-framework/adapters/vue';\r\n *\r\n * const app = createApp(App);\r\n * app.use(wuVuePlugin);\r\n */\r\nconst wuVuePlugin = {\r\n install(app, options = {}) {\r\n // Registrar componente WuSlot globalmente\r\n app.component('WuSlot', WuSlot);\r\n\r\n // Proveer acceso global a Wu\r\n app.provide('wu', getWuInstance());\r\n\r\n // Agregar propiedades globales\r\n app.config.globalProperties.$wu = getWuInstance();\r\n app.config.globalProperties.$wuEvents = useWuEvents();\r\n app.config.globalProperties.$wuStore = (ns) => useWuStore(ns);\r\n\r\n logger.debug('[WuVue] Plugin installed');\r\n }\r\n};\r\n\r\n// ============================================\r\n// AI INTEGRATION\r\n// ============================================\r\nimport { createUseWuAI, useWuAI } from './ai.js';\r\n\r\n// API pública del adapter\r\nexport const wuVue = {\r\n register,\r\n WuSlot,\r\n useWuEvents,\r\n useWuStore,\r\n wuVuePlugin,\r\n createUseWuAI,\r\n useWuAI,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport {\r\n register,\r\n WuSlot,\r\n useWuEvents,\r\n useWuStore,\r\n wuVuePlugin,\r\n createUseWuAI,\r\n useWuAI,\r\n getWuInstance,\r\n waitForWu\r\n};\r\n\r\nexport default wuVue;\r\n"],"names":["logger","constructor","this","isDevelopment","detectEnvironment","logLevel","levels","debug","info","warn","error","silent","window","WU_DEBUG","process","env","NODE_ENV","location","hostname","URLSearchParams","search","has","setLevel","level","setDevelopment","isDev","shouldLog","args","console","log","wu","wuDebug","wuInfo","wuWarn","wuError","getWuInstance","parent","top","createUseWuAI","Vue","ref","options","namespace","messages","isStreaming","send","async","text","trim","ai","value","id","Date","now","role","content","timestamp","res","err","message","clear","useWuAI","state","push","length","adapterState","apps","Map","createApp","initialized","waitForWu","timeout","Promise","resolve","reject","startTime","handleWuReady","cleanup","addEventListener","checkInterval","setInterval","Error","clearInterval","removeEventListener","register","appName","RootComponent","setup","props","onMount","onUnmount","standalone","standaloneContainer","import","ensureVue","mountApp","container","unmountApp","shadowRoot","element","document","body","getRootNode","ShadowRoot","parentElement","host","app","config","errorHandler","instance","warnHandler","msg","trace","provide","mount","setTimeout","querySelectorAll","forEach","style","viteId","getAttribute","querySelector","clonedStyle","cloneNode","insertBefore","firstChild","includes","set","get","unmount","delete","innerHTML","define","containerElement","WuSlot","name","type","String","required","url","default","fallbackText","emits","data","loading","appInstance","containerId","computed","actualAppName","mounted","mountMicrofrontend","beforeUnmount","unmountMicrofrontend","methods","innerContainer","createElement","width","height","$refs","appendChild","autoInit","$emit","template","useWuEvents","subscriptions","emit","event","eventBus","on","callback","unsubscribe","once","off","unsub","useWuStore","initialValue","store","pattern","setState","path","fullPath","getState","wuVuePlugin","install","component","globalProperties","$wu","$wuEvents","$wuStore","ns","wuVue"],"mappings":"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"}
|
package/dist/ai/wu-ai.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{l as e}from"../wu-logger-fJfUHBGA.js";import{c as t,t as s,e as r,a as o,b as i,g as n,d as a,f as c,n as l}from"../wu-ai-browser-primitives-BDKXJlwc.js";class u{constructor(e={}){this.model=e.model||""}formatRequest(){throw new Error("Adapter must implement formatRequest()")}parseResponse(){throw new Error("Adapter must implement parseResponse()")}parseStreamChunk(){throw new Error("Adapter must implement parseStreamChunk()")}getHeaders(){return{"Content-Type":"application/json"}}}class p extends u{constructor(e){super(e),this.model=e.model||"claude-sonnet-4-5-20250929"}getHeaders(e){const t={"Content-Type":"application/json"};return e.apiKey&&(t["x-api-key"]=e.apiKey,t["anthropic-version"]="2023-06-01"),t}formatRequest(e,t={}){const s=e.filter(e=>"system"===e.role),r=e.filter(e=>"system"!==e.role),o={model:t.model||this.model,max_tokens:t.maxTokens||4096,messages:r.map(e=>"tool"===e.role?{role:"user",content:[{type:"tool_result",tool_use_id:e.tool_call_id,content:e.content}]}:e.tool_calls?{role:"assistant",content:e.tool_calls.map(e=>({type:"tool_use",id:e.id,name:e.name,input:e.arguments}))}:{role:e.role,content:e.content})};if(s.length&&(o.system=s.map(e=>e.content).join("\n\n")),t.responseFormat){const e=t.responseFormat,s="\n\nYou MUST respond with valid JSON only. No markdown, no explanation.";if("json"===e||"json_object"===e?.type)o.system=(o.system||"")+s;else if("json_schema"===e?.type){const t=JSON.stringify(e.schema,null,2);o.system=(o.system||"")+s+`\n\nYour response MUST conform to this JSON schema:\n${t}`}o.messages.push({role:"assistant",content:"{"})}return t.tools?.length&&(o.tools=t.tools.map(e=>({name:e.name,description:e.description,input_schema:e.parameters}))),void 0!==t.temperature&&(o.temperature=t.temperature),t.stream&&(o.stream=!0),o}parseResponse(e){const t=(e.content||[]).filter(e=>"text"===e.type),s=(e.content||[]).filter(e=>"tool_use"===e.type),r=t.map(e=>e.text).join(""),o=s.map(e=>({id:e.id,name:e.name,arguments:e.input||{}}));return{content:r,tool_calls:o.length>0?o:void 0,usage:e.usage?{prompt_tokens:e.usage.input_tokens,completion_tokens:e.usage.output_tokens}:void 0}}parseStreamChunk(e){if(!e.startsWith("data: "))return null;const t=e.slice(6).trim();try{const e=JSON.parse(t);if("content_block_delta"===e.type){if("text_delta"===e.delta?.type)return{type:"text",content:e.delta.text};if("input_json_delta"===e.delta?.type)return{type:"tool_call_delta",argumentsDelta:e.delta.partial_json||""}}return"content_block_start"===e.type&&"tool_use"===e.content_block?.type?{type:"tool_call_start",id:e.content_block.id,name:e.content_block.name}:"message_delta"===e.type&&e.usage?{type:"usage",usage:{prompt_tokens:e.usage.input_tokens,completion_tokens:e.usage.output_tokens}}:"message_stop"===e.type?{type:"done"}:null}catch{return null}}}class h extends u{constructor(e){super(e),this._sendFn=e.send||null,this._streamFn=e.stream||null}get isCustom(){return!0}}const m={openai:class extends u{constructor(e){super(e),this.model=e.model||"gpt-4o"}getHeaders(e){const t={"Content-Type":"application/json"};return e.apiKey&&(t.Authorization=`Bearer ${e.apiKey}`),t}formatRequest(e,t={}){const s={model:t.model||this.model,messages:e.map(e=>{const t={role:e.role,content:e.content};return e.tool_call_id&&(t.tool_call_id=e.tool_call_id),e.tool_calls&&(t.tool_calls=e.tool_calls.map(e=>({id:e.id,type:"function",function:{name:e.name,arguments:JSON.stringify(e.arguments)}}))),t})};if(t.tools?.length&&(s.tools=t.tools.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters}}))),void 0!==t.temperature&&(s.temperature=t.temperature),t.maxTokens&&(s.max_tokens=t.maxTokens),t.stream&&(s.stream=!0),t.responseFormat){const e=t.responseFormat;"json"===e||"json_object"===e?.type?s.response_format={type:"json_object"}:"json_schema"===e?.type&&(s.response_format={type:"json_schema",json_schema:{name:e.name||"response",schema:e.schema,strict:!1!==e.strict}})}return s}parseResponse(e){const t=e.choices?.[0];if(!t)return{content:"",tool_calls:[],usage:e.usage};const s=t.message||{},r=(s.tool_calls||[]).map(e=>({id:e.id,name:e.function?.name,arguments:this._safeParseArgs(e.function?.arguments)}));return{content:s.content||"",tool_calls:r.length>0?r:void 0,usage:e.usage?{prompt_tokens:e.usage.prompt_tokens,completion_tokens:e.usage.completion_tokens}:void 0}}parseStreamChunk(e){if(!e.startsWith("data: "))return null;const t=e.slice(6).trim();if("[DONE]"===t)return{type:"done"};try{const e=JSON.parse(t),s=e.choices?.[0]?.delta;if(!s)return null;if(s.tool_calls?.length){const e=s.tool_calls[0];return{type:"tool_call_delta",index:e.index,id:e.id,name:e.function?.name,argumentsDelta:e.function?.arguments||""}}return s.content?{type:"text",content:s.content}:e.usage?{type:"usage",usage:e.usage}:null}catch{return null}}_safeParseArgs(e){if(!e)return{};try{return JSON.parse(e)}catch{return{}}}},anthropic:p,ollama:class extends u{constructor(e){super(e),this.model=e.model||"llama3"}getHeaders(){return{"Content-Type":"application/json"}}formatRequest(e,t={}){const s={model:t.model||this.model,messages:e.map(e=>({role:e.role,content:e.content}))};if(t.tools?.length&&(s.tools=t.tools.map(e=>({type:"function",function:{name:e.name,description:e.description,parameters:e.parameters}}))),void 0!==t.temperature&&(s.options={temperature:t.temperature}),void 0!==t.stream&&(s.stream=t.stream),t.responseFormat){const e=t.responseFormat;"json"===e||"json_object"===e?.type?s.format="json":"json_schema"===e?.type&&(s.format=e.schema)}return s}parseResponse(e){const t=e.message||{},s=(t.tool_calls||[]).map((e,t)=>({id:`ollama_${t}_${Date.now()}`,name:e.function?.name,arguments:e.function?.arguments||{}}));return{content:t.content||"",tool_calls:s.length>0?s:void 0,usage:e.eval_count?{prompt_tokens:e.prompt_eval_count||0,completion_tokens:e.eval_count||0}:void 0}}parseStreamChunk(e){try{const t=JSON.parse(e);return t.done?{type:"done"}:t.message?.content?{type:"text",content:t.message.content}:null}catch{return null}}}};class d{constructor(){this._providers=new Map,this._active=null,this._activeName=null,this._activeConfig={},this._retryConfig={maxRetries:3,baseDelayMs:1e3}}register(t,s={}){const r=s.adapter||t,o=m[r];let i;if(s.send||s.stream)i=new h(s);else{if(!o)throw new Error(`[wu-ai] Unknown adapter '${r}'. Available: ${Object.keys(m).join(", ")}, or provide custom send/stream.`);i=new o(s)}this._providers.set(t,{adapter:i,config:s}),this._active&&!1===s.active||(this._active=i,this._activeName=t,this._activeConfig=s),e.wuInfo(`[wu-ai] Provider registered: '${t}' (adapter: ${r})`)}use(e){const t=this._providers.get(e);if(!t)throw new Error(`[wu-ai] Provider '${e}' not registered`);this._active=t.adapter,this._activeName=e,this._activeConfig=t.config}async send(t,s={}){const{adapter:r,config:o}=this._resolveProvider(s.provider);if(r.isCustom&&r._sendFn)return r._sendFn(t,s);const i=o.endpoint||o.baseUrl;if(!i)throw new Error("[wu-ai] No endpoint configured. Set config.endpoint or config.baseUrl.");const n=this._resolveUrl(i),a=r.formatRequest(t,{...s,stream:!1}),c=r.getHeaders(o),l=await this._fetchWithRetry(n,{method:"POST",headers:c,body:JSON.stringify(a),signal:s.signal}),u=await l.json(),h=r.parseResponse(u);if(r instanceof p&&s.responseFormat&&h.content&&(h.content="{"+h.content),s.responseFormat&&h.content)try{h.parsed=JSON.parse(h.content)}catch{h.parseError="Response is not valid JSON",e.wuDebug("[wu-ai] responseFormat requested but LLM returned invalid JSON")}return h}async*stream(e,t={}){const{adapter:s,config:r}=this._resolveProvider(t.provider);if(s.isCustom&&s._streamFn)return void(yield*s._streamFn(e,t));const o=r.endpoint||r.baseUrl;if(!o)throw new Error("[wu-ai] No endpoint configured. Set config.endpoint or config.baseUrl.");const i=this._resolveUrl(o),n=s.formatRequest(e,{...t,stream:!0}),a=s.getHeaders(r),c=await fetch(i,{method:"POST",headers:a,body:JSON.stringify(n),signal:t.signal});if(!c.ok)throw new Error(`[wu-ai] Stream request failed: ${c.status} ${c.statusText}`);const l=c.body.getReader(),u=new TextDecoder;let h="",m=s instanceof p&&!!t.responseFormat;try{for(;;){const{done:e,value:t}=await l.read();if(e)break;h+=u.decode(t,{stream:!0});const r=h.split("\n");h=r.pop()||"";for(const e of r){const t=e.trim();if(!t)continue;const r=s.parseStreamChunk(t);if(r&&(m&&"text"===r.type&&(r.content="{"+r.content,m=!1),yield r),"done"===r?.type)return}}if(h.trim()){const e=s.parseStreamChunk(h.trim());e&&(yield e)}}finally{l.releaseLock()}}async _fetchWithRetry(t,s){let r;for(let o=0;o<=this._retryConfig.maxRetries;o++)try{const i=await fetch(t,s);if(i.ok)return i;if((429===i.status||i.status>=500)&&(r=new Error(`HTTP ${i.status}: ${i.statusText}`),o<this._retryConfig.maxRetries)){const t=this._retryConfig.baseDelayMs*Math.pow(2,o);e.wuDebug(`[wu-ai] Retry ${o+1}/${this._retryConfig.maxRetries} in ${t}ms (${i.status})`),await new Promise(e=>setTimeout(e,t));continue}const n=new Error(`[wu-ai] Request failed: ${i.status} ${i.statusText}`);throw n._noRetry=!0,n}catch(e){if("AbortError"===e.name)throw e;if(e._noRetry)throw e;if(r=e,o<this._retryConfig.maxRetries){const e=this._retryConfig.baseDelayMs*Math.pow(2,o);await new Promise(t=>setTimeout(t,e));continue}}throw r}_resolveUrl(e){return e.startsWith("/")&&"undefined"!=typeof window?`${window.location.origin}${e}`:e}_resolveProvider(e){if(e){const t=this._providers.get(e);if(!t)throw new Error(`[wu-ai] Provider '${e}' not registered. Available: ${[...this._providers.keys()].join(", ")}`);return{adapter:t.adapter,config:t.config}}return this._ensureActive(),{adapter:this._active,config:this._activeConfig}}_ensureActive(){if(!this._active)throw new Error('[wu-ai] No provider configured. Call wu.ai.provider("name", { endpoint, adapter }) first.')}configureRetry(e){void 0!==e.maxRetries&&(this._retryConfig.maxRetries=e.maxRetries),void 0!==e.baseDelayMs&&(this._retryConfig.baseDelayMs=e.baseDelayMs)}getActiveProvider(){return this._activeName}getStats(){return{activeProvider:this._activeName,registeredProviders:[...this._providers.keys()]}}}const _={readStore:!0,writeStore:!1,emitEvents:!0,readDOM:!1,modifyDOM:!1,executeActions:!0,allowDirectKey:!1},g="closed",f="open",w="half-open";class y{constructor(e={}){this._maxPerMinute=e.requestsPerMinute??20,this._maxPerMinutePerNs=e.requestsPerMinutePerNs??10,this._maxConcurrent=e.maxConcurrent??3,this._globalTimestamps=[],this._nsTimestamps=new Map,this._concurrent=0}configure(e){void 0!==e.requestsPerMinute&&(this._maxPerMinute=e.requestsPerMinute),void 0!==e.requestsPerMinutePerNs&&(this._maxPerMinutePerNs=e.requestsPerMinutePerNs),void 0!==e.maxConcurrent&&(this._maxConcurrent=e.maxConcurrent)}canSend(e="default"){if(this._pruneOld(),this._concurrent>=this._maxConcurrent)return{allowed:!1,reason:`Max concurrent (${this._maxConcurrent}) reached`};if(this._globalTimestamps.length>=this._maxPerMinute)return{allowed:!1,reason:`Global rate limit (${this._maxPerMinute}/min) exceeded`};return(this._nsTimestamps.get(e)||[]).length>=this._maxPerMinutePerNs?{allowed:!1,reason:`Namespace '${e}' rate limit (${this._maxPerMinutePerNs}/min) exceeded`}:{allowed:!0}}recordStart(e="default"){const t=Date.now();this._globalTimestamps.push(t),this._nsTimestamps.has(e)||this._nsTimestamps.set(e,[]),this._nsTimestamps.get(e).push(t),this._concurrent++}recordEnd(){this._concurrent=Math.max(0,this._concurrent-1)}_pruneOld(){const e=Date.now()-6e4;this._globalTimestamps=this._globalTimestamps.filter(t=>t>e);for(const[t,s]of this._nsTimestamps){const r=s.filter(t=>t>e);0===r.length?this._nsTimestamps.delete(t):this._nsTimestamps.set(t,r)}}getStats(){return this._pruneOld(),{globalRequestsLastMinute:this._globalTimestamps.length,concurrent:this._concurrent,maxPerMinute:this._maxPerMinute,maxConcurrent:this._maxConcurrent}}}class v{constructor(e={}){this._state=g,this._failureCount=0,this._maxFailures=e.maxFailures??3,this._cooldownMs=e.cooldownMs??3e4,this._openedAt=0,this._rapidFireThreshold=e.rapidFireThreshold??5,this._rapidFireWindowMs=e.rapidFireWindowMs??2e3,this._recentRequests=[]}configure(e){void 0!==e.maxFailures&&(this._maxFailures=e.maxFailures),void 0!==e.cooldownMs&&(this._cooldownMs=e.cooldownMs)}canPass(){if(this._state===g)return{allowed:!0};if(this._state===f){if(Date.now()-this._openedAt>=this._cooldownMs)return this._state=w,e.wuDebug("[wu-ai] Circuit breaker → HALF-OPEN (testing)"),{allowed:!0};const t=this._cooldownMs-(Date.now()-this._openedAt);return{allowed:!1,reason:`Circuit breaker OPEN (${Math.ceil(t/1e3)}s remaining)`}}return{allowed:!0}}recordSuccess(){this._state===w?(this._state=g,this._failureCount=0,e.wuInfo("[wu-ai] Circuit breaker → CLOSED (recovered)")):this._failureCount=0,this._recordRequest()}recordFailure(){this._failureCount++,this._recordRequest(),this._state!==w?this._failureCount>=this._maxFailures&&this._tripOpen(`${this._failureCount} consecutive failures`):this._tripOpen("Failed during half-open test")}_recordRequest(){const e=Date.now();this._recentRequests.push(e),this._recentRequests=this._recentRequests.filter(t=>e-t<this._rapidFireWindowMs),this._state===g&&this._recentRequests.length>=this._rapidFireThreshold&&this._tripOpen(`${this._recentRequests.length} requests in ${this._rapidFireWindowMs}ms (rapid fire)`)}_tripOpen(t){this._state=f,this._openedAt=Date.now(),e.wuWarn(`[wu-ai] Circuit breaker → OPEN: ${t}. Cooldown: ${this._cooldownMs/1e3}s`)}getState(){return this._state}getStats(){return{state:this._state,failureCount:this._failureCount,maxFailures:this._maxFailures,cooldownMs:this._cooldownMs,openedAt:this._openedAt}}reset(){this._state=g,this._failureCount=0,this._openedAt=0,this._recentRequests=[]}}class b{constructor(e={}){this._maxDepth=e.maxDepth??3,this._activeTraces=new Map,this._traceLog=[],this._maxTraceLog=50}configure(e){void 0!==e.maxDepth&&(this._maxDepth=e.maxDepth)}canProceed(e,t){if(e>this._maxDepth)return{allowed:!1,reason:`Max AI depth (${this._maxDepth}) exceeded at depth ${e}`};if(t){const e=(this._activeTraces.get(t)||0)+1;if(e>this._maxDepth)return{allowed:!1,reason:`Causal chain '${t}' looped ${e} times (max ${this._maxDepth})`}}return{allowed:!0}}enter(e){if(!e)return;const t=(this._activeTraces.get(e)||0)+1;this._activeTraces.set(e,t),this._traceLog.push({traceId:e,count:t,timestamp:Date.now()}),this._traceLog.length>this._maxTraceLog&&this._traceLog.shift()}exit(e){if(!e)return;const t=(this._activeTraces.get(e)||0)-1;t<=0?this._activeTraces.delete(e):this._activeTraces.set(e,t)}createTraceId(){return`t_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}getTraces(){return[...this._traceLog]}getStats(){return{maxDepth:this._maxDepth,activeTraces:this._activeTraces.size,traceLogSize:this._traceLog.length}}}class x{constructor(e={}){this._permissions={..._},this.rateLimiter=new y(e.rateLimit),this.circuitBreaker=new v(e.circuitBreaker),this.loopProtection=new b(e.loopProtection),this._allowedDomains=e.allowedDomains||[],e.permissions&&this.configure(e.permissions)}configure(t){Object.assign(this._permissions,t),this._isProduction()&&this._permissions.allowDirectKey&&(e.wuWarn("[wu-ai] allowDirectKey FORCED to false in production"),this._permissions.allowDirectKey=!1)}check(e){return!0===this._permissions[e]}getPermissions(){return{...this._permissions}}setAllowedDomains(e){this._allowedDomains=e}isDomainAllowed(e){if(0===this._allowedDomains.length)return!0;try{const t=new URL(e).hostname;return this._allowedDomains.some(e=>{if(e.startsWith("*.")){const s=e.slice(2);return t===s||t.endsWith("."+s)}return t===e})}catch{return!1}}preflight(e={}){const t=this.circuitBreaker.canPass();if(!t.allowed)return t;const s=this.rateLimiter.canSend(e.namespace);if(!s.allowed)return s;const r=this.loopProtection.canProceed(e.depth||0,e.traceId);return r.allowed?{allowed:!0}:r}getStats(){return{permissions:{...this._permissions},rateLimiter:this.rateLimiter.getStats(),circuitBreaker:this.circuitBreaker.getStats(),loopProtection:this.loopProtection.getStats(),allowedDomains:[...this._allowedDomains]}}_isProduction(){if("undefined"!=typeof process&&"production"===process.env?.NODE_ENV)return!0;if("undefined"!=typeof window){const e=window.location?.hostname||"";return"localhost"!==e&&"127.0.0.1"!==e&&"0.0.0.0"!==e&&!e.endsWith(".local")}return!1}}const S=["password","token","apiKey","secret","credential","authorization","cookie","session"];function k(e,t=0){if(t>10)return"[MAX_DEPTH]";if(null==e)return e;if("object"!=typeof e)return e;if(Array.isArray(e))return e.map(e=>k(e,t+1));const s={};for(const[r,o]of Object.entries(e)){const e=r.toLowerCase();S.some(t=>e.includes(t.toLowerCase()))?s[r]="[REDACTED]":s[r]=k(o,t+1)}return s}function $(e,t){return e.replace(/\{\{(\w+(?:\.\w+)*)\}\}/g,(e,s)=>{const r=s.split(".").reduce((e,t)=>e?.[t],t);return null==r?"":"object"==typeof r?function(e,t=2e3){if(null==e)return"null";if("function"==typeof e)return"[Function]";if("symbol"==typeof e)return"[Symbol]";if("string"==typeof e)return`<user_data>${e.length>t?e.slice(0,t)+"...[truncated]":e}</user_data>`;if("number"==typeof e||"boolean"==typeof e)return String(e);if("object"==typeof e){const s=k(e),r=JSON.stringify(s);return r.length>t?`<user_data>${r.slice(0,t)}...[truncated]</user_data>`:`<user_data>${r}</user_data>`}return String(e).slice(0,t)}(r):String(r)})}function T(e){if(!e||"object"!=typeof e)return{type:"object",properties:{},required:[]};if("object"===e.type&&e.properties)return e;const t={},s=[];for(const[r,o]of Object.entries(e))if("string"==typeof o)t[r]={type:o};else if("object"==typeof o){const{required:e,...i}=o;t[r]=i.type?i:{type:"string",...i},e&&s.push(r)}return{type:"object",properties:t,required:s}}class C{constructor({store:e,eventBus:t,core:s}){this._store=e,this._eventBus=t,this._core=s,this._config={budget:4e3,charRatio:4,sources:{store:{include:[],priority:"high"},events:{include:[],lastN:10,priority:"medium"},custom:[]}},this._collectors=new Map,this._lastSnapshot=null}configure(e){void 0!==e.budget&&(this._config.budget=e.budget),void 0!==e.charRatio&&(this._config.charRatio=e.charRatio),e.sources&&(e.sources.store&&Object.assign(this._config.sources.store,e.sources.store),e.sources.events&&Object.assign(this._config.sources.events,e.sources.events),e.sources.custom&&(this._config.sources.custom=e.sources.custom))}register(t,s){this._collectors.set(t,{collector:s.collector,priority:s.priority||"medium"}),e.wuDebug(`[wu-ai] Context collector registered: '${t}' (${s.priority||"medium"})`)}async collect(){const t={_timestamp:Date.now(),_mountedApps:this._getMountedApps()},s=this._collectStore();s&&Object.keys(s).length>0&&(t._store=s);const r=this._collectEvents();r.length>0&&(t._events=r);for(const s of this._config.sources.custom)try{const e="function"==typeof s.value?await s.value():s.value;t[s.key]=e}catch(t){e.wuDebug(`[wu-ai] Custom collector '${s.key}' failed: ${t.message}`)}for(const[s,r]of this._collectors)try{const e=await r.collector();t[s]=e}catch(t){e.wuDebug(`[wu-ai] Collector '${s}' failed: ${t.message}`)}return this._lastSnapshot=t,t}toSystemPrompt(e={}){const t=this._lastSnapshot;if(!t)return this._baseSystemPrompt(e);const s=[];s.push("You are an AI assistant connected to a live web application via Wu Framework.","You can observe application state and execute actions when appropriate.",""),t._mountedApps?.length&&s.push(`MOUNTED APPS: ${t._mountedApps.join(", ")}`,"");const r=this._config.budget*this._config.charRatio;let o=s.join("\n").length;const i=this._prioritizeSections(t);for(const e of i){const t=e.text;if(o+t.length>r){if("high"===e.priority){const e=r-o;e>100&&(s.push(t.slice(0,e)+"\n...[truncated]"),o+=e)}}else s.push(t),o+=t.length}if(e.tools?.length){s.push("","AVAILABLE TOOLS:");for(const t of e.tools)s.push(`- ${t.name}: ${t.description}`)}return s.join("\n")}getSnapshot(){return this._lastSnapshot}getInterpolationContext(){if(!this._lastSnapshot)return{};const{_timestamp:e,_mountedApps:t,_store:s,_events:r,...o}=this._lastSnapshot;return{apps:t,store:s,events:r,...o}}_collectStore(){if(!this._store)return{};const{include:e}=this._config.sources.store;if(!e||0===e.length)return{};const t={};for(const s of e)try{const e=this._store.get(s);void 0!==e&&(t[s]=k(e))}catch{}return t}_collectEvents(){if(!this._eventBus)return[];const{include:e,lastN:t}=this._config.sources.events;if(!e||0===e.length)return[];return(this._eventBus.history||[]).filter(t=>e.some(e=>this._matchPattern(t.name||t.event,e))).slice(-(t||10)).map(e=>({event:e.name||e.event,data:k(e.data),timestamp:e.timestamp}))}_getMountedApps(){if(!this._core)return[];try{if(this._core.mounted instanceof Map)return[...this._core.mounted.keys()];const e=this._core.getStats?.();return e?.apps||e?.mounted||[]}catch{return[]}}_prioritizeSections(e){const t=[],s=this._config.sources.store.priority||"high",r=this._config.sources.events.priority||"medium";if(e._store&&Object.keys(e._store).length>0&&t.push({priority:s,text:`APPLICATION STATE:\n${JSON.stringify(e._store,null,2)}`}),e._events?.length){const s=e._events.map(e=>` [${e.event}] ${JSON.stringify(e.data)}`).join("\n");t.push({priority:r,text:`RECENT EVENTS:\n${s}`})}for(const[s,r]of this._collectors)void 0!==e[s]&&t.push({priority:r.priority,text:`${s.toUpperCase()}:\n${JSON.stringify(e[s],null,2)}`});for(const s of this._config.sources.custom)void 0!==e[s.key]&&t.push({priority:s.priority||"low",text:`${s.key}: ${JSON.stringify(e[s.key])}`});const o={high:0,medium:1,low:2};return t.sort((e,t)=>(o[e.priority]??1)-(o[t.priority]??1)),t}_baseSystemPrompt(e={}){let t="You are an AI assistant connected to a web application via Wu Framework.";return e.tools?.length&&(t+="\n\nAVAILABLE TOOLS:\n"+e.tools.map(e=>`- ${e.name}: ${e.description}`).join("\n")),t}_matchPattern(e,t){if(!e||!t)return!1;if("*"===t)return!0;if(!t.includes("*"))return e===t;return new RegExp("^"+t.replace(/\*/g,"[^:]*")+"$").test(e)}getStats(){return{budget:this._config.budget,collectors:[...this._collectors.keys()],storePaths:this._config.sources.store.include,eventPatterns:this._config.sources.events.include,lastCollected:this._lastSnapshot?._timestamp||null}}}class A{constructor({eventBus:e,store:t,permissions:s}){this._eventBus=e,this._store=t,this._permissions=s,this._actions=new Map,this._executionLog=[],this._maxLogSize=100,this._pendingConfirms=new Map}register(t,s){if(!s.handler||"function"!=typeof s.handler)throw new Error(`[wu-ai] Action '${t}' must have a handler function`);this._actions.set(t,{description:s.description||`Execute: ${t}`,parameters:T(s.parameters),handler:s.handler,confirm:s.confirm||!1,permissions:s.permissions||[],dangerous:s.dangerous||!1}),e.wuDebug(`[wu-ai] Action registered: '${t}'${s.dangerous?" [DANGEROUS]":""}`)}unregister(e){this._actions.delete(e)}async execute(t,s,r={}){const o=this._actions.get(t);if(!o)return{success:!1,reason:`Action '${t}' not registered`};for(const e of o.permissions)if(!this._permissions.check(e))return this._emitDenied(t,s,`Missing permission: ${e}`),{success:!1,reason:`Permission denied: ${e}`};const i=function(e,t){const s=[];if(!t||!t.properties)return{valid:!0,errors:s};for(const r of t.required||[])void 0!==e[r]&&null!==e[r]||s.push(`'${r}' is required`);for(const[r,o]of Object.entries(t.properties)){const t=e[r];if(null!=t){if(o.type&&"any"!==o.type){const e=Array.isArray(t)?"array":typeof t;"integer"===o.type?"number"==typeof t&&Number.isInteger(t)||s.push(`'${r}' must be integer, got ${e}`):o.type!==e&&s.push(`'${r}' must be ${o.type}, got ${e}`)}o.enum&&!o.enum.includes(t)&&s.push(`'${r}' must be one of [${o.enum.join(", ")}], got '${t}'`)}}return{valid:0===s.length,errors:s}}(s||{},o.parameters);if(!i.valid)return{success:!1,reason:`Invalid params: ${i.errors.join(", ")}`};if(o.confirm){if(!await this._requestConfirmation(t,s,r.callId))return{success:!1,reason:"User denied action"}}try{o.dangerous&&e.wuWarn(`[wu-ai] Executing DANGEROUS action: '${t}' with params: ${JSON.stringify(s)}`);const i=this._createSandboxedApi(o.permissions),n=await o.handler(s,i);return this._log(t,s,n,r),this._eventBus.emit("ai:action:executed",{action:t,params:s,result:n,traceId:r.traceId},{appName:"wu-ai"}),{success:!0,result:n}}catch(e){return this._eventBus.emit("ai:action:error",{action:t,params:s,error:e.message,traceId:r.traceId},{appName:"wu-ai"}),{success:!1,reason:e.message}}}getToolSchemas(){return function(e){const t=[];for(const[s,r]of e)t.push({name:s,description:r.description||`Execute action: ${s}`,parameters:T(r.parameters)});return t}(this._actions)}has(e){return this._actions.has(e)}getNames(){return[...this._actions.keys()]}getLog(){return[...this._executionLog]}confirmTool(e){const t=this._pendingConfirms.get(e);t&&(clearTimeout(t.timeout),this._pendingConfirms.delete(e),t.resolve(!0))}rejectTool(e){const t=this._pendingConfirms.get(e);t&&(clearTimeout(t.timeout),this._pendingConfirms.delete(e),t.resolve(!1))}_createSandboxedApi(e){const t={},s=new Set(e);return this._permissions.check("readStore")&&(t.getState=e=>this._store.get(e)),this._permissions.check("writeStore")&&s.has("writeStore")&&(t.setState=(e,t)=>this._store.set(e,t)),this._permissions.check("emitEvents")&&(t.emit=(e,t)=>this._eventBus.emit(e,t,{appName:"wu-ai"})),t}_requestConfirmation(t,s,r){const o=r||`confirm_${Date.now()}_${Math.random().toString(36).slice(2,6)}`;return new Promise(r=>{const i=setTimeout(()=>{this._pendingConfirms.delete(o),r(!1),e.wuDebug(`[wu-ai] Confirmation timeout for action '${t}'`)},3e4);this._pendingConfirms.set(o,{resolve:r,timeout:i}),this._eventBus.emit("ai:tool:confirm",{callId:o,action:t,params:s,message:`AI wants to execute: ${t}`},{appName:"wu-ai"})})}_log(e,t,s,r){this._executionLog.push({action:e,params:t,result:"object"==typeof s?{...s}:s,timestamp:Date.now(),traceId:r.traceId}),this._executionLog.length>this._maxLogSize&&this._executionLog.shift()}_emitDenied(t,s,r){this._eventBus.emit("ai:action:denied",{action:t,params:s,reason:r},{appName:"wu-ai"}),e.wuWarn(`[wu-ai] Action denied: '${t}' — ${r}`)}getStats(){return{registeredActions:[...this._actions.keys()],executionLogSize:this._executionLog.length,pendingConfirmations:this._pendingConfirms.size}}}const P={maxHistoryMessages:50,maxToolRounds:5,defaultNamespace:"default",systemPrompt:null,temperature:void 0,maxTokens:void 0,namespaceTTL:18e5,gcInterval:3e5};class N{constructor(e){this.name=e,this.messages=[],this.createdAt=Date.now(),this.lastActivity=Date.now(),this._abortController=null}addMessage(e){this.messages.push({...e,_ts:Date.now()}),this.lastActivity=Date.now()}getMessages(){return this.messages.map(({_ts:e,...t})=>t)}truncate(e){if(this.messages.length<=e)return;const t=this.messages.filter(e=>"system"===e.role),s=this.messages.filter(e=>"system"!==e.role).slice(-e);this.messages=[...t,...s]}clear(){this.messages=[],this.lastActivity=Date.now()}abort(){this._abortController&&(this._abortController.abort(),this._abortController=null)}createAbortController(){return this.abort(),this._abortController=new AbortController,this._abortController}}class R{constructor({provider:e,actions:t,context:s,permissions:r,eventBus:o}){this._provider=e,this._actions=t,this._context=s,this._permissions=r,this._eventBus=o,this._config={...P},this._namespaces=new Map,this._activeRequests=new Map,this._lastGcRun=Date.now()}configure(e){Object.assign(this._config,e)}async send(t,s={}){const r=this._getOrCreateNamespace(s.namespace),o=this._permissions.loopProtection.createTraceId(),i={namespace:r.name,depth:0,traceId:o},n=this._permissions.preflight(i);if(!n.allowed)return{content:`[blocked] ${n.reason}`,namespace:r.name};const a=await this._buildSystemPrompt(s);this._setSystemMessage(r,a);const c=this._processMessage(t,s.templateVars);r.addMessage({role:"user",content:c}),r.truncate(this._config.maxHistoryMessages);const l=r.createAbortController(),u=this._mergeSignals(l.signal,s.signal);this._permissions.rateLimiter.recordStart(r.name);try{const t=[];let i=0;const n=this._config.maxToolRounds;for(;i<=n;){const a=this._actions.getToolSchemas(),c=await this._provider.send(r.getMessages(),{tools:a.length>0?a:void 0,temperature:s.temperature??this._config.temperature,maxTokens:s.maxTokens??this._config.maxTokens,responseFormat:s.responseFormat,provider:s.provider,signal:u}),l={role:"assistant",content:c.content||""};if(c.tool_calls&&(l.tool_calls=c.tool_calls),r.addMessage(l),!c.tool_calls||0===c.tool_calls.length)return this._permissions.circuitBreaker.recordSuccess(),this._eventBus.emit("ai:response",{namespace:r.name,content:c.content,toolResults:t.length>0?t:void 0,usage:c.usage,traceId:o},{appName:"wu-ai"}),{content:c.content||"",tool_results:t.length>0?t:void 0,usage:c.usage,namespace:r.name};if(i++,i>n){const s=`[wu-ai] Tool call loop limit (${n}) reached in namespace '${r.name}'`;return e.wuWarn(s),r.addMessage({role:"assistant",content:s}),{content:s,tool_results:t,namespace:r.name}}this._permissions.loopProtection.enter(o);for(const e of c.tool_calls){const s=await this._actions.execute(e.name,e.arguments,{traceId:o,depth:i,callId:e.id});t.push({tool:e.name,params:e.arguments,result:s.result,success:s.success}),r.addMessage({role:"tool",content:JSON.stringify(s.success?s.result:{error:s.reason}),tool_call_id:e.id})}this._permissions.loopProtection.exit(o)}return{content:"",tool_results:t,namespace:r.name}}catch(e){if(this._permissions.circuitBreaker.recordFailure(),"AbortError"===e.name)return{content:"[aborted]",namespace:r.name};throw this._eventBus.emit("ai:error",{namespace:r.name,error:e.message,traceId:o},{appName:"wu-ai"}),e}finally{this._permissions.rateLimiter.recordEnd(),r._abortController=null}}async*stream(t,s={}){const r=this._getOrCreateNamespace(s.namespace),o=this._permissions.loopProtection.createTraceId(),i={namespace:r.name,depth:0,traceId:o},n=this._permissions.preflight(i);if(!n.allowed)return void(yield{type:"error",error:n.reason});const a=await this._buildSystemPrompt(s);this._setSystemMessage(r,a);const c=this._processMessage(t,s.templateVars);r.addMessage({role:"user",content:c}),r.truncate(this._config.maxHistoryMessages);const l=r.createAbortController(),u=this._mergeSignals(l.signal,s.signal);this._permissions.rateLimiter.recordStart(r.name);try{let t=0;const i=this._config.maxToolRounds;for(;t<=i;){const n=this._actions.getToolSchemas();let a="";const c=new Map;let l=!1;for await(const e of this._provider.stream(r.getMessages(),{tools:n.length>0?n:void 0,temperature:s.temperature??this._config.temperature,maxTokens:s.maxTokens??this._config.maxTokens,responseFormat:s.responseFormat,provider:s.provider,signal:u}))if("text"===e.type)a+=e.content,yield e;else if("tool_call_start"===e.type)c.set(c.size,{id:e.id,name:e.name,args:""});else if("tool_call_delta"===e.type){const t=e.index??c.size-1,s=c.get(t);s?(e.id&&(s.id=e.id),e.name&&(s.name=e.name),s.args+=e.argumentsDelta||""):c.set(t,{id:e.id||`tc_${t}`,name:e.name||"",args:e.argumentsDelta||""})}else{if("done"===e.type){l=!0;break}("usage"===e.type||"error"===e.type)&&(yield e)}if(0===c.size)return a&&r.addMessage({role:"assistant",content:a}),this._permissions.circuitBreaker.recordSuccess(),void(yield{type:"done"});if(t++,t>i){const t=`[wu-ai] Tool call loop limit (${i}) reached in streaming namespace '${r.name}'`;return e.wuWarn(t),yield{type:"error",error:t},void(yield{type:"done"})}const p=[];for(const[,e]of c){let t={};try{t=JSON.parse(e.args)}catch{}p.push({id:e.id,name:e.name,arguments:t})}r.addMessage({role:"assistant",content:a,tool_calls:p}),this._permissions.loopProtection.enter(o);for(const e of p){const s=await this._actions.execute(e.name,e.arguments,{traceId:o,depth:t,callId:e.id});yield{type:"tool_result",tool:e.name,result:s.success?s.result:{error:s.reason},success:s.success},r.addMessage({role:"tool",content:JSON.stringify(s.success?s.result:{error:s.reason}),tool_call_id:e.id})}this._permissions.loopProtection.exit(o),yield{type:"tool_calls_done",count:p.length}}}catch(e){if(this._permissions.circuitBreaker.recordFailure(),"AbortError"===e.name)return void(yield{type:"error",error:"aborted"});yield{type:"error",error:e.message},this._eventBus.emit("ai:error",{namespace:r.name,error:e.message,traceId:o},{appName:"wu-ai"})}finally{this._permissions.rateLimiter.recordEnd(),r._abortController=null}}inject(e,t,s={}){this._getOrCreateNamespace(s.namespace).addMessage({role:e,content:t})}getHistory(e){const t=this._namespaces.get(e||this._config.defaultNamespace);return t?t.getMessages():[]}clear(e){const t=this._namespaces.get(e||this._config.defaultNamespace);t&&t.clear()}clearAll(){for(const e of this._namespaces.values())e.clear()}abort(e){const t=this._namespaces.get(e||this._config.defaultNamespace);t&&t.abort()}abortAll(){for(const e of this._namespaces.values())e.abort()}getNamespaces(){return[...this._namespaces.keys()]}deleteNamespace(e){const t=this._namespaces.get(e);t&&(t.abort(),this._namespaces.delete(e))}_getOrCreateNamespace(e){const t=e||this._config.defaultNamespace;this._maybeGcSweep(),this._namespaces.has(t)||this._namespaces.set(t,new N(t));const s=this._namespaces.get(t);return s.lastActivity=Date.now(),s}_maybeGcSweep(){const t=this._config.namespaceTTL,s=this._config.gcInterval;if(!t||t<=0)return;const r=Date.now();if(r-this._lastGcRun<s)return;this._lastGcRun=r;const o=r-t,i=[];for(const[e,t]of this._namespaces)e!==this._config.defaultNamespace&&(t._abortController||t.lastActivity<o&&i.push(e));for(const e of i)this._namespaces.delete(e);i.length>0&&e.wuDebug(`[wu-ai] GC sweep: removed ${i.length} expired namespace(s): ${i.join(", ")}`)}async _buildSystemPrompt(e){if(e.systemPrompt)return"function"==typeof e.systemPrompt?await e.systemPrompt():e.systemPrompt;if(this._config.systemPrompt)return"function"==typeof this._config.systemPrompt?await this._config.systemPrompt():this._config.systemPrompt;if(this._context){await this._context.collect();const e=this._actions.getToolSchemas();return this._context.toSystemPrompt({tools:e})}return"You are an AI assistant connected to a web application via Wu Framework."}_setSystemMessage(e,t){e.messages.length>0&&"system"===e.messages[0].role?(e.messages[0].content=t,e.messages[0]._ts=Date.now()):e.messages.unshift({role:"system",content:t,_ts:Date.now()})}_processMessage(e,t){if(!t)return e;try{return $(e,{...this._context?.getInterpolationContext()||{},...t})}catch{return e}}_mergeSignals(e,t){if(!t)return e;if("undefined"!=typeof AbortSignal&&AbortSignal.any)return AbortSignal.any([e,t]);const s=new AbortController,r=()=>s.abort();return e.addEventListener("abort",r,{once:!0}),t.addEventListener("abort",r,{once:!0}),s.signal}getStats(){const e={};for(const[t,s]of this._namespaces)e[t]={messageCount:s.messages.length,lastActivity:s.lastActivity,hasActiveRequest:!!s._abortController};return{namespaces:e,config:{...this._config}}}}const D={enabled:!0,maxActiveTriggers:20,defaultDebounceMs:1e3,batchIntervalMs:2e3};class M{constructor(e,t){this.name=e,this.pattern=t.pattern,this.prompt=t.prompt,this.condition=t.condition||null,this.debounceMs=t.debounce??D.defaultDebounceMs,this.priority=t.priority||"medium",this.namespace=t.namespace||`trigger:${e}`,this.systemPrompt=t.systemPrompt||null,this.onResult=t.onResult||null,this.enabled=!1!==t.enabled,this.maxTokens=t.maxTokens||void 0,this.temperature=t.temperature||void 0,this._debounceTimer=null,this._lastFired=0,this._fireCount=0,this._pendingEvent=null}matches(e){if(!this.pattern)return!1;if("*"===this.pattern)return!0;if(!this.pattern.includes("*"))return e===this.pattern;return new RegExp("^"+this.pattern.replace(/\*/g,"[^:]*")+"$").test(e)}buildPrompt(e){return"function"==typeof this.prompt?this.prompt(e):$(this.prompt,{event:e,data:e?.data,timestamp:Date.now()})}async checkCondition(t){if(!this.condition)return!0;try{const e=this.condition(t);return e instanceof Promise?await e:e}catch(t){return e.wuDebug(`[wu-ai] Trigger '${this.name}' condition error: ${t.message}`),!1}}}class E{constructor({eventBus:e,conversation:t,permissions:s}){this._eventBus=e,this._conversation=t,this._permissions=s,this._config={...D},this._triggers=new Map,this._listeners=new Map,this._batchQueue=[],this._batchTimer=null,this._stats={totalFired:0,totalSkipped:0,totalErrors:0}}configure(e){Object.assign(this._config,e)}register(t,s){if(this._triggers.size>=this._config.maxActiveTriggers)return void e.wuWarn(`[wu-ai] Max triggers (${this._config.maxActiveTriggers}) reached. Cannot register '${t}'.`);this._triggers.has(t)&&this.unregister(t);const r=new M(t,s);this._triggers.set(t,r);const o=this._eventBus.on(r.pattern,e=>this._handleEvent(t,e));this._listeners.set(t,o),e.wuDebug(`[wu-ai] Trigger registered: '${t}' → pattern '${r.pattern}' (${r.priority})`)}unregister(e){const t=this._triggers.get(e);t&&t._debounceTimer&&clearTimeout(t._debounceTimer);const s=this._listeners.get(e);"function"==typeof s&&s(),this._triggers.delete(e),this._listeners.delete(e)}setEnabled(e,t){const s=this._triggers.get(e);s&&(s.enabled=t)}setAllEnabled(e){this._config.enabled=e;for(const t of this._triggers.values())t.enabled=e}async fire(t,s={}){const r=this._triggers.get(t);return r?this._executeTrigger(r,s):(e.wuWarn(`[wu-ai] Trigger '${t}' not found`),null)}getNames(){return[...this._triggers.keys()]}getTrigger(e){const t=this._triggers.get(e);return t?{name:t.name,pattern:t.pattern,priority:t.priority,namespace:t.namespace,enabled:t.enabled,fireCount:t._fireCount,lastFired:t._lastFired}:null}destroy(){for(const e of[...this._triggers.keys()])this.unregister(e);this._batchTimer&&(clearTimeout(this._batchTimer),this._batchTimer=null),this._batchQueue=[]}async _handleEvent(e,t){if(!this._config.enabled)return;const s=this._triggers.get(e);if(!s||!s.enabled)return;await s.checkCondition(t)?"high"===s.priority?this._debouncedFire(s,t):"low"===s.priority?(this._batchQueue.push({trigger:s,eventData:t}),this._scheduleBatch()):this._debouncedFire(s,t):this._stats.totalSkipped++}_debouncedFire(e,t){e._pendingEvent=t,e._debounceTimer&&clearTimeout(e._debounceTimer),e.debounceMs<=0?this._executeTrigger(e,t):e._debounceTimer=setTimeout(()=>{e._debounceTimer=null;const t=e._pendingEvent;e._pendingEvent=null,t&&this._executeTrigger(e,t)},e.debounceMs)}_scheduleBatch(){this._batchTimer||(this._batchTimer=setTimeout(()=>{this._batchTimer=null,this._processBatch()},this._config.batchIntervalMs))}async _processBatch(){const e=[...this._batchQueue];this._batchQueue=[];const t=new Map;for(const{trigger:s,eventData:r}of e)t.set(s.name,{trigger:s,eventData:r});for(const{trigger:e,eventData:s}of t.values())await this._executeTrigger(e,s)}async _executeTrigger(t,s){try{const r=t.buildPrompt(s);if(!r)return this._stats.totalSkipped++,null;e.wuDebug(`[wu-ai] Trigger '${t.name}' firing with prompt: ${r.slice(0,100)}...`);const o=await this._conversation.send(r,{namespace:t.namespace,systemPrompt:t.systemPrompt,temperature:t.temperature,maxTokens:t.maxTokens});if(t._fireCount++,t._lastFired=Date.now(),this._stats.totalFired++,this._eventBus.emit("ai:trigger:result",{trigger:t.name,pattern:t.pattern,result:o},{appName:"wu-ai"}),t.onResult)try{await t.onResult(o,s)}catch(s){e.wuDebug(`[wu-ai] Trigger '${t.name}' onResult error: ${s.message}`)}return o}catch(s){return this._stats.totalErrors++,e.wuWarn(`[wu-ai] Trigger '${t.name}' error: ${s.message}`),this._eventBus.emit("ai:trigger:error",{trigger:t.name,error:s.message},{appName:"wu-ai"}),null}}getStats(){const e={};for(const[t,s]of this._triggers)e[t]={pattern:s.pattern,priority:s.priority,enabled:s.enabled,fireCount:s._fireCount,lastFired:s._lastFired};return{...this._stats,triggerCount:this._triggers.size,batchQueueSize:this._batchQueue.length,triggers:e}}}const I="[DONE]",O="agent:";class B{constructor({conversation:e,actions:t,context:s,permissions:r,eventBus:o}){this._conversation=e,this._actions=t,this._context=s,this._permissions=r,this._eventBus=o,this._config={maxSteps:10,systemPrompt:null},this._activeRuns=new Map,this._stats={totalRuns:0,totalSteps:0,completedRuns:0,abortedRuns:0,errorRuns:0}}configure(e){void 0!==e.maxSteps&&(this._config.maxSteps=e.maxSteps),void 0!==e.systemPrompt&&(this._config.systemPrompt=e.systemPrompt)}async*run(t,s={}){const r=s.maxSteps??this._config.maxSteps,o=s.namespace||this._generateNamespace(),i=this._generateRunId(),n=new AbortController;this._activeRuns.set(i,n),s.signal&&(s.signal.aborted?n.abort():s.signal.addEventListener("abort",()=>n.abort(),{once:!0})),this._stats.totalRuns++;const a=await this._buildAgentSystemPrompt(t,s);this._eventBus.emit("ai:agent:start",{runId:i,goal:t,namespace:o,maxSteps:r},{appName:"wu-ai"}),e.wuInfo(`[wu-ai] Agent run started: "${t.slice(0,80)}${t.length>80?"...":""}" (max ${r} steps)`);let c=0,l=!1,u="max_steps";try{for(;c<r;){c++;const e=Date.now();if(n.signal.aborted){const t=this._buildStepResult(c,"aborted",{reason:"Aborted by caller",elapsed:Date.now()-e});return this._stats.abortedRuns++,u="aborted",this._emitStep(i,t),void(yield t)}const r=this._permissions.loopProtection.createTraceId(),p=this._permissions.preflight({namespace:o,depth:c,traceId:r});if(!p.allowed){const t=this._buildStepResult(c,"blocked",{reason:p.reason,elapsed:Date.now()-e});return u="blocked",this._emitStep(i,t),void(yield t)}const h=1===c?t:"Continue working toward the goal. If you are done, include [DONE] in your response.";let m;try{m=await this._conversation.send(h,{namespace:o,systemPrompt:a,provider:s.provider,temperature:s.temperature,maxTokens:s.maxTokens,signal:n.signal})}catch(t){if("AbortError"===t.name||n.signal.aborted){const t=this._buildStepResult(c,"aborted",{reason:"Aborted during LLM call",elapsed:Date.now()-e});return this._stats.abortedRuns++,u="aborted",this._emitStep(i,t),void(yield t)}throw t}const d=Date.now()-e;this._stats.totalSteps++;const _=m.tool_results&&m.tool_results.length>0,g=m.content||"";if(g.includes(I)){const e=this._buildStepResult(c,"done",{content:g.replace(I,"").trim(),toolResults:m.tool_results,usage:m.usage,reason:"Goal completed (DONE marker)",elapsed:d});return u="done",this._stats.completedRuns++,this._emitStep(i,e),s.onStep&&await this._safeCallback(s.onStep,e),void(yield e)}const f=_;if(l&&!f){const e=this._buildStepResult(c,"done",{content:g,toolResults:m.tool_results,usage:m.usage,reason:"Goal completed (no further tool calls)",elapsed:d});return u="done",this._stats.completedRuns++,this._emitStep(i,e),s.onStep&&await this._safeCallback(s.onStep,e),void(yield e)}l=f;const w=_?"tool_call":"thinking",y=this._buildStepResult(c,w,{content:g,toolResults:m.tool_results,usage:m.usage,elapsed:d});if(this._emitStep(i,y),s.onStep&&await this._safeCallback(s.onStep,y),yield y,s.shouldContinue){let e;try{e=await s.shouldContinue(y)}catch{e=!1}if(!e){const e=this._buildStepResult(c,"interrupted",{content:g,reason:"Stopped by shouldContinue callback",elapsed:0});return u="interrupted",this._emitStep(i,e),void(yield e)}}}const e=this._buildStepResult(c,"done",{reason:`Max steps (${r}) reached`,elapsed:0});u="max_steps",yield e}catch(s){throw this._stats.errorRuns++,u="error",e.wuWarn(`[wu-ai] Agent run error: ${s.message}`),this._eventBus.emit("ai:agent:error",{runId:i,goal:t,namespace:o,step:c,error:s.message},{appName:"wu-ai"}),s}finally{this._activeRuns.delete(i),!s.namespace&&o.startsWith(O)&&this._conversation.deleteNamespace(o),this._eventBus.emit("ai:agent:done",{runId:i,goal:t,namespace:o,totalSteps:c,reason:u},{appName:"wu-ai"}),e.wuDebug(`[wu-ai] Agent run finished: ${u} after ${c} step(s)`)}}abort(t){const s=this._activeRuns.get(t);s&&(s.abort(),e.wuDebug(`[wu-ai] Agent run aborted: ${t}`))}abortAll(){for(const[e,t]of this._activeRuns)t.abort();this._activeRuns.clear()}getActiveRuns(){return[...this._activeRuns.keys()]}getStats(){return{...this._stats,activeRuns:this._activeRuns.size,config:{...this._config}}}destroy(){this.abortAll(),this._stats={totalRuns:0,totalSteps:0,completedRuns:0,abortedRuns:0,errorRuns:0}}async _buildAgentSystemPrompt(e,t){const s=t.systemPrompt??this._config.systemPrompt??null;if(s){return"function"==typeof s?await s(e):s}const r=[];if(r.push("You are an autonomous AI agent connected to a live web application via Wu Framework.","You have been given a goal and must work step-by-step to achieve it.","","PROTOCOL:",'- Each message you send is one "step" in your execution.',"- You may call tools to read or modify application state.","- After each step, you will be prompted to continue.","- When the goal is fully achieved, include the marker [DONE] in your response.","- If you determine the goal cannot be achieved, include [DONE] and explain why.","- Be concise. Each step should make meaningful progress.",""),this._context)try{await this._context.collect();const e=this._context.getSnapshot();e?._mountedApps?.length&&r.push(`MOUNTED APPS: ${e._mountedApps.join(", ")}`,""),e?._store&&Object.keys(e._store).length>0&&r.push(`APPLICATION STATE:\n${JSON.stringify(e._store,null,2)}`,"")}catch{}const o=this._actions.getToolSchemas();if(o.length>0){r.push("AVAILABLE TOOLS:");for(const e of o){const t=e.parameters?.properties?Object.keys(e.parameters.properties).join(", "):"none";r.push(`- ${e.name}(${t}): ${e.description}`)}r.push("")}return r.push(`GOAL: ${e}`),r.join("\n")}_buildStepResult(e,t,s={}){return{step:e,type:t,content:s.content??null,toolResults:s.toolResults??null,usage:s.usage??null,reason:s.reason??null,elapsed:s.elapsed??0}}_emitStep(e,t){this._eventBus.emit("ai:agent:step",{runId:e,...t},{appName:"wu-ai"})}async _safeCallback(t,...s){try{const e=t(...s);e&&"function"==typeof e.then&&await e}catch(t){e.wuDebug(`[wu-ai] Agent callback error: ${t.message}`)}}_generateNamespace(){return O+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,6)}_generateRunId(){return"run_"+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,8)}}function j(e,r,o){switch(e.action){case"click":{const s=t(e.selector,e.text);return s.error?{success:!1,error:s.error}:{success:!0,detail:`Clicked: ${e.selector||e.text}`}}case"type":{const t=s(e.selector,e.value,{clear:e.clear??!0,submit:e.submit??!1});return t.error?{success:!1,error:t.error}:{success:!0,detail:`Typed "${e.value}" into ${e.selector}`}}case"navigate":if(r&&e.section)return r.emit("nav:section",{section:e.section},{appName:"wu-ai"}),{success:!0,detail:`Navigated to section: ${e.section}`};if(e.selector){const s=t(e.selector,e.text);return s.error?{success:!1,error:s.error}:{success:!0,detail:`Navigated via click: ${e.selector}`}}return{success:!1,error:'navigate requires "section" or "selector"'};case"wait":return{success:!0,detail:`Wait: ${e.ms||0}ms`};case"emit":return r?(r.emit(e.event,e.data||{},{appName:"wu-ai"}),{success:!0,detail:`Emitted: ${e.event}`}):{success:!1,error:"eventBus not available"};case"setState":return o?(o.set(e.path,e.value),{success:!0,detail:`Set state: ${e.path}`}):{success:!1,error:"store not available"};default:return{success:!1,error:`Unknown action: ${e.action}`}}}function L(e,t=5e3){return new Promise(s=>{if(document.querySelector(e))return void s(!0);let r=0;const o=setInterval(()=>{r+=100,document.querySelector(e)?(clearInterval(o),s(!0)):r>=t&&(clearInterval(o),s(!1))},100)})}function q(e){return new Promise(t=>setTimeout(t,e))}class F{constructor({actions:e,conversation:t,context:s,permissions:r,eventBus:o,agent:i,store:n}){this._actions=e,this._conversation=t,this._context=s,this._permissions=r,this._eventBus=o,this._agent=i,this._store=n,this._capabilities=new Map,this._workflows=new Map,this._config={defaultProvider:null,defaultTemperature:.3},this._stats={totalIntents:0,resolvedIntents:0,failedIntents:0,workflowsRegistered:0,workflowsExecuted:0}}configure(e){void 0!==e.defaultProvider&&(this._config.defaultProvider=e.defaultProvider),void 0!==e.defaultTemperature&&(this._config.defaultTemperature=e.defaultTemperature)}register(t,s,r){if(!t||!s)throw new Error("[wu-ai] capability() requires both appName and actionName");if(!r||"function"!=typeof r.handler)throw new Error(`[wu-ai] capability '${t}:${s}' must have a handler function`);const o=`${t}:${s}`;this._capabilities.has(t)||this._capabilities.set(t,new Map),this._capabilities.get(t).set(s,{description:r.description||s,qualifiedName:o}),this._actions.register(o,{...r,description:`[${t}] ${r.description||s}`}),e.wuDebug(`[wu-ai] Capability registered: ${o}`)}unregister(e,t){const s=this._capabilities.get(e);if(!s)return;const r=`${e}:${t}`;s.delete(t),this._actions.unregister(r),0===s.size&&this._capabilities.delete(e)}removeApp(t){const s=this._capabilities.get(t);if(!s)return 0;let r=0;for(const[e]of s){const s=`${t}:${e}`;this._actions.unregister(s),r++}return this._capabilities.delete(t),e.wuDebug(`[wu-ai] All capabilities removed for app '${t}' (${r})`),this._eventBus.emit("ai:app:removed",{appName:t,capabilitiesRemoved:r},{appName:"wu-ai"}),r}getCapabilityMap(){const e={};for(const[t,s]of this._capabilities){e[t]=[];for(const[,r]of s)e[t].push({action:r.qualifiedName,description:r.description})}return e}getRegisteredApps(){return[...this._capabilities.keys()]}hasApp(e){return this._capabilities.has(e)}getTotalCapabilities(){let e=0;for(const t of this._capabilities.values())e+=t.size;return e}async resolve(e,t={}){if(!e||"string"!=typeof e)throw new Error("[wu-ai] intent() requires a description string");this._stats.totalIntents++;const s=this._generateNamespace();if(this._context)try{await this._context.collect()}catch{}const r=this._buildOrchestratorPrompt(t);this._eventBus.emit("ai:intent:start",{description:e.slice(0,200),namespace:s,capabilities:this.getTotalCapabilities()},{appName:"wu-ai"});try{const o=await this._conversation.send(e,{namespace:s,systemPrompt:r,provider:t.provider||this._config.defaultProvider,temperature:t.temperature??this._config.defaultTemperature,maxTokens:t.maxTokens,signal:t.signal,responseFormat:t.responseFormat}),i=o.tool_results||[],n=this._extractInvolvedApps(i),a=!!o.content;a?this._stats.resolvedIntents++:this._stats.failedIntents++;const c={content:o.content||"",tool_results:i,usage:o.usage||null,resolved:a,appsInvolved:n};return this._eventBus.emit("ai:intent:resolved",{description:e.slice(0,200),resolved:a,appsInvolved:n},{appName:"wu-ai"}),c}catch(t){throw this._stats.failedIntents++,this._eventBus.emit("ai:intent:error",{description:e.slice(0,200),error:t.message},{appName:"wu-ai"}),t}finally{this._conversation.deleteNamespace(s)}}buildOrchestratorPrompt(e={}){return this._buildOrchestratorPrompt(e)}_buildOrchestratorPrompt(e={}){const t=[];t.push("You are an AI orchestrator for a microfrontend application.","Multiple independent apps are mounted, each with specific capabilities.","Resolve cross-app requests by calling the right capabilities in the right order.","","RULES:","- Call capabilities (tools) to gather data or trigger actions.","- You may call multiple capabilities from different apps if needed.","- Synthesize results into a clear, actionable response.","- If a required app is not available or lacks a capability, explain what is missing.","");const s=this.getCapabilityMap(),r=Object.keys(s);if(r.length>0){t.push("CAPABILITY MAP:");for(const e of r){t.push(` ${e}:`);for(const r of s[e])t.push(` - ${r.action}: ${r.description}`)}t.push("")}else t.push("NOTE: No app capabilities are registered. Answer based on available context only.","");if(e.plan&&e.plan.length>0){t.push("SUGGESTED PLAN (follow this unless a better approach is evident):");for(let s=0;s<e.plan.length;s++)t.push(` ${s+1}. ${e.plan[s]}`);t.push("")}const o=this._context?.getSnapshot();return o?._mountedApps?.length&&t.push(`MOUNTED APPS: ${o._mountedApps.join(", ")}`,""),o?._store&&Object.keys(o._store).length>0&&t.push("CURRENT STATE:",JSON.stringify(o._store,null,2),""),t.join("\n")}registerWorkflow(t,s){if(!t)throw new Error("[wu-ai] workflow() requires a name");if(!s||!s.steps||!Array.isArray(s.steps)||0===s.steps.length)throw new Error(`[wu-ai] workflow '${t}' must have a non-empty steps array`);const r=s.mode||(s.steps.length>0&&"object"==typeof s.steps[0]&&s.steps[0].action?"deterministic":"ai");this._workflows.set(t,{description:s.description||t,steps:s.steps,mode:r,parameters:s.parameters||{},maxSteps:s.maxSteps??15,provider:s.provider||null,temperature:s.temperature??.2}),this._stats.workflowsRegistered++,e.wuDebug(`[wu-ai] Workflow registered: '${t}' (${s.steps.length} steps)`)}async*executeWorkflow(e,t={},s={}){const r=this._workflows.get(e);if(!r)throw new Error(`[wu-ai] Workflow '${e}' is not registered`);for(const[s,o]of Object.entries(r.parameters))if(o.required&&(void 0===t[s]||null===t[s]))throw new Error(`[wu-ai] Workflow '${e}' requires parameter '${s}'`);this._stats.workflowsExecuted++,"deterministic"===r.mode?yield*this._executeDeterministic(e,r,t,s):yield*this._executeWithAgent(e,r,t,s)}async*_executeWithAgent(e,t,s,r){if(!this._agent)throw new Error("[wu-ai] Agent module not available for workflow execution");const o=t.steps.map(e=>{let t=e;for(const[e,r]of Object.entries(s))t=t.replace(new RegExp(`\\{\\{${e}\\}\\}`,"g"),String(r));return t}),i=this._buildWorkflowGoal(t,o,s);this._eventBus.emit("ai:workflow:start",{workflow:e,mode:"ai",params:s,steps:o.length},{appName:"wu-ai"});let n=null;try{yield*this._agent.run(i,{maxSteps:t.maxSteps,provider:r.provider||t.provider||this._config.defaultProvider,temperature:t.temperature??.2,onStep:e=>{n=e,r.onStep&&r.onStep(e)},shouldContinue:r.shouldContinue,signal:r.signal})}finally{this._eventBus.emit("ai:workflow:done",{workflow:e,params:s,totalSteps:n?.step||0,result:n?.type||"unknown"},{appName:"wu-ai"})}}async*_executeDeterministic(e,t,s,r){const o=t.steps.map(e=>{const t={...e};for(const[e,r]of Object.entries(s)){const s=new RegExp(`\\{\\{${e}\\}\\}`,"g");for(const e of["value","selector","text","section","event","path"])"string"==typeof t[e]&&(t[e]=t[e].replace(s,String(r)))}return t});this._eventBus?.emit("ai:workflow:start",{workflow:e,mode:"deterministic",params:s,steps:o.length},{appName:"wu-ai"});let i=null;try{for(let e=0;e<o.length;e++){const t=o[e],s=e+1,n=Date.now();if(r.signal?.aborted){const e={step:s,type:"aborted",content:"Workflow aborted",reason:"Aborted by caller",elapsed:0};return i=e,void(yield e)}if("wait"===t.action){if(t.selector){const e=await L(t.selector,t.timeout||5e3),o=Date.now()-n,a={step:s,type:e?"action":"error",content:e?`Waited for "${t.selector}" — found`:`Timeout waiting for "${t.selector}"`,elapsed:o};if(i=a,r.onStep&&r.onStep(a),yield a,!e)return}else if(t.ms){await q(t.ms);const e={step:s,type:"action",content:`Waited ${t.ms}ms`,elapsed:t.ms};i=e,r.onStep&&r.onStep(e),yield e}continue}const a=j(t,this._eventBus,this._store),c=Date.now()-n,l={step:s,type:a.success?"action":"error",content:a.success?a.detail:a.error,elapsed:c};if(i=l,r.onStep&&r.onStep(l),yield l,r.shouldContinue){let e;try{e=await r.shouldContinue(l)}catch{e=!1}if(!e){const e={step:s,type:"interrupted",content:"Stopped by user",reason:"shouldContinue returned false",elapsed:0};return i=e,void(yield e)}}if(!a.success)return;e<o.length-1&&await q(t.delay??200)}const t={step:o.length,type:"done",content:`Workflow "${e}" completed (${o.length} steps)`,reason:"All steps executed",elapsed:0};i=t,r.onStep&&r.onStep(t),yield t}finally{this._eventBus?.emit("ai:workflow:done",{workflow:e,mode:"deterministic",params:s,totalSteps:i?.step||0,result:i?.type||"unknown"},{appName:"wu-ai"})}}hasWorkflow(e){return this._workflows.has(e)}getWorkflow(e){const t=this._workflows.get(e);return t?{description:t.description,steps:[...t.steps],mode:t.mode,parameters:{...t.parameters},maxSteps:t.maxSteps}:null}removeWorkflow(e){this._workflows.delete(e)}getWorkflowNames(){return[...this._workflows.keys()]}_buildWorkflowGoal(e,t,s){const r=[];r.push(`WORKFLOW: ${e.description}`,"","You must follow these steps IN ORDER. Use browser tools (screenshot, click, type)","to interact with the application. After each step, take a screenshot to verify.","","STEPS:");for(let e=0;e<t.length;e++)r.push(` ${e+1}. ${t[e]}`);r.push("","After completing all steps successfully, respond with [DONE].","If a step fails, explain what went wrong.");const o=this.getCapabilityMap(),i=Object.keys(o);if(i.length>0){r.push("","AVAILABLE APP CAPABILITIES:");for(const e of i)for(const t of o[e])r.push(` - ${t.action}: ${t.description}`)}return r.join("\n")}getStats(){return{...this._stats,registeredApps:this.getRegisteredApps(),totalCapabilities:this.getTotalCapabilities(),capabilityMap:this.getCapabilityMap(),workflows:this.getWorkflowNames(),config:{...this._config}}}destroy(){for(const[e,t]of this._capabilities)for(const[s]of t)this._actions.unregister(`${e}:${s}`);this._capabilities.clear(),this._workflows.clear(),this._stats={totalIntents:0,resolvedIntents:0,failedIntents:0,workflowsRegistered:0,workflowsExecuted:0}}_extractInvolvedApps(e){if(!e||!Array.isArray(e))return[];const t=new Set;for(const s of e){const e=s.name||s.tool||"",r=e.indexOf(":");r>0&&t.add(e.slice(0,r))}return[...t]}_generateNamespace(){return"intent:"+Date.now().toString(36)+"_"+Math.random().toString(36).slice(2,6)}}class W{constructor({eventBus:e,store:t,core:s,token:r}){this._store=t,this._core=s,this._initialized=!1,this._modules={},this._token=r||null,this._eventBus=this._wrapEventBus(e)}_wrapEventBus(e){if(!this._token)return e;const t=this._token;return new Proxy(e,{get(e,s){if("emit"===s)return function(s,r,o={}){return e.emit(s,r,{...o,appName:o.appName||"wu-ai",token:o.token||t})};const r=Reflect.get(e,s);return"function"==typeof r?r.bind(e):r}})}init(u={}){return this._initialized?(this._reconfigure(u),this):(this._modules.permissions=new x({permissions:u.permissions,rateLimit:u.rateLimit,circuitBreaker:u.circuitBreaker,loopProtection:u.loopProtection,allowedDomains:u.allowedDomains}),this._modules.provider=new d,this._modules.context=new C({store:this._store,eventBus:this._eventBus,core:this._core}),u.context&&this._modules.context.configure(u.context),this._modules.actions=new A({eventBus:this._eventBus,store:this._store,permissions:this._modules.permissions}),this._modules.conversation=new R({provider:this._modules.provider,actions:this._modules.actions,context:this._modules.context,permissions:this._modules.permissions,eventBus:this._eventBus}),u.conversation&&this._modules.conversation.configure(u.conversation),this._modules.triggers=new E({eventBus:this._eventBus,conversation:this._modules.conversation,permissions:this._modules.permissions}),u.triggers&&this._modules.triggers.configure(u.triggers),this._modules.agent=new B({conversation:this._modules.conversation,actions:this._modules.actions,context:this._modules.context,permissions:this._modules.permissions,eventBus:this._eventBus}),u.agent&&this._modules.agent.configure(u.agent),this._modules.orchestrate=new F({actions:this._modules.actions,conversation:this._modules.conversation,context:this._modules.context,permissions:this._modules.permissions,eventBus:this._eventBus,agent:this._modules.agent,store:this._store}),u.orchestrate&&this._modules.orchestrate.configure(u.orchestrate),this._initialized=!0,e.wuInfo("[wu-ai] Initialized"),"undefined"!=typeof window&&(p=this,h=this._core,r(),p.action("browser_screenshot",{description:"Take a screenshot of the current page or a specific element. Returns a base64 PNG image. Use this to SEE what the user sees.",parameters:{selector:{type:"string",description:"CSS selector of the element to capture. Empty = full visible page.",required:!1}},handler:async e=>o(e.selector),permissions:[]}),p.action("browser_click",{description:"Click an element on the page. Find by CSS selector or by visible text content. Use this to interact with buttons, links, tabs, etc.",parameters:{selector:{type:"string",description:'CSS selector (e.g. "#submit-btn", ".nav-link", "button[type=submit]")',required:!1},text:{type:"string",description:'Visible text to find and click (e.g. "Submit", "Next", "Guardar"). Searches buttons, links, and clickable elements.',required:!1}},handler:async(e,s)=>{const r=t(e.selector,e.text);return r.error||s.emit?.("browser:clicked",{selector:e.selector,text:e.text}),r},permissions:["emitEvents"]}),p.action("browser_type",{description:"Type text into an input, textarea, or contenteditable element. Works with React, Vue, Angular, and other frameworks. Can optionally clear existing text first and submit the form.",parameters:{selector:{type:"string",description:'CSS selector of the input (e.g. "#email", "input[name=search]", "textarea.comment")',required:!0},text:{type:"string",description:"Text to type into the element",required:!0},clear:{type:"boolean",description:"Clear existing value before typing (default: false)",required:!1},submit:{type:"boolean",description:"Submit the form or press Enter after typing (default: false)",required:!1}},handler:async(e,t)=>{const r=s(e.selector,e.text,{clear:e.clear,submit:e.submit});return r.error||t.emit?.("browser:typed",{selector:e.selector,length:e.text.length}),r},permissions:["emitEvents"]}),p.action("browser_select",{description:"Select an option in a <select> dropdown or a custom dropdown component.",parameters:{selector:{type:"string",description:"CSS selector of the <select> element",required:!0},value:{type:"string",description:'The value attribute of the option to select. Use "text:" prefix to match by visible text (e.g. "text:Mexico")',required:!0}},handler:async(e,t)=>{const s=document.querySelector(e.selector);if(!s)return{error:`Element not found: ${e.selector}`};if("select"===s.tagName?.toLowerCase()){const r=Array.from(s.options);let o;if(e.value.startsWith("text:")){const t=e.value.slice(5).toLowerCase();o=r.find(e=>e.textContent.trim().toLowerCase().includes(t))}else o=r.find(t=>t.value===e.value);return o?(s.value=o.value,s.dispatchEvent(new Event("change",{bubbles:!0})),s.dispatchEvent(new Event("input",{bubbles:!0})),t.emit?.("browser:selected",{selector:e.selector,value:o.value}),{selected:o.value,text:o.textContent.trim()}):{error:`Option not found: ${e.value}`}}return s.click(),{clicked:e.selector,note:"Custom dropdown — clicked trigger. Use browser_click to select an option from the opened menu."}},permissions:["emitEvents"]}),p.action("browser_scroll",{description:"Scroll the page or a specific element. Use to reveal content that is not visible.",parameters:{direction:{type:"string",description:'Direction: "up", "down", "top", "bottom"',required:!0},selector:{type:"string",description:"CSS selector of scrollable container (empty = page)",required:!1},amount:{type:"number",description:'Pixels to scroll (default: 500). Ignored for "top"/"bottom".',required:!1}},handler:async e=>{const t=e.selector?document.querySelector(e.selector):window,s=e.amount||500;if(e.selector&&!t)return{error:`Element not found: ${e.selector}`};const r=t===window?document.documentElement:t;switch(e.direction){case"up":r.scrollBy({top:-s,behavior:"smooth"});break;case"down":r.scrollBy({top:s,behavior:"smooth"});break;case"top":r.scrollTo({top:0,behavior:"smooth"});break;case"bottom":r.scrollTo({top:r.scrollHeight,behavior:"smooth"});break;default:return{error:`Invalid direction: ${e.direction}`}}return{scrolled:e.direction,amount:"top"===e.direction||"bottom"===e.direction?"max":s,currentScroll:r.scrollTop}},permissions:[]}),p.action("browser_snapshot",{description:"Get a text representation of the visible DOM structure (accessibility tree). Use this to understand what elements are on the page, their roles, IDs, and text content. Cheaper and faster than a screenshot.",parameters:{selector:{type:"string",description:'CSS selector to snapshot (empty = full page). Use "[data-wu-app=appName]" for a specific micro-app.',required:!1},depth:{type:"number",description:"Max depth to traverse (default: 5)",required:!1}},handler:async e=>{const t=e.selector?document.querySelector(e.selector):document.body;return t?{snapshot:i(t,0,e.depth||5)}:{error:`Element not found: ${e.selector}`}},permissions:[]}),p.action("browser_navigate",{description:"Navigate to a route within the SPA application. Emits a shell:navigate event and updates the store.",parameters:{route:{type:"string",description:'Route path (e.g. "/dashboard", "/users", "/pos/cotizador")',required:!0}},handler:async(e,t)=>(t.emit?.("shell:navigate",{route:e.route}),t.setState?.("currentPath",e.route),{navigated:e.route}),permissions:["emitEvents","writeStore"]}),p.action("browser_network",{description:"View captured HTTP network requests (fetch and XHR). Shows URL, method, status code, duration, and size. Use to debug API calls, check for errors, or monitor performance.",parameters:{method:{type:"string",description:"Filter by HTTP method: GET, POST, PUT, DELETE (empty = all)",required:!1},status:{type:"string",description:'Filter: "2" (2xx success), "4" (4xx errors), "5" (5xx errors), "error" (all failures)',required:!1},limit:{type:"number",description:"Max requests to return (default: 30)",required:!1}},handler:async e=>n(e.method,e.status,e.limit),permissions:[]}),p.action("browser_console",{description:"View captured browser console messages (log, warn, error). Use to check for errors, warnings, or debug output.",parameters:{level:{type:"string",description:'Filter by level: "log", "warn", "error" (empty = all)',required:!1},limit:{type:"number",description:"Max messages to return (default: 30)",required:!1}},handler:async e=>a(e.level,e.limit),permissions:[]}),p.action("browser_info",{description:"Get an overview of the current page state: URL, viewport size, mounted micro-apps, store keys, visible elements summary. Use this FIRST to understand the page before taking actions.",parameters:{},handler:async(e,t)=>{const s=[];if(h._apps)for(const[e,t]of Object.entries(h._apps))s.push({name:e,mounted:t.mounted||t.isMounted||!1,status:t.status||"unknown"});0===s.length&&document.querySelectorAll("[data-wu-app]").forEach(e=>{s.push({name:e.getAttribute("data-wu-app"),mounted:!0})});const r=t.getState?.("")||{},o="object"==typeof r?Object.keys(r):[];return{url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},apps:s,storeKeys:o,networkRequests:l.length,consoleMessages:c.length,consoleErrors:c.filter(e=>"error"===e.level).length}},permissions:["readStore"]}),e.wuInfo("[wu-ai] Browser actions registered (10 tools)")),this._eventBus.emit("ai:initialized",{},{appName:"wu-ai"}),this);var p,h}provider(e,t){return this._ensureInit(),this._modules.provider.register(e,t),this}async send(e,t={}){return this._ensureInit(),this._modules.conversation.send(e,t)}async*stream(e,t={}){this._ensureInit(),yield*this._modules.conversation.stream(e,t)}async json(e,t={}){this._ensureInit();const{schema:s,schemaName:r,...o}=t;let i;i=s?{type:"json_schema",schema:s,name:r||"response"}:t.responseFormat||"json";const n=await this._modules.conversation.send(e,{...o,responseFormat:i});let a,c=null;if(void 0!==n.parsed)c=n.parsed;else if(n.content)try{c=JSON.parse(n.content)}catch{a="LLM response is not valid JSON"}return{data:c,raw:n.content||"",error:a||n.parseError,usage:n.usage,namespace:n.namespace}}abort(e){this._initialized&&(e?this._modules.conversation.abort(e):this._modules.conversation.abortAll())}action(e,t){return this._ensureInit(),this._modules.actions.register(e,t),this}async execute(e,t){this._ensureInit();const s=this._modules.permissions.loopProtection.createTraceId();return this._modules.actions.execute(e,t,{traceId:s,depth:0})}trigger(e,t){return this._ensureInit(),this._modules.triggers.register(e,t),this}async fireTrigger(e,t){return this._ensureInit(),this._modules.triggers.fire(e,t)}async*agent(e,t={}){this._ensureInit(),yield*this._modules.agent.run(e,t)}capability(e,t,s){return this._ensureInit(),this._modules.orchestrate.register(e,t,s),this}async intent(e,t={}){return this._ensureInit(),this._modules.orchestrate.resolve(e,t)}removeApp(e){return this._ensureInit(),this._modules.orchestrate.removeApp(e),this}workflow(e,t){return this._ensureInit(),this._modules.orchestrate.registerWorkflow(e,t),this}async*runWorkflow(e,t={},s={}){this._ensureInit(),yield*this._modules.orchestrate.executeWorkflow(e,t,s)}get context(){return this._ensureInit(),{configure:e=>this._modules.context.configure(e),register:(e,t)=>this._modules.context.register(e,t),collect:()=>this._modules.context.collect(),getSnapshot:()=>this._modules.context.getSnapshot()}}get conversation(){return this._ensureInit(),{getHistory:e=>this._modules.conversation.getHistory(e),clear:e=>this._modules.conversation.clear(e),clearAll:()=>this._modules.conversation.clearAll(),inject:(e,t,s)=>this._modules.conversation.inject(e,t,s),getNamespaces:()=>this._modules.conversation.getNamespaces(),deleteNamespace:e=>this._modules.conversation.deleteNamespace(e)}}get permissions(){return this._ensureInit(),{configure:e=>this._modules.permissions.configure(e),check:e=>this._modules.permissions.check(e),getPermissions:()=>this._modules.permissions.getPermissions(),setAllowedDomains:e=>this._modules.permissions.setAllowedDomains(e)}}tools(){return this._ensureInit(),this._modules.actions.getToolSchemas()}expose(){if(this._ensureInit(),"undefined"==typeof navigator||!navigator.modelContext)return e.wuDebug("[wu-ai] WebMCP not available (navigator.modelContext missing)"),!1;const t=this._modules.actions.getToolSchemas(),s=this._modules.actions.getNames();for(let r=0;r<t.length;r++){const o=t[r],i=s[r];try{navigator.modelContext.registerTool({name:o.name,description:o.description,inputSchema:o.parameters,handler:async e=>{const t=await this.execute(i,e);return t.success?t.result:{error:t.reason}}})}catch(t){e.wuDebug(`[wu-ai] WebMCP register failed for '${o.name}': ${t.message}`)}}return e.wuInfo(`[wu-ai] Exposed ${t.length} tools via WebMCP`),this._eventBus.emit("ai:webmcp:exposed",{toolCount:t.length,tools:t.map(e=>e.name)},{appName:"wu-ai"}),!0}confirmTool(e){this._initialized&&this._modules.actions.confirmTool(e)}rejectTool(e){this._initialized&&this._modules.actions.rejectTool(e)}getStats(){return this._initialized?{initialized:!0,provider:this._modules.provider.getStats(),permissions:this._modules.permissions.getStats(),context:this._modules.context.getStats(),actions:this._modules.actions.getStats(),conversation:this._modules.conversation.getStats(),triggers:this._modules.triggers.getStats(),agent:this._modules.agent.getStats(),orchestrate:this._modules.orchestrate.getStats()}:{initialized:!1}}destroy(){this._initialized&&(this._modules.orchestrate.destroy(),this._modules.agent.destroy(),this._modules.conversation.abortAll(),this._modules.triggers.destroy(),this._modules={},this._initialized=!1,e.wuInfo("[wu-ai] Destroyed"),this._eventBus.emit("ai:destroyed",{},{appName:"wu-ai"}))}_ensureInit(){this._initialized||this.init()}_reconfigure(e){e.permissions&&this._modules.permissions.configure(e.permissions),e.rateLimit&&this._modules.permissions.rateLimiter.configure(e.rateLimit),e.circuitBreaker&&this._modules.permissions.circuitBreaker.configure(e.circuitBreaker),e.loopProtection&&this._modules.permissions.loopProtection.configure(e.loopProtection),e.context&&this._modules.context.configure(e.context),e.conversation&&this._modules.conversation.configure(e.conversation),e.triggers&&this._modules.triggers.configure(e.triggers),e.agent&&this._modules.agent.configure(e.agent),e.orchestrate&&this._modules.orchestrate.configure(e.orchestrate)}}export{W as WuAI};
|
|
2
|
+
//# sourceMappingURL=wu-ai.js.map
|