Add structured response feedback

This commit is contained in:
2026-05-10 23:57:50 +08:00
parent 2ba18e0b35
commit 77c2e37b95
4 changed files with 367 additions and 35 deletions
+115 -24
View File
@@ -394,13 +394,16 @@ class RuntimeController:
feedback: str,
task_id: str | None = None,
session_id: str | None = None,
feedback_type: str | None = None,
severity: str | None = None,
correction: str | None = None,
remember: bool = True,
retry: bool = False,
assistant_answer: str | None = None,
correctness_override: float | None = None,
usefulness_override: float | None = None,
safety_override: float | None = None,
) -> dict[str, object]:
if not self._memory_interface:
return {"status": "error", "message": "Memory not available"}
target_task_id = task_id
target_session_id = session_id
@@ -410,10 +413,9 @@ class RuntimeController:
"message": "Either task_id or session_id must be provided",
}
if not target_session_id and target_task_id:
state = self.task_state_store.get_task(target_task_id)
if state:
target_session_id = state.get("session_id")
state = self.task_state_store.get_task(target_task_id) if target_task_id else None
if not target_session_id and state:
target_session_id = state.get("session_id")
if not target_task_id and target_session_id:
recent_tasks = self.task_state_store.get_session_tasks(target_session_id, limit=1)
@@ -426,8 +428,27 @@ class RuntimeController:
final_weight = max(min_weight, min(max_weight, user_weight))
task_input = state.get("task_input") if state else None
last_directive = state.get("last_directive") if state else None
feedback_type = feedback_type or "other"
severity = severity or "major"
lesson = self._build_feedback_lesson(
feedback_type=feedback_type,
severity=severity,
feedback=feedback,
correction=correction,
task_input=task_input,
)
metadata = {
"feedback_text": feedback,
"feedback_type": feedback_type,
"severity": severity,
"correction": correction,
"assistant_answer": assistant_answer,
"task_input": task_input,
"last_directive": last_directive,
"overrides": {
"correctness": correctness_override,
"usefulness": usefulness_override,
@@ -436,7 +457,7 @@ class RuntimeController:
"source": "user",
}
feedback_text = f"User feedback: {feedback}"
feedback_text = lesson
if correctness_override is not None:
feedback_text += f" | Correctness corrected to: {correctness_override}"
if usefulness_override is not None:
@@ -444,21 +465,91 @@ class RuntimeController:
if safety_override is not None:
feedback_text += f" | Safety corrected to: {safety_override}"
retry_result = None
stored = False
store_error = None
try:
self._memory_interface.insert(
text=feedback_text,
kind="critique",
source="user",
task_id=target_task_id,
session_id=target_session_id,
weight=final_weight,
metadata=metadata,
)
return {
"status": "ok",
"message": "Feedback saved",
"task_id": target_task_id,
"session_id": target_session_id,
}
if remember and self._memory_interface:
self._memory_interface.insert(
text=feedback_text,
kind="critique",
source="user",
task_id=target_task_id,
session_id=target_session_id,
weight=final_weight,
metadata=metadata,
)
stored = True
elif remember and not self._memory_interface:
store_error = "Memory not available"
except Exception as e:
return {"status": "error", "message": str(e)}
store_error = str(e)
if retry and task_input:
retry_input = self._build_retry_input(
task_input=task_input,
feedback=feedback,
feedback_type=feedback_type,
correction=correction,
)
retry_task = UserTask(
session_id=target_session_id or "feedback-retry",
input=retry_input,
context={
"feedback_retry": True,
"original_task_id": target_task_id,
"feedback_type": feedback_type,
"severity": severity,
"correction": correction,
},
)
retry_result = self.handle_task(retry_task)
status = "ok" if stored or not remember else "error"
return {
"status": status,
"message": "Feedback saved" if stored else (store_error or "Feedback accepted"),
"stored": stored,
"task_id": target_task_id,
"session_id": target_session_id,
"lesson": lesson,
"retry_result": retry_result,
}
def _build_feedback_lesson(
self,
feedback_type: str,
severity: str,
feedback: str,
correction: str | None,
task_input: str | None,
) -> str:
parts = [
"User critique lesson.",
f"Error type: {feedback_type}.",
f"Severity: {severity}.",
]
if task_input:
parts.append(f"Original task: {task_input}")
if feedback:
parts.append(f"What was wrong: {feedback}")
if correction:
parts.append(f"Preferred correction: {correction}")
return " | ".join(parts)
def _build_retry_input(
self,
task_input: str,
feedback: str,
feedback_type: str,
correction: str | None,
) -> str:
retry_input = (
f"Повтори задачу с учетом обратной связи.\n"
f"Исходная задача: {task_input}\n"
f"Тип ошибки: {feedback_type}\n"
f"Что было неверно: {feedback}\n"
)
if correction:
retry_input += f"Как должно быть: {correction}\n"
return retry_input