Explorar o código

#5406 AI Agents revamp: agents chat

Aleksandr Trofimov hai 1 mes
pai
achega
700142beb2
Modificáronse 10 ficheiros con 536 adicións e 7 borrados
  1. 3 0
      .gitignore
  2. 72 0
      inc/classes/BxDolAI.php
  3. 3 1
      install/sql/system.sql
  4. 13 0
      package.json
  5. 18 0
      rollup.config.js
  6. 210 0
      src/chat/index.ts
  7. 15 0
      src/index.ts
  8. 34 0
      template/scripts/BxBaseServices.php
  9. 12 0
      tsconfig.json
  10. 156 6
      yarn.lock

+ 3 - 0
.gitignore

@@ -1,3 +1,6 @@
+.npm-pack
+.cursor
+
 # Exclude system cache folders
 # Exclude system cache folders
 packages/*
 packages/*
 cache/*
 cache/*

+ 72 - 0
inc/classes/BxDolAI.php

@@ -415,6 +415,78 @@ class BxDolAI extends BxDolFactory implements iBxDolSingleton
         return $mixed;
         return $mixed;
     }
     }
 
 
+    public function extractChatPromptFromRequest($aData)
+    {
+        if (!is_array($aData))
+            return '';
+
+        if (!empty($aData['prompt']) && is_string($aData['prompt']))
+            return trim($aData['prompt']);
+
+        if (empty($aData['messages']) || !is_array($aData['messages']))
+            return '';
+
+        for ($i = count($aData['messages']) - 1; $i >= 0; $i--) {
+            $aMessage = $aData['messages'][$i];
+            if (!is_array($aMessage))
+                continue;
+
+            if (($aMessage['role'] ?? '') !== 'user')
+                continue;
+
+            if (isset($aMessage['content']) && is_string($aMessage['content']))
+                return trim($aMessage['content']);
+
+            if (!empty($aMessage['parts']) && is_array($aMessage['parts'])) {
+                $aText = [];
+                foreach ($aMessage['parts'] as $aPart) {
+                    if (is_array($aPart) && ($aPart['type'] ?? '') === 'text' && isset($aPart['content']))
+                        $aText[] = $aPart['content'];
+                }
+                $s = trim(implode("\n", $aText));
+                if ($s !== '')
+                    return $s;
+            }
+        }
+
+        return '';
+    }
+
+    public function streamAgentChat($iAgentId, $sPrompt, $aParams = [], $sThreadId = null)
+    {
+        $aParams['chat_history_subindex'] = $aParams['sender_profile_id'] ?? 0;
+
+        $oAdapter = new NeuronAI\Chat\Messages\Stream\Adapters\AGUIAdapter($sThreadId);
+
+        foreach ($oAdapter->getHeaders() as $sName => $sValue)
+            header($sName . ': ' . $sValue);
+
+        if (function_exists('apache_setenv'))
+            @apache_setenv('no-gzip', '1');
+        @ini_set('zlib.output_compression', '0');
+        @ini_set('implicit_flush', '1');
+        while (ob_get_level())
+            ob_end_flush();
+
+        try {
+            $o = self::getAgentInstance((int)$iAgentId, $aParams);
+            $oHandler = $o->stream(new NeuronAI\Chat\Messages\UserMessage($sPrompt));
+
+            foreach ($oHandler->events($oAdapter) as $sEvent) {
+                echo $sEvent;
+                if (ob_get_level())
+                    ob_flush();
+                flush();
+            }
+        } catch (Exception $oException) {
+            bx_log('sys_agents', "Stream exception for agent {$iAgentId}: " . $oException->getMessage() . " INPUT:" . $sPrompt, BX_LOG_ERR);
+            echo 'data: ' . json_encode(['type' => 'RUN_ERROR', 'message' => _t('_sys_agents_exception')]) . "\n\n";
+            flush();
+        }
+
+        exit;
+    }
+
     public function sendMessengerMessage ($iSender, $iRecipient, $sMsg) 
     public function sendMessengerMessage ($iSender, $iRecipient, $sMsg) 
     {        
     {        
         $oMessengerModule = BxDolModule::getInstance('bx_messenger');
         $oMessengerModule = BxDolModule::getInstance('bx_messenger');

+ 3 - 1
install/sql/system.sql

@@ -6810,7 +6810,8 @@ CREATE TABLE IF NOT EXISTS `sys_rewrite_rules` (
 INSERT INTO `sys_rewrite_rules` (`preg`, `service`, `active`) VALUES
 INSERT INTO `sys_rewrite_rules` (`preg`, `service`, `active`) VALUES
 ('^sys-action/(.*)$', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"wiki_action";s:6:"params";a:2:{i:0;s:3:"sys";i:1;s:3:"{1}";}s:5:"class";s:16:"TemplServiceWiki";}', '1'),
 ('^sys-action/(.*)$', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"wiki_action";s:6:"params";a:2:{i:0;s:3:"sys";i:1;s:3:"{1}";}s:5:"class";s:16:"TemplServiceWiki";}', '1'),
 ('^home/?$', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:13:\"home_redirect\";s:6:\"params\";a:0:{}}', 1),
 ('^home/?$', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:13:\"home_redirect\";s:6:\"params\";a:0:{}}', 1),
-('^sys-agent-form-input/(.*)$', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:25:\"call_agent_for_form_input\";s:6:\"params\";a:1:{i:0;s:3:\"{1}\";}s:5:\"class\";s:13:\"TemplServices\";}', 1);
+('^sys-agent-form-input/(.*)$', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:25:\"call_agent_for_form_input\";s:6:\"params\";a:1:{i:0;s:3:\"{1}\";}s:5:\"class\";s:13:\"TemplServices\";}', 1),
+('^sys-ai-chat/(.*)$', 'a:4:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:7:\"ai_chat\";s:6:\"params\";a:1:{i:0;s:3:\"{1}\";}s:5:\"class\";s:13:\"TemplServices\";}', 1);
 
 
 -- --------------------------------------------------------
 -- --------------------------------------------------------
 
 
@@ -7494,6 +7495,7 @@ INSERT INTO `sys_preloader`(`module`, `type`, `content`, `active`, `order`) VALU
 ('system', 'js_system', 'BxDolNestedForm.js', 1, 43),
 ('system', 'js_system', 'BxDolNestedForm.js', 1, 43),
 ('system', 'js_system', 'BxDolConnection.js', 1, 44),
 ('system', 'js_system', 'BxDolConnection.js', 1, 44),
 ('system', 'js_system', 'BxDolSockets.js', 1, 45),
 ('system', 'js_system', 'BxDolSockets.js', 1, 45),
+('system', 'js_system', 'bundle.js', 1, 46),
 
 
 ('system', 'js_translation', '_Are_you_sure', 1, 1),
 ('system', 'js_translation', '_Are_you_sure', 1, 1),
 ('system', 'js_translation', '_error occured', 1, 2),
 ('system', 'js_translation', '_error occured', 1, 2),

+ 13 - 0
package.json

@@ -143,17 +143,30 @@
     "build:jekyll-toc": "cp node_modules/jekyll-toc/toc.js plugins_public; patch -p1 < patches/plugins_public_toc-js.txt",
     "build:jekyll-toc": "cp node_modules/jekyll-toc/toc.js plugins_public; patch -p1 < patches/plugins_public_toc-js.txt",
     "build:urijs": "cp node_modules/urijs/src/URI.min.js plugins_public",
     "build:urijs": "cp node_modules/urijs/src/URI.min.js plugins_public",
     "build:stripe": "mkdir -p plugins_public/stripe; cp -r node_modules/@stripe/connect-js/dist/ plugins_public/stripe",
     "build:stripe": "mkdir -p plugins_public/stripe; cp -r node_modules/@stripe/connect-js/dist/ plugins_public/stripe",
+    "build:bundle": "mkdir -p plugins_public && rollup -c rollup.config.js",
     "build": "mkdir -p plugins_public; rm -rf plugins_public/*; npm run install-bower-components; npm run; npm-run-all --parallel build:*",
     "build": "mkdir -p plugins_public; rm -rf plugins_public/*; npm run install-bower-components; npm run; npm-run-all --parallel build:*",
     "postinstall": "npm run build"
     "postinstall": "npm run build"
   },
   },
   "devDependencies": {
   "devDependencies": {
+    "@ag-ui/core": "0.1.1-canary.beta.0",
+    "@rollup/plugin-commonjs": "^28.0.6",
+    "@rollup/plugin-node-resolve": "^16.0.3",
+    "@rollup/plugin-typescript": "^12.3.0",
     "@tailwindcss/aspect-ratio": "^0.4.2",
     "@tailwindcss/aspect-ratio": "^0.4.2",
     "@tailwindcss/container-queries": "^0.1.1",
     "@tailwindcss/container-queries": "^0.1.1",
     "@tailwindcss/typography": "^0.5.19",
     "@tailwindcss/typography": "^0.5.19",
+    "@tanstack/ai": "^0.49.1",
+    "@tanstack/ai-client": "^0.28.0",
+    "@tanstack/ai-event-client": "^0.10.0",
+    "@tanstack/ai-utils": "^0.4.0",
+    "@tanstack/devtools-event-client": "^0.5.0",
     "bower": "^1.8.14",
     "bower": "^1.8.14",
     "npm-run-all": "^4.1.5",
     "npm-run-all": "^4.1.5",
+    "partial-json": "^0.1.7",
     "rollup": "^4.62.5",
     "rollup": "^4.62.5",
     "tailwindcss": "^3.4.17",
     "tailwindcss": "^3.4.17",
+    "tslib": "^2.8.1",
+    "typescript": "5.9.3",
     "uglify-js": "^3.19.3"
     "uglify-js": "^3.19.3"
   }
   }
 }
 }

+ 18 - 0
rollup.config.js

@@ -0,0 +1,18 @@
+import resolve from '@rollup/plugin-node-resolve';
+import commonjs from '@rollup/plugin-commonjs';
+import typescript from '@rollup/plugin-typescript';
+
+export default {
+    input: 'src/index.ts',
+
+    output: {
+        file: 'plugins_public/bundle.js',
+        format: 'iife',
+    },
+
+    plugins: [
+        resolve({ browser: true }),
+        commonjs(),
+        typescript({ tsconfig: './tsconfig.json' }),
+    ],
+};

+ 210 - 0
src/chat/index.ts

@@ -0,0 +1,210 @@
+import {
+    ChatClient,
+    fetchServerSentEvents,
+    type UIMessage,
+} from '@tanstack/ai-client';
+
+export interface ChatOptions {
+    agentId: number | string;
+    endpoint?: string;
+    placeholder?: string;
+    credentials?: RequestCredentials;
+}
+
+declare const sUrlRoot: string | undefined;
+
+const CHAT_STYLES = `
+.bx-ai-chat-root .bx-ai-chat{display:flex;flex-direction:column;gap:.75rem;height:100%;min-height:18rem}
+.bx-ai-chat-root .bx-ai-chat-messages{flex:1 1 auto;overflow-y:auto;display:flex;flex-direction:column;gap:.5rem;padding:.75rem;border:1px solid rgba(0,0,0,.08);border-radius:.5rem;background:rgba(255,255,255,.6)}
+.bx-ai-chat-root .bx-ai-chat-message{display:flex}
+.bx-ai-chat-root .bx-ai-chat-message-user{justify-content:flex-end}
+.bx-ai-chat-root .bx-ai-chat-message-assistant{justify-content:flex-start}
+.bx-ai-chat-root .bx-ai-chat-message-inner{max-width:85%;padding:.5rem .75rem;border-radius:.75rem;line-height:1.4;word-break:break-word}
+.bx-ai-chat-root .bx-ai-chat-message-user .bx-ai-chat-message-inner{background:#2563eb;color:#fff}
+.bx-ai-chat-root .bx-ai-chat-message-assistant .bx-ai-chat-message-inner{background:#f3f4f6;color:#111827}
+.bx-ai-chat-root .bx-ai-chat-form{display:flex;gap:.5rem}
+.bx-ai-chat-root .bx-ai-chat-input{flex:1 1 auto}
+.bx-ai-chat-root .bx-ai-chat-error{color:#b91c1c;font-size:.875rem}
+.bx-ai-chat-root.bx-ai-chat-loading .bx-ai-chat-send{opacity:.7}`;
+
+let stylesInjected = false;
+
+function injectStyles()
+{
+    if (stylesInjected || typeof document === 'undefined')
+        return;
+
+    const style = document.createElement('style');
+    style.setAttribute('data-bx-ai-chat', '1');
+    style.textContent = CHAT_STYLES;
+    document.head.appendChild(style);
+    stylesInjected = true;
+}
+
+function escapeHtml(text)
+{
+    return text
+        .replace(/&/g, '&amp;')
+        .replace(/</g, '&lt;')
+        .replace(/>/g, '&gt;')
+        .replace(/"/g, '&quot;');
+}
+
+function getMessageText(message: UIMessage): string
+{
+    if (!message.parts || !message.parts.length)
+        return '';
+
+    return message.parts
+        .filter((part) => part.type === 'text')
+        .map((part) => part.content)
+        .join('');
+}
+
+function renderMessages(container: HTMLElement, messages: UIMessage[]): void
+{
+    const list = container.querySelector('.bx-ai-chat-messages');
+    if (!list)
+        return;
+
+    list.innerHTML = messages.map((message) => {
+        const role = message.role === 'user' ? 'user' : 'assistant';
+        const text = escapeHtml(getMessageText(message)).replace(/\n/g, '<br>');
+
+        return `<div class="bx-ai-chat-message bx-ai-chat-message-${role}"><div class="bx-ai-chat-message-inner">${text || '&nbsp;'}</div></div>`;
+    }).join('');
+
+    list.scrollTop = list.scrollHeight;
+}
+
+function setLoading(container: HTMLElement, isLoading: boolean): void
+{
+    const input = container.querySelector('.bx-ai-chat-input');
+    const button = container.querySelector('.bx-ai-chat-send');
+
+    if (input)
+        input.disabled = isLoading;
+
+    if (button)
+        button.disabled = isLoading;
+
+    container.classList.toggle('bx-ai-chat-loading', isLoading);
+}
+
+function buildMarkup(placeholder: string): string
+{
+    return `
+<div class="bx-ai-chat">
+    <div class="bx-ai-chat-messages"></div>
+    <form class="bx-ai-chat-form">
+        <input type="text" class="bx-ai-chat-input bx-form-input" placeholder="${escapeHtml(placeholder)}" autocomplete="off" />
+        <button type="submit" class="bx-ai-chat-send bx-btn">Send</button>
+    </form>
+</div>`;
+}
+
+function getChatEndpoint(agentId: number | string, endpoint?: string): string
+{
+    if (endpoint)
+        return endpoint;
+
+    const root = typeof sUrlRoot !== 'undefined' ? sUrlRoot : '/';
+
+    return `${root}sys-ai-chat/${agentId}`;
+}
+
+export class Chat
+{
+    protected _oContainer: HTMLElement;
+    protected _oClient: ChatClient;
+    protected _bAttached = false;
+
+    constructor(container: HTMLElement | string, options: ChatOptions)
+    {
+        const el = typeof container === 'string'
+            ? document.querySelector<HTMLElement>(container)
+            : container;
+
+        if (!el)
+            throw new Error('Chat: container not found');
+
+        injectStyles();
+
+        this._oContainer = el;
+        this._oContainer.innerHTML = buildMarkup(options.placeholder || 'Type a message…');
+        this._oContainer.classList.add('bx-ai-chat-root');
+
+        const sEndpoint = getChatEndpoint(options.agentId, options.endpoint);
+
+        this._oClient = new ChatClient({
+            connection: fetchServerSentEvents(sEndpoint, {
+                credentials: options.credentials || 'same-origin',
+            }),
+            onMessagesChange: (messages) => renderMessages(this._oContainer, messages),
+            onLoadingChange: (isLoading) => setLoading(this._oContainer, isLoading),
+            onErrorChange: (error) => {
+                if (!error)
+                    return;
+
+                const list = this._oContainer.querySelector('.bx-ai-chat-messages');
+                if (!list)
+                    return;
+
+                const note = document.createElement('div');
+                note.className = 'bx-ai-chat-error';
+                note.textContent = error.message;
+                list.appendChild(note);
+                list.scrollTop = list.scrollHeight;
+            },
+        });
+
+        const form = this._oContainer.querySelector<HTMLFormElement>('.bx-ai-chat-form');
+        const input = this._oContainer.querySelector<HTMLInputElement>('.bx-ai-chat-input');
+
+        form?.addEventListener('submit', (event) => {
+            event.preventDefault();
+
+            if (!input)
+                return;
+
+            const text = input.value.trim();
+            if (!text)
+                return;
+
+            input.value = '';
+            void this._oClient.sendMessage(text);
+        });
+    }
+
+    attach(): void
+    {
+        if (this._bAttached)
+            return;
+
+        this._oClient.attach();
+        this._bAttached = true;
+    }
+
+    detach(): void
+    {
+        if (!this._bAttached)
+            return;
+
+        this._oClient.detach();
+        this._bAttached = false;
+    }
+
+    destroy(): void
+    {
+        this.detach();
+        this._oContainer.innerHTML = '';
+        this._oContainer.classList.remove('bx-ai-chat-root', 'bx-ai-chat-loading');
+    }
+
+    static init(container: HTMLElement | string, options: ChatOptions): Chat
+    {
+        const chat = new Chat(container, options);
+        chat.attach();
+        return chat;
+    }
+}

+ 15 - 0
src/index.ts

@@ -0,0 +1,15 @@
+import { Chat } from './chat';
+
+declare global {
+    interface Window {
+        una: {
+            Chat: typeof Chat;
+        };
+    }
+}
+
+window.una = {
+    Chat,
+};
+
+export {};

+ 34 - 0
template/scripts/BxBaseServices.php

@@ -1791,6 +1791,40 @@ class BxBaseServices extends BxDol implements iBxDolProfileService
         return echoJson(['code' => 200, 'msg' => $mixed]);
         return echoJson(['code' => 200, 'msg' => $mixed]);
     }
     }
 
 
+    public function serviceAiChat($iAgentId)
+    {
+        if (!bx_get_logged_profile_id())
+            return echoJson(['code' => 403, 'msg' => _t('_sys_agents_unauthorized')]);
+
+        if ('POST' !== ($_SERVER['REQUEST_METHOD'] ?? ''))
+            return echoJson(['code' => 405, 'msg' => _t('_error occured')]);
+
+        $iAgentId = (int)$iAgentId;
+        if (!$iAgentId)
+            return echoJson(['code' => 400, 'msg' => _t('_sys_agents_agent_not_found')]);
+
+        $aAgent = BxDolAiQuery::getAgentObject($iAgentId);
+        if (!$aAgent || !$aAgent['active'])
+            return echoJson(['code' => 404, 'msg' => _t('_sys_agents_agent_not_found')]);
+
+        $sJson = file_get_contents('php://input');
+        $aData = json_decode($sJson, true);
+        if (json_last_error() !== JSON_ERROR_NONE)
+            return echoJson(['code' => 400, 'msg' => _t('_sys_agents_json_field_err')]);
+
+        $oAi = BxDolAI::getInstance();
+        if (!$oAi)
+            return echoJson(['code' => 503, 'msg' => _t('_sys_agents_exception')]);
+
+        $sPrompt = $oAi->extractChatPromptFromRequest($aData);
+        if (!$sPrompt)
+            return echoJson(['code' => 400, 'msg' => _t('_sys_agents_json_field_err')]);
+
+        $oAi->streamAgentChat($iAgentId, $sPrompt, [
+            'sender_profile_id' => bx_get_logged_profile_id(),
+        ], $aData['threadId'] ?? null);
+    }
+
     protected function _getOptionsAiAssistants()
     protected function _getOptionsAiAssistants()
     {
     {
         $aResult = ['' => _t('_Select_one')];
         $aResult = ['' => _t('_Select_one')];

+ 12 - 0
tsconfig.json

@@ -0,0 +1,12 @@
+{
+  "compilerOptions": {
+    "target": "ES2020",
+    "module": "ESNext",
+    "moduleResolution": "bundler",
+    "strict": true,
+    "skipLibCheck": true,
+    "esModuleInterop": true,
+    "lib": ["ES2020", "DOM", "DOM.Iterable"]
+  },
+  "include": ["src/**/*.ts"]
+}

