|
5 | 5 | Ok, |
6 | 6 | SdkError, |
7 | 7 | _entry_exception_error, |
8 | | - _normalize_submitted_image_payload, |
| 8 | + _validate_optional_vision_image_payload, |
9 | 9 | plugin_entry, |
10 | 10 | tr, |
11 | 11 | LLM_OPERATION_QUESTION_GENERATE, |
@@ -62,56 +62,60 @@ async def study_generate_question( |
62 | 62 | code="MISSING_TEXT", |
63 | 63 | ) |
64 | 64 | ) |
65 | | - if vision_image_payload: |
66 | | - if not bool(self._cfg.llm_vision_enabled): |
67 | | - return Err(SdkError("llm_vision_enabled is not enabled")) |
68 | | - try: |
69 | | - vision_image_payload = _normalize_submitted_image_payload( |
70 | | - vision_image_payload |
71 | | - ) |
72 | | - except ValueError as exc: |
73 | | - return _entry_exception_error( |
74 | | - self, exc, operation="study_generate_question" |
75 | | - ) |
76 | | - async with self._lock: |
77 | | - active_mode = self._state.active_mode |
78 | | - tutor_context = await self._build_learning_context( |
79 | | - LLM_OPERATION_QUESTION_GENERATE, |
80 | | - input_text=source_text, |
81 | | - extra={ |
82 | | - "source": "ocr_snapshot" |
83 | | - if used_ocr_fallback |
84 | | - else ("vision_image" if vision_image_payload and not source_text else "manual"), |
85 | | - "source_text": source_text, |
86 | | - "topic_hint": str(topic or "").strip(), |
87 | | - "mode": active_mode, |
88 | | - **( |
89 | | - { |
90 | | - "vision_enabled": True, |
91 | | - "vision_image_base64": vision_image_payload, |
92 | | - } |
93 | | - if vision_image_payload |
94 | | - else {} |
95 | | - ), |
96 | | - }, |
97 | | - ) |
98 | | - reply = await self._agent.question_generate( |
99 | | - source_text, mode=active_mode, context=tutor_context |
100 | | - ) |
101 | | - payload = await self._finalize_tutor_call( |
102 | | - LLM_OPERATION_QUESTION_GENERATE, |
103 | | - reply, |
104 | | - history_kind=LLM_OPERATION_QUESTION_GENERATE, |
105 | | - metadata={ |
106 | | - "degraded": reply.degraded, |
107 | | - "diagnostic": reply.diagnostic, |
108 | | - "payload": reply.payload, |
109 | | - "screen_classification": tutor_context.get("screen_classification") |
110 | | - or {}, |
111 | | - }, |
112 | | - extra_context=tutor_context, |
113 | | - ) |
114 | | - payload["screen_classification"] = ( |
115 | | - tutor_context.get("screen_classification") or {} |
| 65 | + validated_vision_image = _validate_optional_vision_image_payload( |
| 66 | + self, vision_image_payload, operation="study_generate_question" |
116 | 67 | ) |
117 | | - return Ok(payload) |
| 68 | + if isinstance(validated_vision_image, Err): |
| 69 | + return validated_vision_image |
| 70 | + vision_image_payload = validated_vision_image |
| 71 | + try: |
| 72 | + async with self._lock: |
| 73 | + active_mode = self._state.active_mode |
| 74 | + tutor_context = await self._build_learning_context( |
| 75 | + LLM_OPERATION_QUESTION_GENERATE, |
| 76 | + input_text=source_text, |
| 77 | + extra={ |
| 78 | + "source": "ocr_snapshot" |
| 79 | + if used_ocr_fallback |
| 80 | + else ( |
| 81 | + "vision_image" |
| 82 | + if vision_image_payload and not source_text |
| 83 | + else "manual" |
| 84 | + ), |
| 85 | + "source_text": source_text, |
| 86 | + "topic_hint": str(topic or "").strip(), |
| 87 | + "mode": active_mode, |
| 88 | + **( |
| 89 | + { |
| 90 | + "vision_enabled": True, |
| 91 | + "vision_image_base64": vision_image_payload, |
| 92 | + } |
| 93 | + if vision_image_payload |
| 94 | + else {} |
| 95 | + ), |
| 96 | + }, |
| 97 | + ) |
| 98 | + reply = await self._agent.question_generate( |
| 99 | + source_text, mode=active_mode, context=tutor_context |
| 100 | + ) |
| 101 | + payload = await self._finalize_tutor_call( |
| 102 | + LLM_OPERATION_QUESTION_GENERATE, |
| 103 | + reply, |
| 104 | + history_kind=LLM_OPERATION_QUESTION_GENERATE, |
| 105 | + metadata={ |
| 106 | + "degraded": reply.degraded, |
| 107 | + "diagnostic": reply.diagnostic, |
| 108 | + "payload": reply.payload, |
| 109 | + "screen_classification": tutor_context.get("screen_classification") |
| 110 | + or {}, |
| 111 | + }, |
| 112 | + extra_context=tutor_context, |
| 113 | + ) |
| 114 | + payload["screen_classification"] = ( |
| 115 | + tutor_context.get("screen_classification") or {} |
| 116 | + ) |
| 117 | + return Ok(payload) |
| 118 | + except Exception as exc: |
| 119 | + return _entry_exception_error( |
| 120 | + self, exc, operation="study_generate_question" |
| 121 | + ) |
0 commit comments