diff --git a/packages/imhotep-core/src/canonical.ts b/packages/imhotep-core/src/canonical.ts index c60a5ea..c12fb9e 100644 --- a/packages/imhotep-core/src/canonical.ts +++ b/packages/imhotep-core/src/canonical.ts @@ -778,7 +778,9 @@ export function adaptSolverWorldToCanonical( matrices: solverWorld.matrices ?? { values: [] }, rects: solverWorld.rects, boxes: solverWorld.boxes, - visualBoxes: solverWorld.visualBoxes ?? solverWorld.boxes, + visualBoxes: solverWorld.visualBoxes && solverWorld.visualBoxes.boxId.length > 0 + ? solverWorld.visualBoxes + : (console.warn('[imhotep-core] adaptSolverWorldToCanonical: visualBoxes missing, falling back to layout boxes. Visual-space assertions may produce incorrect results.'), solverWorld.boxes), fragments: { fragmentId: [], subjectId: [], diff --git a/packages/imhotep-core/src/pipeline.ts b/packages/imhotep-core/src/pipeline.ts index 2429d6f..52ce22c 100644 --- a/packages/imhotep-core/src/pipeline.ts +++ b/packages/imhotep-core/src/pipeline.ts @@ -802,8 +802,8 @@ export function executionIrToClauseDescriptors(context: ExecutionContext): Claus clauseKind: 'unknown', version: 1, subjectRef: executionIr.clauseSubject[i], - referenceRef: executionIr.clauseReference[i] || undefined, - frameRef: executionIr.clauseFrame[i] || undefined, + referenceRef: executionIr.clauseReference[i] ?? undefined, + frameRef: executionIr.clauseFrame[i] ?? undefined, options: { unsupported: true, rawType: clauseType }, }) continue @@ -837,13 +837,13 @@ export function executionIrToClauseDescriptors(context: ExecutionContext): Claus clauseId: `clause_${i}`, clauseKind, version: 1, - subjectRef: subjectRef || undefined, - referenceRef: referenceRef || undefined, - frameRef: executionIr.clauseFrame[i] || undefined, - stateRef: context.stateIds[executionIr.clauseState[i]] || undefined, - timelineRef: context.timelineIds[executionIr.clauseTimeline[i]] || undefined, - envGuardRef: context.envGuardIds[executionIr.clauseEnvGuard[i]] || undefined, - toleranceRef: context.toleranceIds[executionIr.clauseTolerance[i]] || undefined, + subjectRef: subjectRef ?? undefined, + referenceRef: referenceRef ?? undefined, + frameRef: executionIr.clauseFrame[i] ?? undefined, + stateRef: context.stateIds[executionIr.clauseState[i]] ?? undefined, + timelineRef: context.timelineIds[executionIr.clauseTimeline[i]] ?? undefined, + envGuardRef: context.envGuardIds[executionIr.clauseEnvGuard[i]] ?? undefined, + toleranceRef: context.toleranceIds[executionIr.clauseTolerance[i]] ?? undefined, bounds: Object.keys(bounds).length > 0 ? bounds : undefined, options: Object.keys(options).length > 0 ? options : undefined, }) diff --git a/packages/imhotep-geometry/src/domain-index.ts b/packages/imhotep-geometry/src/domain-index.ts index ffde03f..da5a9c5 100644 --- a/packages/imhotep-geometry/src/domain-index.ts +++ b/packages/imhotep-geometry/src/domain-index.ts @@ -16,7 +16,7 @@ import { GeometryWorld } from './world.js' * If the selector is not indexed, returns an empty array. */ export function getElementsBySelector(world: GeometryWorld, selector: string): number[] { - const normalized = selector.trim().toLowerCase() + const normalized = selector.trim() return world.selectorIndex.get(normalized) ?? [] } diff --git a/packages/imhotep-playwright/src/extraction.ts b/packages/imhotep-playwright/src/extraction.ts index 67d6301..b8a5c23 100644 --- a/packages/imhotep-playwright/src/extraction.ts +++ b/packages/imhotep-playwright/src/extraction.ts @@ -409,12 +409,11 @@ export async function extractWorldFastGeometry( selectorToIds: Array<[string, number[]]> } - const selectorPlans: SelectorPlan[] = await Promise.all( - selectors.map(async (key, i) => { - const queries = await materializeSemanticSelector(playwrightPage, key, i) - return { key, queries } - }), - ) + const selectorPlans: SelectorPlan[] = [] + for (let i = 0; i < selectors.length; i++) { + const queries = await materializeSemanticSelector(playwrightPage, selectors[i], i) + selectorPlans.push({ key: selectors[i], queries }) + } try { const extracted = await playwrightPage.evaluate(({ plans, needs }: any) => { @@ -800,12 +799,11 @@ export async function extractWorldCdp( const errors: ImhotepDiagnostic[] = [] const selectorToNodeIds = new Map() - const selectorPlans: SelectorPlan[] = await Promise.all( - selectors.map(async (key, i) => { - const queries = await materializeSemanticSelector(playwrightPage, key, i) - return { key, queries } - }), - ) + const selectorPlans: SelectorPlan[] = [] + for (let i = 0; i < selectors.length; i++) { + const queries = await materializeSemanticSelector(playwrightPage, selectors[i], i) + selectorPlans.push({ key: selectors[i], queries }) + } const sessionManager = createSessionManager(playwrightPage) try { @@ -993,12 +991,11 @@ export async function extractWorld( if (requiredFacts?.styles) { try { - const plans: SelectorPlan[] = await Promise.all( - filteredSelectors.map(async (key, i) => { - const queries = await materializeSemanticSelector(playwrightPage, key, i) - return { key, queries } - }), - ) + const plans: SelectorPlan[] = [] + for (let i = 0; i < filteredSelectors.length; i++) { + const queries = await materializeSemanticSelector(playwrightPage, filteredSelectors[i], i) + plans.push({ key: filteredSelectors[i], queries }) + } const chWidthsBySelector = await measureChWidthsByPlan(playwrightPage, plans) attachMeasuredChWidths(result.world, result.selectorToIds, chWidthsBySelector) } catch { diff --git a/packages/imhotep-solver/src/engine.ts b/packages/imhotep-solver/src/engine.ts index 131ea92..ff6e69d 100644 --- a/packages/imhotep-solver/src/engine.ts +++ b/packages/imhotep-solver/src/engine.ts @@ -272,7 +272,13 @@ export function evaluate( diagnostics.push(...result.diagnostics); } } catch (err) { - const message = err instanceof Error ? err.message : String(err); + const message = err instanceof Error ? err.message : String(err) + const stack = err instanceof Error ? err.stack : undefined + console.warn(`[imhotep-solver] clause evaluator exception for kind "${clause.clauseKind}" (id ${clause.clauseId}): ${message}`) + if (stack) console.warn(stack) + const detail = err instanceof Error && err.name === 'TypeError' + ? `UNCAUGHT PROGRAMMING BUG: ${message}\n${stack ?? ''}` + : `Evaluator error: ${message}` const result: ClauseResult = { clauseId: clause.clauseId, status: 'error', @@ -282,7 +288,7 @@ export function evaluate( code: 'IMH_EVALUATOR_EXCEPTION', severity: 'error', category: 'internal-error', - message, + message: detail, clauseId: clause.clauseId, }, ],