+ 156 - 6
yarn.lock

@@ -2,6 +2,11 @@
 # yarn lockfile v1
 # yarn lockfile v1
 
 
 
 
+"@ag-ui/core@0.1.1-canary.beta.0":
+  version "0.1.1-canary.beta.0"
+  resolved "https://registry.yarnpkg.com/@ag-ui/core/-/core-0.1.1-canary.beta.0.tgz#b79accbfaac3bb0ceb1cce3962d9b288b6e5d670"
+  integrity sha512-zcP3RH5p3HJTZ0kyQxNOL1blnVFTDpaShitR7UMS/thwFdl48V6CAG+WQBcYEu/dfa8mKonRez88N0Ok+nEI+w==
+
 "@alloc/quick-lru@^5.2.0":
 "@alloc/quick-lru@^5.2.0":
   version "5.2.0"
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
   resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
@@ -105,7 +110,7 @@
   resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
   resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
   integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
   integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
 
 
-"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0":
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
   version "1.5.5"
   version "1.5.5"
   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
   integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
   integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
@@ -391,6 +396,47 @@
     node-gyp "^13.0.0"
     node-gyp "^13.0.0"
     proc-log "^7.0.0"
     proc-log "^7.0.0"
 
 
+"@rollup/plugin-commonjs@^28.0.6":
+  version "28.0.9"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.9.tgz#b875cd1590617a40c4916d561d75761c6ca3c6d1"
+  integrity sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==
+  dependencies:
+    "@rollup/pluginutils" "^5.0.1"
+    commondir "^1.0.1"
+    estree-walker "^2.0.2"
+    fdir "^6.2.0"
+    is-reference "1.2.1"
+    magic-string "^0.30.3"
+    picomatch "^4.0.2"
+
+"@rollup/plugin-node-resolve@^16.0.3":
+  version "16.0.3"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz#0988e6f2cbb13316b0f5e7213f757bc9ed44928f"
+  integrity sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==
+  dependencies:
+    "@rollup/pluginutils" "^5.0.1"
+    "@types/resolve" "1.20.2"
+    deepmerge "^4.2.2"
+    is-module "^1.0.0"
+    resolve "^1.22.1"
+
+"@rollup/plugin-typescript@^12.3.0":
+  version "12.3.0"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.3.0.tgz#cc51b830973bc14c9456fe6532f322f2a40f5f12"
+  integrity sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big==
+  dependencies:
+    "@rollup/pluginutils" "^5.1.0"
+    resolve "^1.22.1"
+
+"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.1.0":
+  version "5.4.0"
+  resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.4.0.tgz#ac23a29ced0247060a210815fca39c17de4d2f26"
+  integrity sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==
+  dependencies:
+    "@types/estree" "^1.0.0"
+    estree-walker "^2.0.2"
+    picomatch "^4.0.2"
+
 "@rollup/rollup-android-arm-eabi@4.62.5":
 "@rollup/rollup-android-arm-eabi@4.62.5":
   version "4.62.5"
   version "4.62.5"
   resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.5.tgz#ea71e1a350caefa1bb4c530b3bf785e7b1c17e21"
   resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.5.tgz#ea71e1a350caefa1bb4c530b3bf785e7b1c17e21"
