fix: tool registry emits Anthropic schema, question lifecycle cleanup
- Tool.to_schema() emits input_schema (Anthropic Messages API) instead of OpenAI-style parameters - QuestionManager: remove questions from _pending on answer and timeout, reject double answers, add list_pending() - core/skills/__init__.py so skills are importable as a package - revert optional-import fallbacks in logger/message_bus: nats-py and loguru are hard requirements, a broken install should fail loudly - tests for wait_for_answer happy path and timeout cleanup Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012AJLYcbTHCe45fyFnMfEin
This commit is contained in:
@@ -110,24 +110,33 @@ class QuestionManager:
|
||||
raise TimeoutError(f"Question {question.question_id} timed out waiting for human input")
|
||||
finally:
|
||||
self._futures.pop(question.question_id, None)
|
||||
self._pending.pop(question.question_id, None)
|
||||
|
||||
def answer_question(self, question_id: str, answer: Any) -> bool:
|
||||
"""Called when human operator submits an answer from the UI."""
|
||||
"""Called when human operator submits an answer from the UI.
|
||||
|
||||
Returns False if the question is unknown or was already answered."""
|
||||
question = self._pending.get(question_id)
|
||||
if not question:
|
||||
logger.warning(f"No pending question found for id {question_id}")
|
||||
return False
|
||||
if question.answered:
|
||||
logger.warning(f"Question {question_id} already answered; ignoring")
|
||||
return False
|
||||
|
||||
question.answered = True
|
||||
question.answer = answer
|
||||
|
||||
fut = self._futures.get(question_id)
|
||||
if fut and not fut.done():
|
||||
fut.set_result(answer)
|
||||
return True
|
||||
|
||||
fut.set_result(answer) # wait_for_answer() removes it from _pending
|
||||
else:
|
||||
self._pending.pop(question_id, None) # nobody waiting; don't leak
|
||||
return True
|
||||
|
||||
def list_pending(self) -> List[Question]:
|
||||
return [q for q in self._pending.values() if not q.answered]
|
||||
|
||||
def get_pending(self, question_id: str) -> Optional[Question]:
|
||||
return self._pending.get(question_id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user