@@ -165,41 +165,6 @@ async def set_coding_task(
165165 if workflow_guidance .risk_assessment_required is not None :
166166 task_metadata .risk_assessment_required = workflow_guidance .risk_assessment_required
167167
168- # Use LLM-based research requirements analysis for precise URL count determination
169- if task_metadata .research_required is True :
170- try :
171- logger .info (f"🔍 Analyzing research requirements for task: { task_metadata .title } " )
172- research_analysis = await analyze_research_requirements (
173- task_metadata = task_metadata ,
174- user_requirements = user_requirements or "" ,
175- ctx = ctx
176- )
177-
178- # Update task metadata with detailed LLM analysis
179- update_task_metadata_with_analysis (task_metadata , research_analysis )
180-
181- logger .info (
182- f"✅ Research analysis complete: Expected URLs={ task_metadata .expected_url_count } , "
183- f"Minimum URLs={ task_metadata .minimum_url_count } "
184- )
185-
186- except Exception as e :
187- logger .error (f"❌ Failed to analyze research requirements: { e } " )
188- # Fallback to basic scope-based URL counts
189- scope_to_urls = {
190- ResearchScope .NONE : (0 , 0 ),
191- ResearchScope .LIGHT : (2 , 1 ),
192- ResearchScope .DEEP : (4 , 2 ),
193- }
194- expected , minimum = scope_to_urls .get (task_metadata .research_scope , (0 , 0 ))
195- task_metadata .expected_url_count = expected
196- task_metadata .minimum_url_count = minimum
197- task_metadata .url_requirement_reasoning = (
198- task_metadata .research_rationale or
199- f"Fallback expectations based on research scope '{ task_metadata .research_scope .value } ' "
200- f"(LLM analysis failed: { e } )"
201- )
202-
203168 # Update timestamp to reflect changes
204169 task_metadata .updated_at = int (time .time ())
205170
@@ -272,15 +237,12 @@ async def raise_obstacle(
272237 problem : str ,
273238 research : str ,
274239 options : list [str ],
240+ task_id : str , # REQUIRED: Task ID for context and memory
275241 ctx : Context ,
276- task_id : str | None = None , # OPTIONAL for tests when no task context
277- ) -> str :
242+ ) -> ObstacleResult :
278243 """Obstacle handling tool - description loaded from tool_description_provider."""
279244 # Log tool execution start
280- log_tool_execution ("raise_obstacle" , task_id or "test_task" )
281-
282- # Ensure we have a session id for logging/saving
283- task_id = task_id or "test_task"
245+ log_tool_execution ("raise_obstacle" , task_id )
284246
285247 # Store original input for saving later
286248 original_input = {
@@ -374,17 +336,24 @@ async def raise_obstacle(
374336 guidance = "Call set_coding_task to update the task with any new requirements or clarifications from the obstacle resolution. Then continue with the workflow."
375337 )
376338
339+ # Create enhanced response
340+ result = ObstacleResult (
341+ obstacle_acknowledged = True ,
342+ resolution_guidance = f"✅ OBSTACLE RESOLVED: { response_text } " ,
343+ alternative_approaches = options ,
344+ current_task_metadata = task_metadata ,
345+ workflow_guidance = workflow_guidance ,
346+ )
347+
377348 # Save successful interaction as conversation record
378349 await conversation_service .save_tool_interaction (
379350 session_id = task_id , # Use task_id as primary key
380351 tool_name = "raise_obstacle" ,
381352 tool_input = json .dumps (original_input ),
382- tool_output = json .dumps ({
383- "obstacle_acknowledged" : True ,
384- "resolution_guidance" : f"✅ OBSTACLE RESOLVED: { response_text } " ,
385- }),
353+ tool_output = json .dumps (result .model_dump (mode = 'json' )),
386354 )
387- return f"✅ OBSTACLE RESOLVED: { response_text } "
355+
356+ return result
388357
389358 else :
390359 # Elicitation failed or not available - return the fallback message
@@ -395,17 +364,23 @@ async def raise_obstacle(
395364 guidance = f"Obstacle not resolved: { elicit_result .message } . Manual intervention required."
396365 )
397366
367+ result = ObstacleResult (
368+ obstacle_acknowledged = False ,
369+ resolution_guidance = elicit_result .message ,
370+ alternative_approaches = options ,
371+ current_task_metadata = task_metadata ,
372+ workflow_guidance = workflow_guidance ,
373+ )
374+
398375 # Save failed interaction
399376 await conversation_service .save_tool_interaction (
400377 session_id = task_id , # Use task_id as primary key
401378 tool_name = "raise_obstacle" ,
402379 tool_input = json .dumps (original_input ),
403- tool_output = json .dumps ({
404- "obstacle_acknowledged" : False ,
405- "resolution_guidance" : elicit_result .message ,
406- }),
380+ tool_output = json .dumps (result .model_dump (mode = 'json' )),
407381 )
408- return elicit_result .message
382+
383+ return result
409384
410385 except Exception as e :
411386 # Create error response
@@ -416,18 +391,24 @@ async def raise_obstacle(
416391 guidance = f"Error handling obstacle: { e !s} . Manual intervention required."
417392 )
418393
394+ error_result = ObstacleResult (
395+ obstacle_acknowledged = False ,
396+ resolution_guidance = f"❌ ERROR: Failed to elicit user decision. Error: { e !s} . Cannot resolve obstacle without user input." ,
397+ alternative_approaches = options ,
398+ current_task_metadata = task_metadata ,
399+ workflow_guidance = error_guidance ,
400+ )
401+
419402 # Save error interaction
420403 with contextlib .suppress (builtins .BaseException ):
421404 await conversation_service .save_tool_interaction (
422405 session_id = task_id , # Use task_id as primary key
423406 tool_name = "raise_obstacle" ,
424407 tool_input = json .dumps (original_input ),
425- tool_output = json .dumps ({
426- "obstacle_acknowledged" : False ,
427- "resolution_guidance" : f"❌ ERROR: Failed to elicit user decision. Error: { e !s} . Cannot resolve obstacle without user input." ,
428- }),
408+ tool_output = json .dumps (error_result .model_dump (mode = 'json' )),
429409 )
430- return f"❌ ERROR: Failed to elicit user decision. Error: { e !s} . Cannot resolve obstacle without user input."
410+
411+ return error_result
431412
432413
433414@mcp .tool (
@@ -437,15 +418,14 @@ async def raise_missing_requirements(
437418 current_request : str ,
438419 identified_gaps : list [str ],
439420 specific_questions : list [str ],
421+ task_id : str , # REQUIRED: Task ID for context and memory
440422 ctx : Context ,
441- task_id : str | None = None , # OPTIONAL for tests when no task context
442- ) -> str :
423+ ) -> MissingRequirementsResult :
443424 """Requirements clarification tool - description loaded from tool_description_provider."""
444425 # Log tool execution start
445- log_tool_execution ("raise_missing_requirements" , task_id or "test_task" )
426+ log_tool_execution ("raise_missing_requirements" , task_id )
446427
447428 # Store original input for saving later
448- task_id = task_id or "test_task"
449429 original_input = {
450430 "current_request" : current_request ,
451431 "identified_gaps" : identified_gaps ,
@@ -1424,7 +1404,7 @@ async def judge_code_change(
14241404
14251405 # STEP 4: Save tool interaction to conversation history
14261406 await conversation_service .save_tool_interaction (
1427- session_id = task_id or "test_task" , # Use task_id as primary key
1407+ session_id = task_id , # Use task_id as primary key
14281408 tool_name = "judge_code_change" ,
14291409 tool_input = json .dumps (original_input ),
14301410 tool_output = json .dumps (result .model_dump (mode = 'json' )),
0 commit comments