@@ -562,6 +608,11 @@
     "@sigstore/core" "^4.0.1"
     "@sigstore/core" "^4.0.1"
     "@sigstore/protobuf-specs" "^0.5.0"
     "@sigstore/protobuf-specs" "^0.5.0"
 
 
+"@standard-schema/spec@^1.1.0":
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8"
+  integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==
+
 "@stripe/connect-js@^3.4.6":
 "@stripe/connect-js@^3.4.6":
   version "3.4.6"
   version "3.4.6"
   resolved "https://registry.yarnpkg.com/@stripe/connect-js/-/connect-js-3.4.6.tgz#03bf1fbb812226015f8e2c1f103f6082149dc5a8"
   resolved "https://registry.yarnpkg.com/@stripe/connect-js/-/connect-js-3.4.6.tgz#03bf1fbb812226015f8e2c1f103f6082149dc5a8"
@@ -619,6 +670,48 @@
   dependencies:
   dependencies:
     postcss-selector-parser "6.0.10"
     postcss-selector-parser "6.0.10"
 
 
+"@tanstack/ai-client@^0.28.0":
+  version "0.28.0"
+  resolved "https://registry.yarnpkg.com/@tanstack/ai-client/-/ai-client-0.28.0.tgz#1072a0c3453329e8c88794300d940e0d3998c391"
+  integrity sha512-KkOLqw4d2MkzhmqFiHGANjmhpvBWHlKDSSCdZA/o57d+Sc/dS+1fJBqRO5tKGI2m8Y9q3+TINGGo4pNUUFyfTQ==
+  dependencies:
+    "@tanstack/ai" "^0.49.1"
+    "@tanstack/ai-event-client" "^0.10.0"
+    "@tanstack/ai-utils" "^0.4.0"
+
+"@tanstack/ai-event-client@^0.10.0":
+  version "0.10.0"
+  resolved "https://registry.yarnpkg.com/@tanstack/ai-event-client/-/ai-event-client-0.10.0.tgz#5133a0156d689dc1e6038b2de3340dbd613f9a43"
+  integrity sha512-grvlmM0z4rMLvjwPKBfT4/sL4D97yqocSzyaTvUa+2wZmXESCf/uR/7ZAldOKBasEx6qO5EJ31hdKDEDjnrnDg==
+  dependencies:
+    "@tanstack/devtools-event-client" "^0.4.1"
+
+"@tanstack/ai-utils@^0.4.0":
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/@tanstack/ai-utils/-/ai-utils-0.4.0.tgz#d4ee407d446471d0ba1c500348e6b5be22e481ad"
+  integrity sha512-xqvAgPJkIuGk1m+jZKyb7vBTQIaBmUD9EVzlPkDWWMp80n69uwL0TnBZCVk+OwL9goTQiFy648dnBfLsiJgl6A==
+
+"@tanstack/ai@^0.49.1":
+  version "0.49.1"
+  resolved "https://registry.yarnpkg.com/@tanstack/ai/-/ai-0.49.1.tgz#0ec6d84689843afbc43bfcc0f1284804f26c7b63"
+  integrity sha512-tOyeMiegTztxLReWpdlzcjAvQ1RutGXwONniixErozeLiErNyNo9fbgTOwdKX9sGM9Gp3HvvXvB5zwGkintxbg==
+  dependencies:
+    "@ag-ui/core" "0.1.1-canary.beta.0"
+    "@standard-schema/spec" "^1.1.0"
+    "@tanstack/ai-event-client" "^0.10.0"
+    "@tanstack/ai-utils" "^0.4.0"
+    partial-json "^0.1.7"
+
+"@tanstack/devtools-event-client@^0.4.1":
+  version "0.4.4"
+  resolved "https://registry.yarnpkg.com/@tanstack/devtools-event-client/-/devtools-event-client-0.4.4.tgz#c58185e737bee28b3afce206509412225e9f9031"
+  integrity sha512-6T5Yop/793YI+H+5J8Hsyj4kCih9sl4t3ElLgKioW5hk3ocn+ZdSJ94tT7vL7uabxSugWYBZlOTMPzEw2puvQw==
+
+"@tanstack/devtools-event-client@^0.5.0":
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/@tanstack/devtools-event-client/-/devtools-event-client-0.5.0.tgz#15de361dff2cd26b9f2cd01aba63e88043943c69"
+  integrity sha512-H+OH3zC6Vhu/K0NaVfQKknEKawc/+2PT+D3SB3Ox0V8SiMlTo0abbmH2rH0721R2aNYbjdMXA1oENOd8E2UVoA==
+
 "@tufjs/canonical-json@2.0.0":
 "@tufjs/canonical-json@2.0.0":
   version "2.0.0"
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a"
   resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a"
