Replace intent dimensions with corpus-backed problem picker#18
Merged
Conversation
There was a problem hiding this comment.
3 issues found across 20 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/web/app/app/new/intent/picker.tsx">
<violation number="1" location="packages/web/app/app/new/intent/picker.tsx:171">
P1: Cached chip clicks do not cancel/invalidate in-flight fetches, so stale responses can overwrite the current difficulty selection.</violation>
<violation number="2" location="packages/web/app/app/new/intent/picker.tsx:200">
P2: Error handling assumes `getSourceProblems` throws, but it always returns `[]` on failure, so fetch failures are misclassified as empty results.</violation>
</file>
<file name="packages/web/app/app/new/verify/view.tsx">
<violation number="1" location="packages/web/app/app/new/verify/view.tsx:142">
P2: Stale `intentSource` is not cleared when `srcRef` mismatches, which can run verification with the wrong source item.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Comment on lines
+171
to
+180
| if (cached !== undefined) { | ||
| setDisplayed(cached); | ||
| if ( | ||
| selectedItemId.length > 0 && | ||
| !cached.some((c) => c.item_id === selectedItemId) | ||
| ) { | ||
| setSelectedItemId(""); | ||
| } | ||
| return next; | ||
| }); | ||
| return; | ||
| } |
There was a problem hiding this comment.
P1: Cached chip clicks do not cancel/invalidate in-flight fetches, so stale responses can overwrite the current difficulty selection.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/web/app/app/new/intent/picker.tsx, line 171:
<comment>Cached chip clicks do not cancel/invalidate in-flight fetches, so stale responses can overwrite the current difficulty selection.</comment>
<file context>
@@ -131,31 +118,167 @@ export function IntentPicker({ schoolLevel, grade, topic, candidates }: Props) {
+ if (cache === null) return;
+
+ const cached = cache.get(chip);
+ if (cached !== undefined) {
+ setDisplayed(cached);
+ if (
</file context>
Suggested change
| if (cached !== undefined) { | |
| setDisplayed(cached); | |
| if ( | |
| selectedItemId.length > 0 && | |
| !cached.some((c) => c.item_id === selectedItemId) | |
| ) { | |
| setSelectedItemId(""); | |
| } | |
| return next; | |
| }); | |
| return; | |
| } | |
| if (cached !== undefined) { | |
| requestIdRef.current += 1; | |
| setLoadingDiff(false); | |
| setDisplayed(cached); | |
| if ( | |
| selectedItemId.length > 0 && | |
| !cached.some((c) => c.item_id === selectedItemId) | |
| ) { | |
| setSelectedItemId(""); | |
| } | |
| return; | |
| } |
| difficulty: chip, | ||
| limit: 30, | ||
| }); | ||
| } catch (err) { |
There was a problem hiding this comment.
P2: Error handling assumes getSourceProblems throws, but it always returns [] on failure, so fetch failures are misclassified as empty results.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/web/app/app/new/intent/picker.tsx, line 200:
<comment>Error handling assumes `getSourceProblems` throws, but it always returns `[]` on failure, so fetch failures are misclassified as empty results.</comment>
<file context>
@@ -131,31 +118,167 @@ export function IntentPicker({ schoolLevel, grade, topic, candidates }: Props) {
+ difficulty: chip,
+ limit: 30,
+ });
+ } catch (err) {
+ if (requestIdRef.current === myRequestId) {
+ console.warn(
</file context>
| } | ||
| const validated = parseIntentSource(parsed); | ||
| if (validated === null) return; | ||
| if (validated.item_id !== srcRef) return; |
There was a problem hiding this comment.
P2: Stale intentSource is not cleared when srcRef mismatches, which can run verification with the wrong source item.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/web/app/app/new/verify/view.tsx, line 142:
<comment>Stale `intentSource` is not cleared when `srcRef` mismatches, which can run verification with the wrong source item.</comment>
<file context>
@@ -91,41 +96,79 @@ function stateLabel(status: Step["status"]): string {
}
+ const validated = parseIntentSource(parsed);
+ if (validated === null) return;
+ if (validated.item_id !== srcRef) return;
+ setIntentSource(validated);
+ }, [srcRef]);
</file context>
Suggested change
| if (validated.item_id !== srcRef) return; | |
| if (validated.item_id !== srcRef) { | |
| setIntentSource(null); | |
| return; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
요약
S3(intent) 단계를 재설계했습니다. 정적 예시 3개 대신 실제 corpus에서 기준 문항을 골라 출제하고, 파이프라인에서 무의미하던 "보존해야 하는 능력"(평가 차원, dims) 섹션을 전면 제거합니다. 이를 위해 agent에 읽기 전용 엔드포인트를 신설합니다.
왜
intent-extraction프롬프트가 dims를 참조하지 않고, 성취기준 Strategy YAML이 런타임에 덮어쓰며(43개 토픽 전부 보유), 검증 verdict도 차원을 비교하지 않습니다 → 사용자가 고르는 의미가 없었음.변경 (3 commits)
GET /api/source-problems(school/grade/topic/difficulty/limit). 기존 RagClient 재사용, CORS 기존 설정 그대로. figure 의존 문항 제외 + topic 전체를 훑어limit채움.lib/source-problems-client.ts(SSR+client fetch),lib/verification-storage-key.ts(검증 결과 sessionStorage 키 단일화 — 기존 3중 중복 제거).기준 문항 표시 품질
LatexMixed로$…$를 렌더(원시 텍스트 노출 X).그림,다음/아래/위 그래프,그래프와 같이,다음/아래 도형,다음/아래/위의 표는·를,<table>. 맨그래프·도형·표·좌표(자기완결)는 유지 — 휴리스틱, 정밀도 우선.검증
pnpm test178 green (Node 158 + Python 20), typecheck 0(양 패키지). pre-commit/pre-push 훅 통과.difficulty=hard정상 narrowing, 미존재 토픽 →[],school_level누락 → 400.srcRef+sessionStorage 핸드오프 → 6단계 SSE 진행. 콘솔 에러 0.참고 / 범위 밖
Summary by cubic
Replaced the S3 intent step with a corpus-backed problem picker and removed “dimensions” across the flow. Added LaTeX bracket/paren delimiter support and updated picker cards to show a short preview (3 lines) and expand to full text only when selected.
New Features
GET /api/source-problems(school_level/grade/topic_code/difficulty/limit). ReusesRagClient, filters figure-dependent items via explicit-reference regex, no LLM, existing CORS preserved.getSourceProblemsfetcher for SSR and difficulty refetch; intent picker with single-select cards, KaTeX (supports$...$,$$...$$,\[...\],\(...\)), difficulty chips (cached, race-safe), and a responsive grid with uniform previews that expand on selection. Selected source stored tosessionStorageand passed assrcRef. Unified verification result key viaverification-storage-key; SSE now sendssource_item_idand writes results under the new key. Added tests for the agent route, latex renderer, and storage key.Migration
srcRef={item_id}instead ofdimsandsource.sessionStoragekey; old cached entries are ignored.Written for commit 9e096e2. Summary will update on new commits.