UNPKG

magnitude-core

Version:
1 lines 339 kB
{"version":3,"sources":["../src/web/scripts/shadowDOMInputAdapter.js","../src/ai/baml_client/config.ts","../src/ai/baml_client/globals.ts","../src/ai/baml_client/inlinedbaml.ts","../src/logger.ts","../src/agent/index.ts","../src/ai/util.ts","../src/ai/baml_client/index.ts","../src/ai/baml_client/async_client.ts","../src/ai/baml_client/async_request.ts","../src/ai/baml_client/parser.ts","../src/ai/baml_client/tracing.ts","../src/ai/modelHarness.ts","../src/ai/baml_client/type_builder.ts","../src/actions/util.ts","../src/util.ts","../src/memory/context.ts","../src/memory/image.ts","../src/memory/serde.ts","../src/memory/observation.ts","../src/agent/errors.ts","../src/memory/index.ts","../src/actions/index.ts","../src/actions/taskActions.ts","../src/web/stability.ts","../src/web/util.ts","../src/web/visualizer.ts","../src/web/tabs.ts","../src/web/transformer.ts","../src/web/harness.ts","../src/actions/webActions.ts","../src/web/browserProvider.ts","../src/ai/grounding.ts","../src/common/util.ts","../src/connectors/browserConnector.ts","../src/agent/narrator.ts","../src/agent/browserAgent.ts","../src/telemetry/index.ts","../src/version.ts","../src/telemetry/events.ts","../src/index.ts"],"sourcesContent":["// Custom Shadow DOM Input Adapter script for browser injection\nmodule.exports = function getShadowDOMInputAdapterScript() {\n return function() {\n if (typeof window.magnitudeShadowDOMAdapter !== 'undefined') {\n console.warn('magnitudeShadowDOMAdapter already defined. Cleaning up old one.');\n if(typeof window.magnitudeShadowDOMAdapter.cleanup === 'function') {\n window.magnitudeShadowDOMAdapter.cleanup();\n }\n }\n\n window.magnitudeShadowDOMAdapter = {\n activePopup: null, // Generic reference to the currently open popup/dropdown\n activePopupType: null, // 'select', 'date', 'color'\n activePopupOriginalElement: null, // The element that triggered the popup\n boundHandleDocumentMousedown: null,\n boundHandleDocumentClick: null, // For click event prevention\n boundHandleOutsidePopupClick: null,\n boundHandleDocumentKeydown: null, // For select typeahead\n searchString: '', // For select typeahead\n searchTimeoutId: null, // For select typeahead\n\n // --- Initialization and Cleanup ---\n init: function() {\n this.boundHandleDocumentMousedown = this.handleDocumentMousedown.bind(this);\n document.addEventListener('mousedown', this.boundHandleDocumentMousedown, true);\n \n this.boundHandleDocumentClick = this.handleDocumentClick.bind(this);\n document.addEventListener('click', this.boundHandleDocumentClick, true);\n \n this.boundHandleDocumentKeydown = this.handleDocumentKeydown.bind(this); // Added for select typeahead\n\n console.log('Shadow DOM Input Adapter mousedown, click, and keydown listeners prepared.');\n },\n\n cleanup: function() {\n this.closeActivePopup(); // This will also remove keydown listener if active\n if (this.boundHandleDocumentMousedown) {\n document.removeEventListener('mousedown', this.boundHandleDocumentMousedown, true);\n this.boundHandleDocumentMousedown = null;\n }\n if (this.boundHandleDocumentClick) {\n document.removeEventListener('click', this.boundHandleDocumentClick, true);\n this.boundHandleDocumentClick = null;\n }\n // Ensure keydown listener is removed if it was somehow left active\n if (this.boundHandleDocumentKeydown && this.activePopupType !== 'select') { // Only if not handled by closeActivePopup\n document.removeEventListener('keydown', this.boundHandleDocumentKeydown, true);\n }\n console.log('Shadow DOM Input Adapter cleaned up.');\n },\n\n // --- Main Mousedown & Click Handlers ---\n handleDocumentMousedown: function(e) {\n const target = e.target;\n if (!target || typeof target.tagName !== 'string') return;\n\n // If mousedown is inside an active custom popup, let its internal handlers manage it.\n if (this.activePopup && this.activePopup.contains(target)) {\n return;\n }\n\n if (target.tagName === 'SELECT' || (target.tagName === 'OPTION' && target.parentElement && target.parentElement.tagName === 'SELECT')) {\n this.handleSelectInteraction(target.tagName === 'SELECT' ? target : target.parentElement, e);\n } else if (target.tagName === 'INPUT' && target.type === 'date') {\n this.handleDateInputInteraction(target, e);\n } else if (target.tagName === 'INPUT' && target.type === 'color') {\n this.handleColorInputInteraction(target, e);\n }\n // Note: The outside click listener (_setupOutsideClickListener) is responsible for closing popups\n // when clicking outside. This main mousedown handler focuses on opening/toggling them.\n },\n\n handleDocumentClick: function(e) {\n const target = e.target;\n if (!target || typeof target.tagName !== 'string') return;\n\n // If the click target is one of the elements we manage (select, date input, color input),\n // and the click is NOT inside an active custom popup UI that we've created,\n // then prevent the default action of the click. This is a secondary measure\n // to stop native pickers or behaviors if mousedown prevention wasn't enough.\n if ( (target.tagName === 'INPUT' && (target.type === 'date' || target.type === 'color')) ||\n (target.tagName === 'SELECT') ||\n (target.tagName === 'OPTION' && target.parentElement && target.parentElement.tagName === 'SELECT')\n ) {\n \n if (this.activePopup && this.activePopup.contains(target)) {\n // Click is inside our active custom popup. Do nothing here.\n // Let the popup's own event handlers manage it.\n return;\n }\n \n // If the click is on the original element (or an option within a select),\n // prevent its default action. Our mousedown handler should have already\n // initiated the custom UI if applicable.\n e.preventDefault();\n e.stopPropagation();\n // console.log(`Default click action prevented for: ${target.tagName} (type: ${target.type || 'N/A'})`);\n }\n },\n \n // --- Generic Popup Management ---\n closeActivePopup: function() {\n if (this.activePopup) {\n this.activePopup.remove();\n this.activePopup = null;\n }\n this.activePopupType = null;\n this.activePopupOriginalElement = null;\n if (this.boundHandleOutsidePopupClick) {\n document.removeEventListener('mousedown', this.boundHandleOutsidePopupClick, true);\n this.boundHandleOutsidePopupClick = null;\n }\n if (this.activePopupType === 'select' && this.boundHandleDocumentKeydown) {\n document.removeEventListener('keydown', this.boundHandleDocumentKeydown, true);\n }\n clearTimeout(this.searchTimeoutId);\n this.searchString = '';\n this.searchTimeoutId = null;\n },\n\n _setupOutsideClickListener: function() {\n // Use setTimeout to ensure the mousedown event that opened the popup doesn't immediately close it\n setTimeout(() => {\n this.boundHandleOutsidePopupClick = (event) => {\n if (this.activePopup && \n !this.activePopup.contains(event.target) && \n event.target !== this.activePopupOriginalElement &&\n (!this.activePopupOriginalElement || !this.activePopupOriginalElement.contains(event.target)) // Also check if click is on children of original element\n ) {\n this.closeActivePopup();\n }\n };\n document.addEventListener('mousedown', this.boundHandleOutsidePopupClick, true);\n }, 0);\n },\n \n _createPopupElement: function(originalElement, type) { // Added type for specific styling/content\n const rect = originalElement.getBoundingClientRect();\n const popup = document.createElement('div');\n popup.dataset.popupType = type;\n this._setStyles(popup, {\n position: 'fixed',\n left: `${rect.left}px`,\n top: `${rect.bottom + 2}px`,\n minWidth: `${rect.width}px`,\n background: 'white',\n border: '1px solid #ccc',\n boxShadow: '0 2px 10px rgba(0,0,0,0.15)',\n zIndex: '2147483647',\n padding: '10px',\n borderRadius: '4px',\n display: 'flex',\n flexDirection: 'column',\n gap: '5px', \n });\n return popup;\n },\n\n _updateInputValidationIndicator: function(inputElementContainer, isValid) {\n let indicatorSpan = inputElementContainer.querySelector('.validation-indicator');\n if (!indicatorSpan) {\n indicatorSpan = document.createElement('span');\n indicatorSpan.className = 'validation-indicator';\n this._setStyles(indicatorSpan, {\n marginLeft: '5px',\n display: 'inline-flex',\n alignItems: 'center',\n width: '16px', // Fixed width for the indicator\n height: '16px', // Fixed height\n justifyContent: 'center',\n });\n inputElementContainer.appendChild(indicatorSpan); // Append next to the input\n }\n\n if (isValid === true) {\n indicatorSpan.textContent = '✔';\n indicatorSpan.style.color = 'green';\n } else if (isValid === false) {\n indicatorSpan.textContent = '✖';\n indicatorSpan.style.color = 'red';\n } else { // null or undefined or empty string\n indicatorSpan.textContent = '';\n }\n },\n\n // --- SELECT Element Specific Logic ---\n handleSelectInteraction: function(selectElement, event) {\n event.preventDefault();\n event.stopPropagation();\n \n if (this.activePopupType === 'select' && this.activePopupOriginalElement === selectElement) {\n this.closeActivePopup();\n return;\n }\n this.closeActivePopup();\n this.createAndShowSelectDropdown(selectElement);\n },\n\n createAndShowSelectDropdown: function(select) {\n const dropdown = this._createPopupElement(select, 'select');\n this._setStyles(dropdown, { \n padding: '0', \n maxHeight: `${Math.min(300, window.innerHeight - select.getBoundingClientRect().bottom - 20)}px`,\n overflowY: 'auto',\n gap: '0', // Select doesn't need the main popup gap\n });\n\n const contentWrapper = document.createElement('div'); \n this._setStyles(contentWrapper, { padding: '5px 0' });\n \n Array.from(select.options).forEach((option, index) => {\n const div = document.createElement('div');\n div.textContent = option.text;\n this._setStyles(div, {\n padding: '8px 12px', margin: '0', cursor: 'pointer',\n backgroundColor: index === select.selectedIndex ? '#e0e0e0' : 'white',\n whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',\n });\n div.setAttribute('data-index', index.toString());\n div.onmouseenter = function() { this.style.backgroundColor = index === select.selectedIndex ? '#d0d0d0' : '#f0f0f0'; };\n div.onmouseleave = function() { this.style.backgroundColor = index === select.selectedIndex ? '#e0e0e0' : 'white'; };\n div.onclick = () => {\n select.selectedIndex = index;\n select.dispatchEvent(new Event('input', { bubbles: true }));\n select.dispatchEvent(new Event('change', { bubbles: true }));\n this.closeActivePopup();\n };\n contentWrapper.appendChild(div);\n });\n\n dropdown.appendChild(contentWrapper);\n \n const rootNode = select.getRootNode() instanceof ShadowRoot ? select.getRootNode() : document.body;\n rootNode.appendChild(dropdown);\n\n this.activePopup = dropdown;\n this.activePopupType = 'select';\n this.activePopupOriginalElement = select;\n select.blur();\n this._setupOutsideClickListener();\n\n // For typeahead\n this.searchString = '';\n clearTimeout(this.searchTimeoutId);\n document.addEventListener('keydown', this.boundHandleDocumentKeydown, true);\n\n console.log('Custom select dropdown created for:', select.id || select.name);\n },\n\n // --- Keydown Handler for Select Typeahead ---\n handleDocumentKeydown: function(e) {\n if (!this.activePopup || this.activePopupType !== 'select' || !this.activePopupOriginalElement) {\n return;\n }\n\n // Ignore modifier keys, navigation keys, Escape, Tab (but handle Enter)\n if (e.metaKey || e.ctrlKey || e.altKey || \n ['Shift', 'Control', 'Alt', 'Meta', 'Escape', 'Tab', \n 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', \n 'Home', 'End', 'PageUp', 'PageDown'].includes(e.key)) {\n if (e.key === 'Escape') {\n this.closeActivePopup();\n }\n return;\n }\n\n if (e.key === 'Enter') {\n e.preventDefault();\n e.stopImmediatePropagation(); // Changed to stopImmediatePropagation\n const options = Array.from(this.activePopup.querySelectorAll('[data-index]'));\n const highlightedOption = options.find(opt => opt.style.backgroundColor === 'rgb(173, 216, 230)'); // Light blue in rgb\n\n if (highlightedOption) {\n const index = parseInt(highlightedOption.getAttribute('data-index'));\n const select = this.activePopupOriginalElement;\n select.selectedIndex = index;\n select.dispatchEvent(new Event('input', { bubbles: true }));\n select.dispatchEvent(new Event('change', { bubbles: true }));\n this.closeActivePopup();\n }\n return;\n }\n \n // Prevent default browser behavior for printable characters when dropdown is open\n // e.g. page search\n if (e.key.length === 1) {\n e.preventDefault();\n e.stopPropagation();\n }\n\n\n clearTimeout(this.searchTimeoutId);\n this.searchString += e.key.toLowerCase();\n\n this.searchTimeoutId = setTimeout(() => {\n this.searchString = '';\n }, 800); // Reset search string after 800ms of inactivity\n\n const options = Array.from(this.activePopup.querySelectorAll('[data-index]'));\n let matchedOption = null;\n\n for (const optionElement of options) {\n if (optionElement.textContent.toLowerCase().startsWith(this.searchString)) {\n matchedOption = optionElement;\n break;\n }\n }\n\n if (matchedOption) {\n options.forEach(opt => {\n // Reset background for all options, considering original selected state\n const optIndex = parseInt(opt.getAttribute('data-index'));\n const originalSelect = this.activePopupOriginalElement;\n opt.style.backgroundColor = optIndex === originalSelect.selectedIndex ? '#e0e0e0' : 'white';\n // Reset hover effect styles if any were applied directly\n opt.onmouseenter = function() { this.style.backgroundColor = optIndex === originalSelect.selectedIndex ? '#d0d0d0' : '#f0f0f0'; };\n opt.onmouseleave = function() { this.style.backgroundColor = optIndex === originalSelect.selectedIndex ? '#e0e0e0' : 'white'; };\n });\n \n // Highlight the matched option\n matchedOption.style.backgroundColor = '#add8e6'; // Light blue for highlight\n // Temporarily override hover for matched item to keep highlight\n matchedOption.onmouseenter = function() { this.style.backgroundColor = '#add8e6'; }; \n \n matchedOption.scrollIntoView({ block: 'nearest' });\n }\n },\n \n // --- DATE Input Specific Logic ---\n handleDateInputInteraction: function(dateInputElement, event) {\n event.preventDefault();\n event.stopPropagation();\n if (this.activePopupType === 'date' && this.activePopupOriginalElement === dateInputElement) {\n this.closeActivePopup();\n return;\n }\n this.closeActivePopup();\n this.createAndShowDatePopup(dateInputElement);\n },\n\n createAndShowDatePopup: function(originalDateInput) {\n const popup = this._createPopupElement(originalDateInput, 'date');\n this._setStyles(popup, { flexDirection: 'row', alignItems: 'center', gap: '0' }); // Override for side-by-side\n\n const textInput = document.createElement('input');\n textInput.type = 'text';\n textInput.placeholder = 'MM/DD/YYYY';\n this._setStyles(textInput, { flexGrow: '1', padding: '8px', border: '1px solid #ccc', borderRadius: '3px' });\n if (originalDateInput.value) { // YYYY-MM-DD\n const parts = originalDateInput.value.split('-');\n if (parts.length === 3) textInput.value = `${parts[1]}/${parts[2]}/${parts[0]}`;\n else textInput.value = originalDateInput.value;\n }\n \n popup.appendChild(textInput);\n this._updateInputValidationIndicator(popup, null); // Create indicator span\n\n const self = this;\n textInput.addEventListener('input', function() {\n const inputValue = this.value;\n if (!inputValue) {\n self._updateInputValidationIndicator(popup, null);\n return;\n }\n const dateParts = inputValue.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (dateParts) {\n const month = parseInt(dateParts[1], 10);\n const day = parseInt(dateParts[2], 10);\n const year = parseInt(dateParts[3], 10);\n if (month >= 1 && month <= 12 && day >= 1 && day <= 31) { // Basic validation\n self._updateInputValidationIndicator(popup, true);\n originalDateInput.value = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;\n originalDateInput.dispatchEvent(new Event('input', { bubbles: true }));\n originalDateInput.dispatchEvent(new Event('change', { bubbles: true }));\n // Do NOT close popup here, wait for Enter or outside click\n } else {\n self._updateInputValidationIndicator(popup, false);\n }\n } else {\n self._updateInputValidationIndicator(popup, false);\n }\n });\n \n textInput.addEventListener('keydown', function(e) {\n if (e.key === 'Enter') {\n e.preventDefault();\n // Perform final validation and close if valid\n const inputValue = this.value;\n const dateParts = inputValue.match(/^(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})$/);\n if (dateParts) {\n const month = parseInt(dateParts[1], 10);\n const day = parseInt(dateParts[2], 10);\n const year = parseInt(dateParts[3], 10);\n if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {\n // Value is already set by input listener, just close\n self.closeActivePopup();\n }\n }\n // If not valid, popup stays open, indicator shows '✖'\n }\n });\n\n const rootNode = originalDateInput.getRootNode() instanceof ShadowRoot ? originalDateInput.getRootNode() : document.body;\n rootNode.appendChild(popup);\n\n this.activePopup = popup;\n this.activePopupType = 'date';\n this.activePopupOriginalElement = originalDateInput;\n originalDateInput.blur();\n this._setupOutsideClickListener();\n setTimeout(() => {\n textInput.focus();\n textInput.select();\n }, 0);\n console.log('Custom date popup created for:', originalDateInput.id || originalDateInput.name);\n },\n\n // --- COLOR Input Specific Logic ---\n handleColorInputInteraction: function(colorInputElement, event) {\n event.preventDefault();\n event.stopPropagation();\n if (this.activePopupType === 'color' && this.activePopupOriginalElement === colorInputElement) {\n this.closeActivePopup();\n return;\n }\n this.closeActivePopup();\n this.createAndShowColorPopup(colorInputElement);\n },\n\n createAndShowColorPopup: function(originalColorInput) {\n const popup = this._createPopupElement(originalColorInput, 'color');\n this._setStyles(popup, { flexDirection: 'row', alignItems: 'center', gap: '0' });\n\n const textInput = document.createElement('input');\n textInput.type = 'text';\n textInput.placeholder = '#RRGGBB';\n this._setStyles(textInput, { flexGrow: '1', padding: '8px', border: '1px solid #ccc', borderRadius: '3px', marginRight: '5px'});\n if (originalColorInput.value) textInput.value = originalColorInput.value;\n\n const previewSpan = document.createElement('span');\n this._setStyles(previewSpan, {\n width: '28px', height: '28px', display: 'inline-block', border: '1px solid #ccc',\n backgroundColor: originalColorInput.value || '#ffffff', borderRadius: '3px', flexShrink: '0',\n marginRight: '5px', // Space before validation indicator\n });\n \n popup.appendChild(textInput);\n popup.appendChild(previewSpan);\n this._updateInputValidationIndicator(popup, null); // Create indicator span\n\n const self = this;\n textInput.addEventListener('input', function() {\n const inputValue = this.value.trim();\n if (!inputValue) {\n self._updateInputValidationIndicator(popup, null);\n previewSpan.style.backgroundColor = '#ffffff';\n return;\n }\n\n let finalColor = '';\n if (/^#([0-9A-Fa-f]{3}){1,2}$/.test(inputValue)) {\n finalColor = inputValue;\n } else if (/^[0-9A-Fa-f]{6}$/.test(inputValue) || /^[0-9A-Fa-f]{3}$/.test(inputValue)) {\n finalColor = '#' + inputValue;\n }\n\n if (finalColor) {\n previewSpan.style.backgroundColor = finalColor;\n self._updateInputValidationIndicator(popup, true);\n originalColorInput.value = finalColor;\n originalColorInput.dispatchEvent(new Event('input', { bubbles: true }));\n originalColorInput.dispatchEvent(new Event('change', { bubbles: true }));\n // Do NOT close popup here, wait for Enter or outside click\n } else {\n previewSpan.style.backgroundColor = '#ffffff';\n self._updateInputValidationIndicator(popup, false);\n }\n });\n if(textInput.value) textInput.dispatchEvent(new Event('input')); // Trigger initial validation/preview\n\n textInput.addEventListener('keydown', function(e) {\n if (e.key === 'Enter') {\n e.preventDefault();\n // Perform final validation and close if valid\n const inputValue = this.value.trim();\n let finalColor = '';\n if (/^#([0-9A-Fa-f]{3}){1,2}$/.test(inputValue)) {\n finalColor = inputValue;\n } else if (/^[0-9A-Fa-f]{6}$/.test(inputValue) || /^[0-9A-Fa-f]{3}$/.test(inputValue)) {\n finalColor = '#' + inputValue;\n }\n if (finalColor) {\n // Value is already set by input listener, just close\n self.closeActivePopup();\n }\n // If not valid, popup stays open, indicator shows '✖'\n }\n });\n \n const rootNode = originalColorInput.getRootNode() instanceof ShadowRoot ? originalColorInput.getRootNode() : document.body;\n rootNode.appendChild(popup);\n \n this.activePopup = popup;\n this.activePopupType = 'color';\n this.activePopupOriginalElement = originalColorInput;\n originalColorInput.blur();\n this._setupOutsideClickListener();\n setTimeout(() => {\n textInput.focus();\n textInput.select();\n }, 0);\n console.log('Custom color popup created for:', originalColorInput.id || originalColorInput.name);\n },\n\n // --- Helper Functions ---\n _setStyles: function(element, styles) {\n for (const property in styles) {\n element.style[property] = styles[property];\n }\n }\n // _copyAttributes is not used in this version as we are not replacing elements.\n };\n\n window.magnitudeShadowDOMAdapter.init();\n }.toString();\n}\n","/*************************************************************************************************\n\nWelcome to Baml! To use this generated code, please run one of the following:\n\n$ npm install @boundaryml/baml\n$ yarn add @boundaryml/baml\n$ pnpm add @boundaryml/baml\n\n*************************************************************************************************/\n\n// This file was generated by BAML: do not edit it. Instead, edit the BAML\n// files and re-generate this code.\n//\n/* eslint-disable */\n// tslint:disable\n// @ts-nocheck\n// biome-ignore format: autogenerated code\nexport { setLogLevel, getLogLevel, setLogJsonMode as setLogJson } from \"@boundaryml/baml/logging\";\nexport { resetBamlEnvVars } from \"./globals\";","/*************************************************************************************************\n\nWelcome to Baml! To use this generated code, please run one of the following:\n\n$ npm install @boundaryml/baml\n$ yarn add @boundaryml/baml\n$ pnpm add @boundaryml/baml\n\n*************************************************************************************************/\n\n// This file was generated by BAML: do not edit it. Instead, edit the BAML\n// files and re-generate this code.\n//\n/* eslint-disable */\n// tslint:disable\n// @ts-nocheck\n// biome-ignore format: autogenerated code\nimport { BamlRuntime, BamlCtxManager } from '@boundaryml/baml'\nimport { getBamlFiles } from './inlinedbaml'\n\n// Create a copy of process.env to avoid mutations\nconst env = { ...process.env }\n\nexport const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME = BamlRuntime.fromFiles(\n 'baml_src',\n getBamlFiles(),\n env\n)\nexport const DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX = new BamlCtxManager(DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME)\n\n/**\n * @deprecated resetBamlEnvVars is deprecated and is safe to remove, since environment variables are now lazily loaded on each function call\n */\nexport function resetBamlEnvVars(envVars: Record<string, string | undefined>) {\n if (DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.allowResets()) {\n const envVarsToReset = Object.fromEntries(Object.entries(envVars).filter((kv): kv is [string, string] => kv[1] !== undefined));\n DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_RUNTIME.reset('baml_src', getBamlFiles(), envVarsToReset)\n DO_NOT_USE_DIRECTLY_UNLESS_YOU_KNOW_WHAT_YOURE_DOING_CTX.reset()\n } else {\n throw new Error('BamlError: Cannot reset BAML environment variables while there are active BAML contexts.')\n }\n}","/*************************************************************************************************\n\nWelcome to Baml! To use this generated code, please run one of the following:\n\n$ npm install @boundaryml/baml\n$ yarn add @boundaryml/baml\n$ pnpm add @boundaryml/baml\n\n*************************************************************************************************/\n\n// This file was generated by BAML: do not edit it. Instead, edit the BAML\n// files and re-generate this code.\n//\n/* eslint-disable */\n// tslint:disable\n// @ts-nocheck\n// biome-ignore format: autogenerated code\nconst fileMap = {\n \n \"behaviorTests.baml\": \"\\ntest DoNotOverplan1 {\\n functions [CreatePartialRecipe]\\n args {\\n screenshot {\\n url \\\"https://magnitude-test-screenshots.s3.us-east-1.amazonaws.com/do_not_overplan_1.png\\\"\\n }\\n step {\\n description #\\\"Create a new company\\\"#\\n checks [\\n #\\\"Company added successfully\\\"#\\n ]\\n testData {\\n data [\\n\\n ]\\n other #\\\"Make up the first 2 values and use defaults for the rest\\\"#\\n }\\n }\\n previousActions [\\n\\n ]\\n }\\n @@assert( one_action, {{ this.actions|length == 1 }} )\\n @@assert( not_marked_finished, {{ this.finished == false }} )\\n}\\n\\n\\ntest DoNotOverplan2 {\\n // Especially with the test data, planner might be tempted to click create company and also plan to fill form fields.\\n // BUT we do not want it to do that - it should only click the button.\\n functions [CreatePartialRecipe]\\n args {\\n screenshot {\\n url \\\"https://magnitude-test-screenshots.s3.us-east-1.amazonaws.com/do_not_overplan_2.png\\\"\\n }\\n step {\\n description #\\\"Create a new company\\\"#\\n checks [\\n #\\\"Company added successfully\\\"#\\n ]\\n testData {\\n data [\\n\\n ]\\n other #\\\"Make up the first 2 values and use defaults for the rest\\\"#\\n }\\n }\\n previousActions [\\n #\\\"\\n {\\n \\\"variant\\\": \\\"click\\\",\\n \\\"target\\\": \\\"Companies option in the left sidebar menu\\\"\\n }\\n \\\"#\\n ]\\n }\\n @@assert( one_action, {{ this.actions|length == 1 }} )\\n @@assert( not_marked_finished, {{ this.finished == false }} )\\n}\\n\\ntest OptimalPlanning1 {\\n functions [CreatePartialRecipe]\\n args {\\n screenshot {\\n url \\\"https://magnitude-test-screenshots.s3.us-east-1.amazonaws.com/do_not_underplan_1.png\\\"\\n }\\n step {\\n description #\\\"Create a new company\\\"#\\n checks [\\n #\\\"Company added successfully\\\"#\\n ]\\n testData {\\n data [\\n\\n ]\\n other #\\\"Make up the first 2 values and use defaults for the rest\\\"#\\n }\\n }\\n previousActions [\\n #\\\"\\n {\\n \\\"variant\\\": \\\"click\\\",\\n \\\"target\\\": \\\"Companies option in the left sidebar menu\\\"\\n }\\n \\\"#,\\n #\\\"\\n {\\n \\\"variant\\\": \\\"click\\\",\\n \\\"target\\\": \\\"Add Company button in the top right corner\\\"\\n }\\n \\\"#\\n ]\\n \\n }\\n // optimal is type name, type domain, click save, mark finished\\n @@assert( optimal_actions, {{ this.actions|length == 3 }} )\\n // @@assert( not_marked_finished, {{ this.finished == false }} )\\n}\\n\\n\\n\\n// test CheckContextRemove1 {\\n// // Manual for now - ideally we'd want to verify that executor can check the returned description successfully\\n// functions [RemoveImplicitCheckContext]\\n// args {\\n// screenshot {\\n// url \\\"https://magnitude-test-screenshots.s3.us-east-1.amazonaws.com/check_context_remove_1.png\\\"\\n// }\\n// check #\\\"Company added successfully\\\"#\\n// previousActions [\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Companies option in the left sidebar menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"'Add Company' button in the top right corner of the Companies page\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"type\\\",\\n// \\\"target\\\": \\\"Name input field\\\",\\n// \\\"content\\\": \\\"Acme Solutions\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"type\\\",\\n// \\\"target\\\": \\\"Domain input field\\\",\\n// \\\"content\\\": \\\"acmesolutions.com\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"type\\\",\\n// \\\"target\\\": \\\"Logo URL input field\\\",\\n// \\\"content\\\": \\\"https://example.com/image.jpg\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"type\\\",\\n// \\\"target\\\": \\\"Industry input field\\\",\\n// \\\"content\\\": \\\"Technology\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Size dropdown menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"1-10 option in the Size dropdown\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Revenue dropdown menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"<$100K option in the Revenue dropdown\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"ICP Fit dropdown menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Medium option in the ICP Fit dropdown\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Est. ARR dropdown menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"<$10K option in the Est. ARR dropdown\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Connection Strength dropdown menu\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Weak option in the Connection Strength dropdown\\\"\\n// }\\n// \\\"#,\\n// #\\\"\\n// {\\n// \\\"variant\\\": \\\"click\\\",\\n// \\\"target\\\": \\\"Save button\\\"\\n// }\\n// \\\"#\\n// ]\\n// }\\n// }\\n\\ntest TargetGrounding1 {\\n // This test is a screenshot of Magnitude dasboard. Goal is to go to test playground.\\n // Originally failed because target was described as \\\"TC-0 Playground Test Case button\\\"\\n // This aligns more with the card shown rather that the specific button that actually needs to be clicked\\n // which has text \\\"Experiment Now (Free!)\\\"\\n // We want the planner to ground the targets in very specific details when available, such as the text on a button.\\n // This test asserts that the generated target includes specific text from the button, at least \\\"Experiment Now\\\"\\n functions [CreatePartialRecipe]\\n args {\\n screenshot {\\n url \\\"https://magnitude-test-screenshots.s3.us-east-1.amazonaws.com/target_grounding_1.png\\\"\\n }\\n step {\\n description #\\\"Go to test playground\\\"#\\n checks [\\n ]\\n testData {\\n data [\\n\\n ]\\n other \\\"\\\"\\n }\\n }\\n previousActions [\\n ]\\n }\\n @@assert( includes_button_text, {{ \\\"Experiment Now (Free!)\\\" in this.actions[0].target }} )\\n}\",\n \"clients.baml\": \"// Learn more about clients at https://docs.boundaryml.com/docs/snippets/clients/overview\\n\\nclient<llm> SonnetBedrock {\\n provider aws-bedrock\\n retry_policy Exponential\\n options {\\n inference_configuration {\\n temperature 0.0\\n }\\n model_id \\\"anthropic.claude-3-5-sonnet-20240620-v1:0\\\"\\n }\\n}\\n\\nclient<llm> SonnetAnthropic {\\n provider anthropic\\n retry_policy Exponential\\n options {\\n model \\\"claude-3-5-sonnet-20240620\\\"\\n api_key env.ANTHROPIC_API_KEY\\n temperature 0.0\\n }\\n}\\n\\nclient<llm> GeminiPro {\\n provider \\\"google-ai\\\"\\n options {\\n api_key env.GOOGLE_API_KEY\\n model \\\"gemini-2.5-pro-preview-05-06\\\"\\n generationConfig {\\n temperature 0.0\\n }\\n }\\n}\\n\\nclient<llm> GeminiProOpenRouter {\\n provider \\\"openai-generic\\\"\\n options {\\n base_url \\\"https://openrouter.ai/api/v1\\\"\\n api_key env.OPENROUTER_API_KEY\\n model \\\"google/gemini-2.5-pro-preview-03-25\\\"\\n temperature 0.0\\n }\\n}\\n\\nclient<llm> GeminiFlash {\\n provider \\\"openai-generic\\\"\\n options {\\n base_url \\\"https://openrouter.ai/api/v1\\\"\\n api_key env.OPENROUTER_API_KEY\\n model \\\"google/gemini-2.5-flash-preview\\\"\\n temperature 0.0\\n }\\n}\\n\\nclient<llm> GPT {\\n provider openai\\n options {\\n model \\\"gpt-4.1-2025-04-14\\\"\\n api_key env.OPENAI_API_KEY\\n temperature 0.0\\n }\\n}\\n\\n// client<llm> Macro {\\n// provider openai\\n// options {\\n// model \\\"gpt-4o\\\"\\n// api_key env.OPENAI_API_KEY\\n// temperature 0.0\\n// }\\n// }\\n\\nclient<llm> NovitaLlamaMaverick {\\n provider \\\"openai-generic\\\"\\n retry_policy Exponential\\n options {\\n base_url \\\"https://api.novita.ai/v3/openai\\\"\\n api_key env.NOVITA_API_KEY\\n model \\\"meta-llama/llama-4-maverick-17b-128e-instruct-fp8\\\"\\n temperature 0.0\\n logprobs true\\n }\\n}\\n\\nclient<llm> Molmo {\\n provider \\\"openai-generic\\\"\\n retry_policy Exponential\\n options {\\n base_url env.MOLMO_VLLM_BASE_URL\\n api_key env.MOLMO_VLLM_API_KEY\\n model \\\"Molmo-7B-D-0924\\\"\\n temperature 0.0\\n logprobs true\\n }\\n}\\n\\nretry_policy Exponential {\\n max_retries 5\\n strategy {\\n type exponential_backoff\\n delay_ms 500\\n multiplier 2.0\\n max_delay_ms 10000\\n }\\n}\\n\\n// Default used by macro.ts\\nretry_policy DefaultRetryPolicy {\\n max_retries 5\\n strategy {\\n type exponential_backoff\\n delay_ms 500\\n multiplier 2.0\\n max_delay_ms 10000\\n }\\n}\\n\",\n \"diagnosis.baml\": \"\\n// class FailureClassification {\\n// classification \\\"bug\\\" | \\\"misalignment\\\"\\n// }\\n\\nclass BugFailureClassification {\\n reasoning string\\n classification \\\"bug\\\"\\n title string\\n expectedResult string\\n actualResult string\\n severity \\\"critical\\\" | \\\"high\\\" | \\\"medium\\\" | \\\"low\\\"\\n}\\n\\nclass MisalignmentClassification {\\n reasoning string\\n classification \\\"misalignment\\\"\\n\\n fault \\\"test\\\" | \\\"agent\\\" @description(#\\\"\\n Is this likely a problem with the test case or some issue with the agent?\\n \\\"#)\\n \\n message string @description(#\\\"\\n If fault of test case:\\n Message to the developer who wrote the test case to help them understand what may have happened and how they might be able to fix it.\\n Be simple, direct, and informative.\\n If fault of agent:\\n Message to the developer who wrote the test case (not the person who wrote the agent) to help them understand what may have happened, and suggest possible ways to adjust the test case to accommodate the issue.\\n \\\"#)\\n}\\n\\n// class FailureClassification {\\n// reasoning\\n// classification \\\"bug\\\" | \\\"misalignment\\\"\\n// }\\n\\ntemplate_string BaseMeta #\\\"\\n You are observing the execution of an LLM agent that runs test cases.\\n This agent executes test cases by observing screenshots from the browser, acting out steps, and verifying checks.\\n\\\"#\\n\\n// should this be given the original or adjusted check?\\n// should this be given more ctx of the overall step or test case?\\n// this is a tricky prompt, but its not as critical to get right as others\\n// it does become more important if we rely on classify as bug/misalign then correct minor misaligns only if not bug\\n// ^ if we need this then we should think of a more isolated/logical prompt to detect misalignments\\n// function ClassifyCheckFailure (context: BrowserExecutionContext, check: string) -> BugFailureClassification | MisalignmentClassification {\\n// client SonnetAnthropic\\n// prompt #\\\"\\n// {{ _.role(\\\"system\\\") }}\\n// {{ BaseMeta() }}\\n\\n// The agent just marked a check as failed. Your job is to figure out why.\\n\\n// Either:\\n// (1) The web application actually has a bug in it\\n// or\\n// (2) There's some misalignment between the test case and what is in the interface\\n\\n// If there is a bug, please break it down in detail.\\n// If it is a misalignment, please describe what you think happened.\\n\\n// Use the provided history of actions the agent took as well as the most recent screenshot to help you identify what happened.\\n\\n// {{ ctx.output_format }}\\n\\n// {{ _.role(\\\"user\\\") }}\\n\\n// The \\\"check\\\" that was marked as failed:\\n// {{ check }}\\n\\n// {{ DescribeBrowserExecutionContext(context) }}\\n// \\\"#\\n// }\\n\\n// function DiagnoseTargetNotFound (screenshot: image, step: TestStep, target: string, previousActions: string[]) -> BugFailureClassification | MisalignmentClassification {\\n// client SonnetAnthropic\\n// prompt #\\\"\\n// {{ _.role(\\\"system\\\") }}\\n// {{ BaseMeta() }}\\n\\n// The agent had an issue acting out a step because it could not find a target. Your job is to figure out why.\\n\\n// Either:\\n// (1) The web application actually has a bug in it\\n// or\\n// (2) There's some misalignment between the test case and what is in the interface\\n\\n// If there is a bug, please break it down in detail.\\n// If it is a misalignment, please describe what you think happened.\\n\\n// Use the provided history of actions the agent took as well as the most recent screenshot to help you identify what happened.\\n\\n// {{ ctx.output_format }}\\n\\n// {{ _.role(\\\"user\\\") }}\\n\\n// The history of previous actions:\\n// {%if previousActions %}\\n// (there are none)\\n// {%endif%}\\n// {%for action in previousActions%}\\n// {{ action }}\\n// {%endfor%}\\n \\n// The step that failed: <step>{{ step.description }}</step>\\n// Target that could not be found: <target>{{ target }}</target>\\n \\n\\n// Current screenshot:\\n// {{screenshot}}\\n// \\\"#\\n// }\",\n \"extract.baml\": \"// if primitive, populate key \\\"data\\\"\\n// if array, populate key data with that array\\n// else fill with object fields\\nclass ExtractedData {\\n @@dynamic\\n}\\n\\nfunction ExtractData (instructions: string, screenshot: image, domContent: string) -> ExtractedData {\\n client GeminiPro\\n prompt #\\\"\\n {{ _.role(\\\"system\\\") }}\\n Based on the browser screenshot and page content, extract data according to these instructions:\\n <instructions>{{ instructions }}</instructions>\\n \\n {{ ctx.output_format }}\\n\\n {{ _.role(\\\"user\\\") }}\\n\\n {{ domContent }}\\n\\n {{ screenshot }}\\n \\\"#\\n}\",\n \"generators.baml\": \"// This helps use auto generate libraries you can use in the language of\\n// your choice. You can have multiple generators if you use multiple languages.\\n// Just ensure that the output_dir is different for each generator.\\ngenerator target {\\n // Valid values: \\\"python/pydantic\\\", \\\"typescript\\\", \\\"ruby/sorbet\\\", \\\"rest/openapi\\\"\\n output_type \\\"typescript\\\"\\n\\n // Where the generated code will be saved (relative to baml_src/)\\n output_dir \\\"../src/ai\\\"\\n\\n // The version of the BAML package you have installed (e.g. same version as your baml-py or @boundaryml/baml).\\n // The BAML VSCode extension version should also match this version.\\n version \\\"0.90.2\\\"\\n\\n // Valid values: \\\"sync\\\", \\\"async\\\"\\n // This controls what `b.FunctionName()` will be (sync or async).\\n default_client_mode async\\n}\\n\",\n \"memory.baml\": \"// BamlImage class is assumed to be defined and available from your BAML setup\\n// For example, it might be part of a core BAML library or generated separately.\\n// If not, you might need to define it or import it if it's in another baml file.\\n// For now, we assume 'Image' is a known type to BAML.\\n\\n// class BamlThought {\\n// variant \\\"thought\\\"\\n// timestamp string\\n// message string\\n// }\\n\\n// class BamlTurn {\\n// variant \\\"turn\\\"\\n// timestamp string\\n// action string \\n// content (string | image)[] // multimedia content \\\"chunks\\\"\\n// }\\n\\n\\n// class Observation {\\n// source string\\n// content (string | image)[] // multimedia content \\\"chunks\\\"\\n// }\\n\\nclass ConnectorInstructions {\\n connectorId string\\n instructions string\\n //content (string | image)[]\\n}\\n\\nclass ModularMemoryContext {\\n instructions string? // additional task-level or agent-level instructions\\n //history (BamlThought | BamlTurn)[]\\n //observations Observation[]\\n observationContent (string | image)[] // complete rendered observation content as multimedia content \\\"chunks\\\"\\n //currentTimestamp string\\n connectorInstructions ConnectorInstructions[]\\n}\\n\",\n \"planner.baml\": \"class PartialRecipe {\\n // this CoT pipeline is not thoroughly tested against alternatives\\n // observations string? @description(#\\\"Any key observations about past actions or current state\\\"#)\\n // meta_reasoning string @description(#\\\"Reflect on the current state of task execution with respect to your own abilities as an agent\\\"#)\\n // reasoning string @description(#\\\"Consider what you can see right now and what actions you can plan without guessing\\\"#)\\n\\n // Simplifying CoT - seemed to be causing underplanning on Claude\\n //observations string @description(#\\\"What important clues or key information are worth considering?\\\"#)\\n reasoning string @description(#\\\"What is the most actions you can safely take at once?\\\"#)\\n\\n //actions ActionIntent[]\\n @@dynamic\\n //finished bool\\n}\\n\\n\\n// render \\\"chunked\\\" multimedia content of strings or images with no added whitespace between\\ntemplate_string RenderContent(content: (string | image)[]) #\\\"\\n {% for chunk in content -%}{{chunk}}{%- endfor %}\\n\\\"#\\n\\n\\n// template_string DescribeModularMemoryContext(context: ModularMemoryContext) #\\\"\\n// {% for entry in context.history %}\\n// {% if entry.variant == \\\"thought\\\" %}\\n// [{{entry.timestamp}}] {{entry.message}}\\n// {% elif entry.variant == \\\"turn\\\" %}\\n// [{{entry.timestamp}}] {{entry.action}}\\n// {{ RenderContent(entry.content) }}\\n// {% endif %}\\n// {% endfor %}\\n// \\\"#\\n\\n// unused\\ntemplate_string HybridMeta #\\\"\\n <meta>\\n You are a web agent powered by (1) a powerful LLM (you) and (2) a small vision model (Moondream).\\n You operate by planning out actions over time to try and complete a certain task.\\n To do this successfully you may need to consider and adjust for your own limitations as an agent, so here is so