@@ -640,7 +733,7 @@
     "@types/jquery" "*"
     "@types/jquery" "*"
     "@types/underscore" "*"
     "@types/underscore" "*"
 
 
-"@types/estree@1.0.9":
+"@types/estree@*", "@types/estree@1.0.9", "@types/estree@^1.0.0":
   version "1.0.9"
   version "1.0.9"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24"
   integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==
   integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==
@@ -655,6 +748,11 @@
   resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-4.0.1.tgz#7c08ca6492876b70e11e4724af35b347069038cd"
   resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-4.0.1.tgz#7c08ca6492876b70e11e4724af35b347069038cd"
   integrity sha512-9a59A/tycXgYuPABcp6/3spSShn0NT2UOM4EfHvMumjYi4lJWTsK5SZWjhx3yRm9IHGCeWXdV2YfNsrWrft/CA==
   integrity sha512-9a59A/tycXgYuPABcp6/3spSShn0NT2UOM4EfHvMumjYi4lJWTsK5SZWjhx3yRm9IHGCeWXdV2YfNsrWrft/CA==
 
 
+"@types/resolve@1.20.2":
+  version "1.20.2"
+  resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
+  integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
+
 "@types/underscore@*":
 "@types/underscore@*":
   version "1.13.0"
   version "1.13.0"
   resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.13.0.tgz#dd8c034a92e5b8e24650c31af43d807c5340cee4"
   resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.13.0.tgz#dd8c034a92e5b8e24650c31af43d807c5340cee4"
