@awi-protocol/sdk 0.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 +195 -0
- package/dist/index.d.mts +382 -0
- package/dist/index.d.ts +382 -0
- package/dist/index.js +766 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +733 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/advisory-executor.ts","../src/compiler/local-axir.ts","../src/compiler/grammar/axir-schema.gbnf"],"sourcesContent":["/**\n * AWI (Agent Web Interface) JavaScript SDK\n * \n * Deterministic web automation for AI agents.\n * \n * @example\n * ```typescript\n * import { AWIClient } from '@awi-protocol/sdk';\n * \n * const client = new AWIClient({\n * endpoint: 'https://awi.example.com',\n * certificate: 'your-jwt-token',\n * });\n * \n * const result = await client.execute({\n * target: 'awi://linkedin.com/jobs/search/v1',\n * params: { query: 'rust engineer' },\n * });\n * ```\n */\n\nexport { AWIClient, AWIError } from './client';\nexport { AdvisoryExecutor } from './advisory-executor';\nexport {\n LocalAXIRCompiler,\n type LocalAXIRCompilerOptions,\n} from './compiler/local-axir';\nexport type {\n AgentRequest,\n AgentResponse,\n Recipe,\n RecipeStep,\n SelectorSet,\n Selector,\n ExtractionSpec,\n ExtractionField,\n ValidationRules,\n AXIRIntent,\n RegistryEntry,\n FeedbackRequest,\n DelegationRequest,\n AWIClientOptions,\n ExecutionMetrics,\n ExecutionMode,\n RecipeStatus,\n AgentTier,\n} from './types';\nexport type {\n AXIRNode,\n AXIREdge,\n AXIRWorkflow,\n AXIRIntentMapping,\n AXIRField,\n AXIRCompilationResult,\n AXIRHealingResult,\n SelectorCandidate,\n PageType,\n} from './compiler/types';\n\nexport { default } from './client';\n","/**\n * AWI Client\n * \n * Main SDK class for interacting with AWI servers.\n * Supports proxy mode (server executes browser) and advisory mode (returns blueprint).\n */\n\nimport fetch from 'cross-fetch';\nimport type {\n AgentRequest,\n AgentResponse,\n AWIClientOptions,\n Recipe,\n RegistryEntry,\n FeedbackRequest,\n DelegationRequest,\n ExecutionMetrics,\n} from './types';\n\nexport class AWIError extends Error {\n code: string;\n statusCode: number;\n details?: Record<string, unknown>;\n\n constructor(code: string, message: string, statusCode: number, details?: Record<string, unknown>) {\n super(message);\n this.name = 'AWIError';\n this.code = code;\n this.statusCode = statusCode;\n this.details = details;\n }\n}\n\nexport class AWIClient {\n private endpoint: string;\n private certificate: string;\n private timeout: number;\n private retries: number;\n\n constructor(options: AWIClientOptions) {\n this.endpoint = options.endpoint.replace(/\\/$/, '');\n this.certificate = options.certificate;\n this.timeout = options.timeout || 30000;\n this.retries = options.retries || 3;\n }\n\n /**\n * Execute a recipe in proxy mode.\n * The server runs the browser and returns structured data.\n */\n async execute<T = unknown>(request: Omit<AgentRequest, 'mode'>): Promise<AgentResponse<T>> {\n return this._request<AgentResponse<T>>('/v1/execute', {\n ...request,\n mode: 'proxy',\n });\n }\n\n /**\n * Get advisory blueprint for agent-side execution.\n * Returns the recipe structure without running the browser.\n */\n async getAdvisory(target: string): Promise<AgentResponse<Recipe>> {\n return this._request<AgentResponse<Recipe>>('/v1/advisory', {\n target,\n });\n }\n\n /**\n * Execute in advisory mode - get blueprint then run locally.\n * This is useful when you want to control the browser yourself.\n */\n async executeAdvisory<T = unknown>(\n request: Omit<AgentRequest, 'mode'>,\n localExecutor: (blueprint: Recipe, params: Record<string, unknown>) => Promise<T>\n ): Promise<AgentResponse<T>> {\n // Get blueprint\n const advisory = await this.getAdvisory(request.target);\n\n if (!advisory.success || !advisory.data) {\n return {\n ...advisory,\n data: null,\n } as AgentResponse<T>;\n }\n\n // Execute locally\n const startTime = Date.now();\n try {\n const data = await localExecutor(advisory.data, request.params);\n const latency = Date.now() - startTime;\n\n return {\n success: true,\n data,\n errors: [],\n metadata: {\n ...advisory.metadata,\n latency_ms: latency,\n mode: 'advisory-local',\n },\n execution_path: ['advisory', 'local-execution'],\n axir_intent: advisory.axir_intent,\n };\n } catch (error) {\n return {\n success: false,\n data: null,\n errors: [{\n code: 'LOCAL_EXECUTION_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n }],\n metadata: advisory.metadata,\n execution_path: ['advisory', 'local-execution-failed'],\n };\n }\n }\n\n /**\n * Submit feedback on execution quality.\n */\n async feedback(request: FeedbackRequest): Promise<AgentResponse<{ feedback_received: boolean }>> {\n return this._request('/v1/feedback', request);\n }\n\n /**\n * Explore an unknown domain and generate a recipe.\n */\n async explore(domain: string, action: string, resource?: string): Promise<AgentResponse<Recipe>> {\n const target = `awi://${domain}/${resource || action}/${action}/v1`;\n return this._request('/v1/execute', {\n target,\n params: {},\n mode: 'proxy',\n options: { explore: true },\n });\n }\n\n /**\n * List supported sites in the registry.\n */\n async listRegistry(options?: {\n category?: string;\n certifiedOnly?: boolean;\n minConfidence?: number;\n search?: string;\n limit?: number;\n }): Promise<AgentResponse<{ sites: RegistryEntry[]; stats: Record<string, unknown> }>> {\n const params = new URLSearchParams();\n if (options?.category) params.set('category', options.category);\n if (options?.certifiedOnly) params.set('certified_only', 'true');\n if (options?.minConfidence) params.set('min_confidence', String(options.minConfidence));\n if (options?.search) params.set('search', options.search);\n if (options?.limit) params.set('limit', String(options.limit));\n\n return this._request(`/v1/registry?${params.toString()}`, undefined, 'GET');\n }\n\n /**\n * Search registry.\n */\n async searchRegistry(query: string, limit?: number): Promise<AgentResponse<{ results: RegistryEntry[] }>> {\n const params = new URLSearchParams();\n params.set('q', query);\n if (limit) params.set('limit', String(limit));\n\n return this._request(`/v1/registry/search?${params.toString()}`, undefined, 'GET');\n }\n\n /**\n * Delegate execution to another agent.\n */\n async delegate(request: DelegationRequest): Promise<AgentResponse<{ delegation_id: string }>> {\n return this._request('/v1/delegate', request);\n }\n\n /**\n * Join a multi-agent session.\n */\n async joinSession(sessionId: string): Promise<AgentResponse<{ session_id: string; participants: string[] }>> {\n return this._request('/v1/session/join', { session_id: sessionId });\n }\n\n /**\n * Check server health.\n */\n async health(): Promise<{ status: string; version: string }> {\n const response = await fetch(`${this.endpoint}/health`, {\n method: 'GET',\n headers: {\n 'Accept': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new AWIError('HEALTH_CHECK_FAILED', 'Server health check failed', response.status);\n }\n\n return response.json();\n }\n\n /**\n * Get execution metrics from a response.\n */\n getMetrics(response: AgentResponse<unknown>): ExecutionMetrics {\n return {\n latency_ms: response.metadata?.latency_ms || 0,\n fallback_count: (response.metadata?.fallback_count as number) || 0,\n selectors_used: (response.metadata?.selectors_used as string[]) || [],\n cache_status: response.metadata?.cache_status || 'miss',\n };\n }\n\n private async _request<T>(\n path: string,\n body?: unknown,\n method: string = 'POST'\n ): Promise<T> {\n const url = `${this.endpoint}${path}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'AWI-Agent-Certificate': this.certificate,\n };\n\n let lastError: Error | undefined;\n\n for (let attempt = 0; attempt < this.retries; attempt++) {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n const response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new AWIError(\n errorData.errors?.[0]?.code || 'REQUEST_FAILED',\n errorData.errors?.[0]?.message || `HTTP ${response.status}`,\n response.status,\n errorData\n );\n }\n\n return response.json() as Promise<T>;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n // Don't retry on 4xx errors (client errors)\n if (error instanceof AWIError && error.statusCode >= 400 && error.statusCode < 500) {\n throw error;\n }\n\n // Wait before retry (exponential backoff)\n if (attempt < this.retries - 1) {\n await new Promise(resolve => setTimeout(resolve, Math.pow(2, attempt) * 1000));\n }\n }\n }\n\n throw lastError || new AWIError('MAX_RETRIES', 'Max retries exceeded', 502);\n }\n}\n\nexport default AWIClient;\n","/**\n * Advisory Mode Executor\n * \n * Executes recipe blueprints locally in a browser or Node.js environment.\n * Useful when you want to control the browser yourself but use AWI selectors.\n */\n\nimport type { Recipe, RecipeStep, SelectorSet, ExecutionMetrics } from './types';\n\nexport interface LocalExecutionContext {\n document: Document;\n window: Window;\n console: Console;\n}\n\nexport class AdvisoryExecutor {\n private context: LocalExecutionContext;\n private metrics: ExecutionMetrics;\n\n constructor(context: LocalExecutionContext) {\n this.context = context;\n this.metrics = {\n latency_ms: 0,\n fallback_count: 0,\n selectors_used: [],\n cache_status: 'bypass',\n };\n }\n\n /**\n * Execute a recipe blueprint locally.\n */\n async execute<T = unknown>(recipe: Recipe, params: Record<string, unknown>): Promise<{\n success: boolean;\n data: T | null;\n errors: Array<{ code: string; message: string }>;\n metrics: ExecutionMetrics;\n }> {\n const startTime = Date.now();\n const errors: Array<{ code: string; message: string }> = [];\n const executionPath: string[] = [];\n\n try {\n // Execute steps\n for (const step of recipe.steps) {\n const stepResult = await this._executeStep(step, params, recipe);\n\n if (stepResult.error) {\n errors.push(stepResult.error);\n break;\n }\n\n executionPath.push(`${step.type}:${step.name || 'unnamed'}`);\n }\n\n // Extract data if all steps passed\n let data: T | null = null;\n if (errors.length === 0 && recipe.extraction) {\n data = await this._extractData<T>(recipe);\n }\n\n this.metrics.latency_ms = Date.now() - startTime;\n\n return {\n success: errors.length === 0,\n data,\n errors,\n metrics: { ...this.metrics },\n };\n } catch (error) {\n return {\n success: false,\n data: null,\n errors: [{\n code: 'EXECUTION_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n }],\n metrics: { ...this.metrics },\n };\n }\n }\n\n private async _executeStep(\n step: RecipeStep,\n params: Record<string, unknown>,\n recipe: Recipe\n ): Promise<{ error?: { code: string; message: string } }> {\n try {\n switch (step.type) {\n case 'navigate':\n if (step.url) {\n const url = this._interpolate(step.url, params);\n this.context.window.location.href = url;\n }\n break;\n\n case 'wait':\n if (step.selector) {\n const selectorSet = recipe.selectors[step.selector];\n if (selectorSet) {\n await this._waitForSelector(selectorSet);\n }\n } else {\n await this._sleep(1000);\n }\n break;\n\n case 'click':\n if (step.selector) {\n const element = this._resolveSelector(recipe.selectors[step.selector]);\n if (element) {\n element.click();\n } else {\n return { error: { code: 'CLICK_FAILED', message: `Selector not found: ${step.selector}` } };\n }\n }\n break;\n\n case 'type':\n if (step.selector && step.value) {\n const element = this._resolveSelector(recipe.selectors[step.selector]) as HTMLInputElement | null;\n if (element) {\n const value = this._interpolate(step.value, params);\n element.value = value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n } else {\n return { error: { code: 'TYPE_FAILED', message: `Selector not found: ${step.selector}` } };\n }\n }\n break;\n\n case 'scroll':\n const amount = step.amount || 500;\n this.context.window.scrollBy(0, amount);\n break;\n\n case 'extract_list':\n case 'extract_one':\n // Extraction happens after all steps\n break;\n }\n\n return {};\n } catch (error) {\n return {\n error: {\n code: 'STEP_ERROR',\n message: error instanceof Error ? error.message : 'Unknown step error',\n },\n };\n }\n }\n\n private async _extractData<T>(recipe: Recipe): Promise<T | null> {\n const extraction = recipe.extraction;\n if (!extraction) return null;\n\n const containerSet = recipe.selectors[extraction.container];\n if (!containerSet) return null;\n\n const container = this._resolveSelector(containerSet);\n if (!container) return null;\n\n const items = extraction.mode === 'list' \n ? Array.from(container.children)\n : [container];\n\n const results: Array<Record<string, unknown>> = [];\n\n for (const item of items) {\n const record: Record<string, unknown> = {};\n\n for (const field of extraction.fields) {\n const fieldSet = recipe.selectors[field.selector];\n if (fieldSet) {\n const fieldElement = this._resolveSelectorWithin(item as HTMLElement, fieldSet);\n if (fieldElement) {\n let value = fieldElement.textContent || '';\n\n // Apply transform\n if (field.transform) {\n value = String(this._applyTransform(value, field.transform));\n }\n\n record[field.name] = value;\n } else {\n record[field.name] = null;\n }\n }\n }\n\n results.push(record);\n }\n\n return (extraction.mode === 'one' ? results[0] : results) as T;\n }\n\n private _resolveSelector(selectorSet: SelectorSet): HTMLElement | null {\n for (const selector of selectorSet.selectors) {\n const element = this._trySelector(selector.type, selector.value);\n if (element) {\n this.metrics.selectors_used.push(selectorSet.name);\n return element;\n }\n this.metrics.fallback_count++;\n }\n return null;\n }\n\n private _resolveSelectorWithin(parent: HTMLElement, selectorSet: SelectorSet): HTMLElement | null {\n for (const selector of selectorSet.selectors) {\n try {\n const element = parent.querySelector(selector.value) as HTMLElement | null;\n if (element) {\n this.metrics.selectors_used.push(selectorSet.name);\n return element;\n }\n } catch {\n // Invalid selector, try next\n }\n }\n return null;\n }\n\n private _trySelector(type: string, value: string): HTMLElement | null {\n try {\n switch (type) {\n case 'css':\n return this.context.document.querySelector(value) as HTMLElement | null;\n case 'semantic':\n // Try data-testid\n return this.context.document.querySelector(`[data-testid=\"${value}\"]`) as HTMLElement | null;\n case 'text':\n // XPath or text content search\n const xpath = `//*[contains(text(), \"${value}\")]`;\n const result = this.context.document.evaluate(\n xpath,\n this.context.document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n return result.singleNodeValue as HTMLElement | null;\n case 'attribute':\n return this.context.document.querySelector(`[${value}]`) as HTMLElement | null;\n default:\n return null;\n }\n } catch {\n return null;\n }\n }\n\n private async _waitForSelector(selectorSet: SelectorSet, timeout: number = 10000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < timeout) {\n if (this._resolveSelector(selectorSet)) {\n return;\n }\n await this._sleep(100);\n }\n throw new Error(`Timeout waiting for selector: ${selectorSet.name}`);\n }\n\n private _interpolate(template: string, params: Record<string, unknown>): string {\n return template.replace(/\\{([^}]+)\\}/g, (match, key) => {\n const value = params[key];\n return value !== undefined ? String(value) : match;\n });\n }\n\n private _applyTransform(value: string, transform: string): string | number {\n switch (transform) {\n case 'strip':\n return value.trim();\n case 'strip_currency':\n return value.replace(/[$€,\\s]/g, '').trim();\n case 'number':\n const digits = value.replace(/[^0-9.]/g, '');\n return digits.includes('.') ? parseFloat(digits) : parseInt(digits, 10);\n case 'lower':\n return value.toLowerCase();\n case 'upper':\n return value.toUpperCase();\n default:\n return value;\n }\n }\n\n private _sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n\nexport default AdvisoryExecutor;\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport * as os from 'node:os';\nimport * as https from 'node:https';\nimport * as http from 'node:http';\n\nimport type {\n AXIRCompilationResult,\n AXIRHealingResult,\n} from './types';\n\nimport AXIR_GRAMMAR from './grammar/axir-schema.gbnf';\n\nlet nativeAvailable = false;\nlet getLlama: any;\n\n// Dynamically load the optional native dependency so the SDK works without it\ntry {\n const llama = require('node-llama-cpp');\n getLlama = llama.getLlama;\n nativeAvailable = true;\n} catch {\n nativeAvailable = false;\n}\n\nconst DEFAULT_MODEL_URL =\n 'https://huggingface.co/bartowski/Phi-3-mini-128k-instruct-GGUF/resolve/main/Phi-3-mini-128k-instruct-Q4_K_M.gguf';\n\nconst DEFAULT_MODEL_FILENAME = 'phi3-128k-q4.gguf';\n\nexport interface LocalAXIRCompilerOptions {\n modelPath?: string;\n modelUrl?: string;\n contextSize?: number;\n gpuLayers?: number;\n onDownloadProgress?: (downloaded: number, total: number) => void;\n onStatus?: (message: string) => void;\n}\n\nexport class LocalAXIRCompiler {\n private modelPath: string;\n private modelUrl: string;\n private contextSize: number;\n private gpuLayers: number | undefined;\n private onDownloadProgress?: (downloaded: number, total: number) => void;\n private onStatus?: (message: string) => void;\n\n private model: any = null;\n private context: any = null;\n private grammar: any = null;\n private ready = false;\n\n constructor(options: LocalAXIRCompilerOptions = {}) {\n if (!nativeAvailable) {\n throw new Error(\n 'Local AXIR compilation requires node-llama-cpp.\\n' +\n 'Install it: npm install node-llama-cpp\\n' +\n 'Note: this package contains native C++ bindings and needs build tools.\\n' +\n ' * macOS: Xcode Command Line Tools (xcode-select --install)\\n' +\n ' * Linux: build-essential / gcc-c++ / python3\\n' +\n ' * Windows: Visual Studio Build Tools or windows-build-tools npm package\\n' +\n 'Docs: https://github.com/withcatai/node-llama-cpp#installation'\n );\n }\n\n const cacheDir = path.join(os.homedir(), '.awi', 'models');\n this.modelPath = options.modelPath || path.join(cacheDir, DEFAULT_MODEL_FILENAME);\n this.modelUrl = options.modelUrl || DEFAULT_MODEL_URL;\n this.contextSize = options.contextSize || 32768;\n this.gpuLayers = options.gpuLayers;\n this.onDownloadProgress = options.onDownloadProgress;\n this.onStatus = options.onStatus;\n }\n\n // -------------------------------------------------------------------------\n // Public API\n // -------------------------------------------------------------------------\n\n async compile(\n domHTML: string,\n a11yTree: string,\n intent: string,\n params?: Record<string, unknown>\n ): Promise<AXIRCompilationResult> {\n await this._ensureModel();\n await this._ensureGrammar();\n\n const prompt = this._buildCompilePrompt(domHTML, a11yTree, intent, params);\n const start = Date.now();\n\n this._status('Compiling AXIR locally...');\n const resultText = await this._complete(prompt, 4096, 0.3);\n const parsed = JSON.parse(resultText) as AXIRCompilationResult;\n\n parsed.model_used = 'phi-3-mini-128k-q4-local';\n parsed.tokens_used = this._estimateTokens(prompt, resultText);\n parsed.compilation_time_ms = Date.now() - start;\n\n this._status(`AXIR compiled in ${parsed.compilation_time_ms}ms`);\n return parsed;\n }\n\n async heal(\n domHTML: string,\n brokenSelector: string,\n semanticIntent: string\n ): Promise<AXIRHealingResult> {\n await this._ensureModel();\n\n const prompt = this._buildHealPrompt(domHTML, brokenSelector, semanticIntent);\n const start = Date.now();\n\n this._status('Healing selector locally...');\n const resultText = await this._complete(prompt, 256, 0.1);\n\n let selector: string;\n let confidence = 0.85;\n let reasoning: string | undefined;\n\n try {\n const parsed = JSON.parse(resultText);\n selector = parsed.selector ?? parsed;\n confidence = parsed.confidence ?? 0.85;\n reasoning = parsed.reasoning;\n } catch {\n selector = resultText.trim().replace(/^[\"']|[\"']$/g, '');\n }\n\n this._status(`Selector healed in ${Date.now() - start}ms`);\n return { selector, confidence, reasoning };\n }\n\n isModelCached(): boolean {\n return fs.existsSync(this.modelPath);\n }\n\n clearCache(): void {\n if (fs.existsSync(this.modelPath)) {\n fs.unlinkSync(this.modelPath);\n this.model = null;\n this.context = null;\n this.grammar = null;\n this.ready = false;\n }\n }\n\n // -------------------------------------------------------------------------\n // Model lifecycle\n // -------------------------------------------------------------------------\n\n private async _ensureModel(): Promise<void> {\n if (this.ready) return;\n\n if (!fs.existsSync(this.modelPath)) {\n await this._downloadModel();\n }\n\n this._status('Loading local model...');\n const llama = await getLlama();\n\n const gpuLayers = this.gpuLayers ?? this._autoDetectGPULayers();\n this.model = new llama.LlamaModel({\n modelPath: this.modelPath,\n gpuLayers,\n });\n\n // node-llama-cpp v3 API: context is created via the model\n this.context = await this.model.createContext({\n contextSize: this.contextSize,\n });\n\n this.ready = true;\n this._status('Local model ready.');\n }\n\n private async _ensureGrammar(): Promise<void> {\n if (this.grammar) return;\n const llama = await getLlama();\n this.grammar = new llama.LlamaGrammar({\n grammar: AXIR_GRAMMAR,\n });\n }\n\n private _autoDetectGPULayers(): number {\n if (process.env.AWI_GPU_LAYERS) {\n return parseInt(process.env.AWI_GPU_LAYERS, 10);\n }\n return 0;\n }\n\n // -------------------------------------------------------------------------\n // Resumable model download\n // -------------------------------------------------------------------------\n\n private async _downloadModel(): Promise<void> {\n const dir = path.dirname(this.modelPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const tempPath = `${this.modelPath}.tmp`;\n const urlObj = new URL(this.modelUrl);\n const protocol = urlObj.protocol === 'https:' ? https : http;\n\n let startByte = 0;\n if (fs.existsSync(tempPath)) {\n startByte = fs.statSync(tempPath).size;\n this._status(`Resuming download from ${startByte} bytes...`);\n } else {\n this._status('Downloading local compiler model (2.7GB, one-time)...');\n }\n\n return new Promise<void>((resolve, reject) => {\n const headers: http.OutgoingHttpHeaders = {\n 'User-Agent': 'AWI-SDK/1.0',\n };\n if (startByte > 0) {\n headers['Range'] = `bytes=${startByte}-`;\n }\n\n const request = protocol.get(\n urlObj,\n { headers },\n (response) => {\n if (response.statusCode === 301 || response.statusCode === 302) {\n if (response.headers.location) {\n this.modelUrl = response.headers.location;\n return this._downloadModel().then(resolve).catch(reject);\n }\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 206) {\n return reject(\n new Error(`Model download failed: HTTP ${response.statusCode}`)\n );\n }\n\n const total = parseInt(\n response.headers['content-length'] || '0',\n 10\n );\n const append = startByte > 0 && response.statusCode === 206;\n const file = fs.createWriteStream(tempPath, { flags: append ? 'a' : 'w' });\n let downloaded = startByte;\n\n response.on('data', (chunk: Buffer) => {\n downloaded += chunk.length;\n this.onDownloadProgress?.(downloaded, total + startByte);\n });\n\n response.pipe(file);\n file.on('finish', () => {\n file.close();\n fs.renameSync(tempPath, this.modelPath);\n this._status('Model download complete.');\n resolve();\n });\n\n file.on('error', (err: Error) => {\n fs.unlinkSync(tempPath);\n reject(err);\n });\n }\n );\n\n request.on('error', reject);\n request.setTimeout(300_000, () => {\n request.destroy();\n reject(new Error('Model download timed out after 5 minutes'));\n });\n });\n }\n\n // -------------------------------------------------------------------------\n // Inference\n // -------------------------------------------------------------------------\n\n private async _complete(\n prompt: string,\n maxTokens: number,\n temperature: number\n ): Promise<string> {\n if (!this.context) throw new Error('Model not loaded');\n\n const sequence = this.context.getSequence();\n await sequence.evaluate(prompt);\n\n const response = await sequence.generateResponse(maxTokens, {\n temperature,\n grammar: this.grammar,\n });\n\n let text = '';\n for await (const token of response) {\n text += token;\n }\n return text;\n }\n\n // -------------------------------------------------------------------------\n // Prompt builders\n // -------------------------------------------------------------------------\n\n private _buildCompilePrompt(\n domHTML: string,\n a11yTree: string,\n intent: string,\n params?: Record<string, unknown>\n ): string {\n const paramsJson = params ? JSON.stringify(params, null, 2) : '{}';\n\n return [\n `<|system|>`,\n `You are an expert web-scraping analyst. Your job is to read a simplified DOM and accessibility tree, then output a structured JSON object describing the page layout, interactive elements, and data extraction plan.`,\n ``,\n `Output MUST be valid JSON matching this schema:`,\n `- workflow.nodes: map of node_id -> {element_type, semantic_role, intent, tag, selector_candidates[], parent_id?, children_ids?, aria_label?, aria_role?, text_content?, confidence, reasoning?}`,\n `- workflow.edges: list of {from_node, to_node, action, condition?, probability}`,\n `- workflow.entry_points: list of starting node_ids`,\n `- workflow.exit_points: list of terminal node_ids`,\n `- workflow.domain: the domain name`,\n `- workflow.page_type: one of landing|search|listing|detail|form|checkout|dashboard|unknown`,\n `- intents: list of {intent, action, parameters[], context}`,\n `- selectors: map of selector_name -> list of {type, value, priority}`,\n `- fields: list of {name, selector, transform?, required}`,\n `- container?: string (optional container selector name)`,\n ``,\n `Element types: button, link, input, form, navigation, search, filter, sort, pagination, container, list, item, heading, text, image, unknown.`,\n `Selector types: css, semantic, text, attribute.`,\n `<|user|>`,\n `Intent: ${intent}`,\n `Parameters: ${paramsJson}`,\n ``,\n `Simplified DOM:`,\n `${this._truncate(domHTML, 40_000)}`,\n ``,\n `Accessibility Tree:`,\n `${this._truncate(a11yTree, 8_000)}`,\n ``,\n `Compile AXIR:`,\n `<|assistant|>`,\n ].join('\\n');\n }\n\n private _buildHealPrompt(\n domHTML: string,\n brokenSelector: string,\n semanticIntent: string\n ): string {\n return [\n `<|system|>`,\n `You are a CSS selector repair tool. Given a broken selector and the current DOM, output the new CSS selector that targets the same semantic element.`,\n ``,\n `Output JSON: {\"selector\": \"...\", \"confidence\": 0.0-1.0, \"reasoning\": \"...\"}`,\n `<|user|>`,\n `Broken selector: ${brokenSelector}`,\n `Semantic intent: ${semanticIntent}`,\n ``,\n `Current DOM (truncated):`,\n `${this._truncate(domHTML, 20_000)}`,\n ``,\n `New selector:`,\n `<|assistant|>`,\n ].join('\\n');\n }\n\n private _truncate(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return text.slice(0, maxChars) + '\\n[...truncated...]';\n }\n\n private _estimateTokens(prompt: string, response: string): number {\n return Math.ceil((prompt.length + response.length) / 4);\n }\n\n private _status(message: string): void {\n this.onStatus?.(message);\n }\n}\n","root ::= \"{\" ws axir-fields ws \"}\"\n\naxir-fields ::=\n \"\\\"workflow\\\"\" \":\" workflow ws \",\"\n ws \"\\\"intents\\\"\" \":\" intents ws \",\"\n ws \"\\\"selectors\\\"\" \":\" selectors ws \",\"\n ws \"\\\"fields\\\"\" \":\" fields\n [\",\" ws \"\\\"container\\\"\" \":\" string]\n [\",\" ws \"\\\"model_used\\\"\" \":\" string]\n [\",\" ws \"\\\"tokens_used\\\"\" \":\" number]\n [\",\" ws \"\\\"compilation_time_ms\\\"\" \":\" number]\n\nworkflow ::=\n \"{\" ws\n \"\\\"nodes\\\"\" \":\" \"{\" ws node-list ws \"}\" ws \",\"\n ws \"\\\"edges\\\"\" \":\" \"[\" ws edge-list ws \"]\" ws \",\"\n ws \"\\\"entry_points\\\"\" \":\" \"[\" ws string-list ws \"]\" ws \",\"\n ws \"\\\"exit_points\\\"\" \":\" \"[\" ws string-list ws \"]\" ws \",\"\n ws \"\\\"domain\\\"\" \":\" string ws \",\"\n ws \"\\\"page_type\\\"\" \":\" page-type\n [\",\" ws \"\\\"structure_hash\\\"\" \":\" string]\n ws \"}\"\n\nnode-list ::= [node-pair (\",\" ws node-pair)*]\nnode-pair ::= string \":\" \"{\" ws\n \"\\\"element_type\\\"\" \":\" element-type ws \",\"\n ws \"\\\"semantic_role\\\"\" \":\" string ws \",\"\n ws \"\\\"intent\\\"\" \":\" string ws \",\"\n ws \"\\\"tag\\\"\" \":\" string ws \",\"\n ws \"\\\"selector_candidates\\\"\" \":\" \"[\" ws selector-list ws \"]\"\n [\",\" ws \"\\\"parent_id\\\"\" \":\" string]\n [\",\" ws \"\\\"children_ids\\\"\" \":\" \"[\" ws string-list ws \"]\"]\n [\",\" ws \"\\\"aria_label\\\"\" \":\" string]\n [\",\" ws \"\\\"aria_role\\\"\" \":\" string]\n [\",\" ws \"\\\"text_content\\\"\" \":\" string]\n \",\" ws \"\\\"confidence\\\"\" \":\" number\n [\",\" ws \"\\\"reasoning\\\"\" \":\" string]\nws \"}\"\n\nelement-type ::=\n \"\\\"button\\\"\" | \"\\\"link\\\"\" | \"\\\"input\\\"\" | \"\\\"form\\\"\" |\n \"\\\"navigation\\\"\" | \"\\\"search\\\"\" | \"\\\"filter\\\"\" | \"\\\"sort\\\"\" |\n \"\\\"pagination\\\"\" | \"\\\"container\\\"\" | \"\\\"list\\\"\" | \"\\\"item\\\"\" |\n \"\\\"heading\\\"\" | \"\\\"text\\\"\" | \"\\\"image\\\"\" | \"\\\"unknown\\\"\"\n\npage-type ::=\n \"\\\"landing\\\"\" | \"\\\"search\\\"\" | \"\\\"listing\\\"\" | \"\\\"detail\\\"\" |\n \"\\\"form\\\"\" | \"\\\"checkout\\\"\" | \"\\\"dashboard\\\"\" | \"\\\"unknown\\\"\"\n\nedge-list ::= [edge (\",\" ws edge)*]\nedge ::= \"{\" ws\n \"\\\"from_node\\\"\" \":\" string ws \",\"\n ws \"\\\"to_node\\\"\" \":\" string ws \",\"\n ws \"\\\"action\\\"\" \":\" string\n [\",\" ws \"\\\"condition\\\"\" \":\" string]\n [\",\" ws \"\\\"probability\\\"\" \":\" number]\nws \"}\"\n\nselector-list ::= [selector (\",\" ws selector)*]\nselector ::= \"{\" ws\n \"\\\"type\\\"\" \":\" selector-type ws \",\"\n ws \"\\\"value\\\"\" \":\" string ws \",\"\n ws \"\\\"priority\\\"\" \":\" number\n [\",\" ws \"\\\"confidence\\\"\" \":\" number]\nws \"}\"\n\nselector-type ::= \"\\\"css\\\"\" | \"\\\"semantic\\\"\" | \"\\\"text\\\"\" | \"\\\"attribute\\\"\"\n\nintents ::= \"[\" ws [intent (\",\" ws intent)*] ws \"]\"\nintent ::= \"{\" ws\n \"\\\"intent\\\"\" \":\" string ws \",\"\n ws \"\\\"action\\\"\" \":\" string ws \",\"\n ws \"\\\"parameters\\\"\" \":\" \"[\" ws [string (\",\" ws string)*] ws \"]\" ws \",\"\n ws \"\\\"context\\\"\" \":\" string\nws \"}\"\n\nfields ::= \"[\" ws [field (\",\" ws field)*] ws \"]\"\nfield ::= \"{\" ws\n \"\\\"name\\\"\" \":\" string ws \",\"\n ws \"\\\"selector\\\"\" \":\" string\n [\",\" ws \"\\\"transform\\\"\" \":\" string]\n [\",\" ws \"\\\"required\\\"\" \":\" boolean]\nws \"}\"\n\nselectors ::= \"{\" ws [selector-pair (\",\" ws selector-pair)*] ws \"}\"\nselector-pair ::= string \":\" \"[\" ws selector-list ws \"]\"\n\nstring-list ::= [string (\",\" ws string)*]\n\nstring ::= \"\\\"\" char* \"\\\"\"\nchar ::= [^\"\\\\] | \"\\\\\" ([\"\\\\/bfnrt] | \"u\" [0-9a-fA-F]{4})\n\nnumber ::= [\"-\"]? (\"0\" | [1-9] [0-9]*) ([.] [0-9]+)? ([eE] [\"-\"]? [0-9]+)?\n\nboolean ::= \"true\" | \"false\"\n\nws ::= [ \\t\\n\\r]*\n"],"mappings":"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","names":["fetch","path"]}
|