@@ -1017,6 +1115,11 @@ common-ancestor-path@^2.0.0:
   resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz#f1d361aea9236aad5b92a0ff5b9df1422dd360ff"
   resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz#f1d361aea9236aad5b92a0ff5b9df1422dd360ff"
   integrity sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==
   integrity sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==
 
 
+commondir@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+  integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
+
 concat-map@0.0.1:
 concat-map@0.0.1:
   version "0.0.1"
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -1114,6 +1217,11 @@ deepmerge-ts@^7.1.5:
   resolved "https://registry.yarnpkg.com/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz#ff818564007f5c150808d2b7b732cac83aa415ab"
   resolved "https://registry.yarnpkg.com/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz#ff818564007f5c150808d2b7b732cac83aa415ab"
   integrity sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==
   integrity sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==
 
 
+deepmerge@^4.2.2:
+  version "4.3.1"
+  resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
+  integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+
 define-data-property@^1.0.1, define-data-property@^1.1.4:
 define-data-property@^1.0.1, define-data-property@^1.1.4:
   version "1.1.4"
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
   resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
@@ -1305,6 +1413,11 @@ escape-string-regexp@^1.0.5:
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
   integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
 
 
+estree-walker@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
+  integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
+
 ev-emitter@^1.0.0:
 ev-emitter@^1.0.0:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a"
   resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a"
@@ -1368,7 +1481,7 @@ fastq@^1.6.0:
   dependencies:
   dependencies:
     reusify "^1.0.4"
     reusify "^1.0.4"
 
 
-fdir@^6.5.0:
+fdir@^6.2.0, fdir@^6.5.0:
   version "6.5.0"
   version "6.5.0"
   resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
   resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
   integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
   integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
@@ -1713,7 +1826,6 @@ headroom.js@^0.12.0:
 
 
 "highlight.js@github:highlightjs/highlight.js":
 "highlight.js@github:highlightjs/highlight.js":
   version "11.12.0"
   version "11.12.0"
-  uid "080fbd8c0f941938c5f9564438d2bc2db39636fd"
   resolved "https://codeload.github.com/highlightjs/highlight.js/tar.gz/080fbd8c0f941938c5f9564438d2bc2db39636fd"
   resolved "https://codeload.github.com/highlightjs/highlight.js/tar.gz/080fbd8c0f941938c5f9564438d2bc2db39636fd"
 
 
 hls.js@^1.7.1:
 hls.js@^1.7.1:
@@ -1982,6 +2094,11 @@ is-map@^2.0.3:
   resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
   resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
   integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
   integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
 
 
+is-module@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
+  integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
+
 is-negative-zero@^2.0.3:
 is-negative-zero@^2.0.3:
   version "2.0.3"
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
   resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
@@ -2000,6 +2117,13 @@ is-number@^7.0.0:
   resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
   resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
   integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
   integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
 
 
+is-reference@1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
+  integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
+  dependencies:
+    "@types/estree" "*"
+
 is-regex@^1.1.4, is-regex@^1.2.1:
 is-regex@^1.1.4, is-regex@^1.2.1:
   version "1.2.1"
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
@@ -2172,7 +2296,6 @@ jstree@^3.3.17:
 
 
 "jush@https://github.com/vrana/jush":
 "jush@https://github.com/vrana/jush":
   version "0.0.0"
   version "0.0.0"
-  uid "897e3b0c14d7af0a105ef862dc7cc6289ac6755d"
   resolved "https://github.com/vrana/jush#897e3b0c14d7af0a105ef862dc7cc6289ac6755d"
   resolved "https://github.com/vrana/jush#897e3b0c14d7af0a105ef862dc7cc6289ac6755d"
 
 
 just-diff-apply@^5.2.0:
 just-diff-apply@^5.2.0:
@@ -2349,6 +2472,13 @@ lru-cache@^11.0.0, lru-cache@^11.1.0, lru-cache@^11.2.1:
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.2.tgz#00e16665c90c620fba14a3c368732a976493f760"
   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.2.tgz#00e16665c90c620fba14a3c368732a976493f760"
   integrity sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==
   integrity sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==
 
 
+magic-string@^0.30.3:
+  version "0.30.21"
+  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91"
+  integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==
+  dependencies:
+    "@jridgewell/sourcemap-codec" "^1.5.5"
+
 make-fetch-happen@^16.0.0, make-fetch-happen@^16.0.1:
 make-fetch-happen@^16.0.0, make-fetch-happen@^16.0.1:
   version "16.0.1"
   version "16.0.1"
   resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-16.0.1.tgz#86c18bf9c18793bb4e64a653ba43184ea1e9384e"
   resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-16.0.1.tgz#86c18bf9c18793bb4e64a653ba43184ea1e9384e"
@@ -2840,6 +2970,11 @@ parse-json@^4.0.0:
     error-ex "^1.3.1"
     error-ex "^1.3.1"
     json-parse-better-errors "^1.0.1"
     json-parse-better-errors "^1.0.1"
 
 
+partial-json@^0.1.7:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/partial-json/-/partial-json-0.1.7.tgz#b735a89edb3e25f231a3c4caeaae71dc9f578605"
+  integrity sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==
+
 path-browserify@^1.0.1:
 path-browserify@^1.0.1:
   version "1.0.1"
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
   resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
@@ -2892,6 +3027,11 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.2.tgz#5a942915e26b372dc0f0e6753149a16e6b1c5601"
   integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==
   integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==
 
 
+picomatch@^4.0.2:
+  version "4.0.7"
+  resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.7.tgz#6313360034ccb36b3dc61ecbdff78121f90fe21f"
+  integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==
+
 picomatch@^4.0.4:
 picomatch@^4.0.4:
   version "4.0.5"
   version "4.0.5"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.5.tgz#51ea57a17d86f605f81039595fbc40ed06a55fab"
   resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.5.tgz#51ea57a17d86f605f81039595fbc40ed06a55fab"
@@ -3187,7 +3327,7 @@ regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.4:
     gopd "^1.2.0"
     gopd "^1.2.0"
     set-function-name "^2.0.2"
     set-function-name "^2.0.2"
 
 
-resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.8:
+resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.8:
   version "1.22.12"
   version "1.22.12"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f"
   integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==
   integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==
@@ -3699,6 +3839,11 @@ ts-interface-checker@^0.1.9:
   resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
   resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
   integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
   integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
 
 
+tslib@^2.8.1:
+  version "2.8.1"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+  integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
 tuf-js@^6.0.0:
 tuf-js@^6.0.0:
   version "6.0.0"
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-6.0.0.tgz#2637f81f31a78582643ea50435e523de34cccb78"
   resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-6.0.0.tgz#2637f81f31a78582643ea50435e523de34cccb78"
@@ -3758,6 +3903,11 @@ typed-array-length@^1.0.7:
     possible-typed-array-names "^1.1.0"
     possible-typed-array-names "^1.1.0"
     reflect.getprototypeof "^1.0.10"
     reflect.getprototypeof "^1.0.10"
 
 
+typescript@5.9.3:
+  version "5.9.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
+  integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
+
 uglify-js@^3.19.3:
 uglify-js@^3.19.3:
   version "3.19.3"
   version "3.19.3"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f"