[codex] fix bridge state db sync (#740)
* fix bridge session db flush cursor * fix bridge state db result sync
This commit is contained in:
@@ -688,6 +688,8 @@ class AgentPool:
|
|||||||
if db is None:
|
if db is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
history_len = len(conversation_history) if conversation_history else 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(db, "create_session"):
|
if hasattr(db, "create_session"):
|
||||||
db.create_session(
|
db.create_session(
|
||||||
@@ -701,6 +703,7 @@ class AgentPool:
|
|||||||
if messages:
|
if messages:
|
||||||
last = messages[-1]
|
last = messages[-1]
|
||||||
if last.get("role") == "user" and last.get("content") == user_content:
|
if last.get("role") == "user" and last.get("content") == user_content:
|
||||||
|
self._align_prepersist_flush_cursor(session, history_len)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
db.append_message(
|
db.append_message(
|
||||||
@@ -710,21 +713,86 @@ class AgentPool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# AIAgent will build messages as conversation_history + current user.
|
# AIAgent will build messages as conversation_history + current user.
|
||||||
# Since the current user was pre-persisted above, advance its flush
|
# Since the current user was pre-persisted above, align the flush
|
||||||
# cursor so the normal end-of-turn flush only writes assistant/tool
|
# cursor so the normal end-of-turn flush starts at assistant/tool
|
||||||
# messages for this turn.
|
# messages generated by this run.
|
||||||
history_len = len(conversation_history) if conversation_history else 0
|
self._align_prepersist_flush_cursor(session, history_len)
|
||||||
try:
|
|
||||||
session.agent._last_flushed_db_idx = max(
|
|
||||||
int(getattr(session.agent, "_last_flushed_db_idx", 0) or 0),
|
|
||||||
history_len + 1,
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _align_prepersist_flush_cursor(self, session: AgentSession, history_len: int) -> None:
|
||||||
|
try:
|
||||||
|
session.agent._last_flushed_db_idx = history_len + 1
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _session_db_message_count(self, session_id: str, profile: str | None) -> int | None:
|
||||||
|
db = self._db.get_for_profile(profile)
|
||||||
|
if db is None or not hasattr(db, "get_messages"):
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return len(db.get_messages(session_id) or [])
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _sync_result_tail_to_session_db(
|
||||||
|
self,
|
||||||
|
session: AgentSession,
|
||||||
|
result: dict[str, Any],
|
||||||
|
conversation_history: list[dict[str, Any]] | None,
|
||||||
|
profile: str | None,
|
||||||
|
db_count_after_prepersist: int | None,
|
||||||
|
) -> None:
|
||||||
|
db = self._db.get_for_profile(profile)
|
||||||
|
if db is None or db_count_after_prepersist is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
after_count = self._session_db_message_count(session.session_id, profile)
|
||||||
|
if after_count is None or after_count > db_count_after_prepersist:
|
||||||
|
return
|
||||||
|
|
||||||
|
messages = result.get("messages")
|
||||||
|
if not isinstance(messages, list):
|
||||||
|
return
|
||||||
|
|
||||||
|
history_len = len(conversation_history) if conversation_history else 0
|
||||||
|
generated = [
|
||||||
|
msg for msg in messages[history_len + 1:]
|
||||||
|
if isinstance(msg, dict) and msg.get("role") in {"assistant", "tool"}
|
||||||
|
]
|
||||||
|
if not generated:
|
||||||
|
return
|
||||||
|
|
||||||
|
appended = 0
|
||||||
|
for msg in generated:
|
||||||
|
try:
|
||||||
|
db.append_message(
|
||||||
|
session_id=session.session_id,
|
||||||
|
role=str(msg.get("role") or "assistant"),
|
||||||
|
content=msg.get("content"),
|
||||||
|
tool_name=msg.get("tool_name"),
|
||||||
|
tool_calls=msg.get("tool_calls") if isinstance(msg.get("tool_calls"), list) else None,
|
||||||
|
tool_call_id=msg.get("tool_call_id"),
|
||||||
|
finish_reason=msg.get("finish_reason"),
|
||||||
|
reasoning=msg.get("reasoning") if msg.get("role") == "assistant" else None,
|
||||||
|
reasoning_content=msg.get("reasoning_content") if msg.get("role") == "assistant" else None,
|
||||||
|
reasoning_details=msg.get("reasoning_details") if msg.get("role") == "assistant" else None,
|
||||||
|
codex_reasoning_items=msg.get("codex_reasoning_items") if msg.get("role") == "assistant" else None,
|
||||||
|
codex_message_items=msg.get("codex_message_items") if msg.get("role") == "assistant" else None,
|
||||||
|
)
|
||||||
|
appended += 1
|
||||||
|
except Exception:
|
||||||
|
break
|
||||||
|
|
||||||
|
if appended:
|
||||||
|
print(
|
||||||
|
"[hermes_bridge] synced missing result tail to session db "
|
||||||
|
f"session={session.session_id} appended={appended}",
|
||||||
|
file=sys.stderr,
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
def start_chat(
|
def start_chat(
|
||||||
self,
|
self,
|
||||||
session_id: str,
|
session_id: str,
|
||||||
@@ -776,6 +844,7 @@ class AgentPool:
|
|||||||
except Exception:
|
except Exception:
|
||||||
previous_approval_callback = None
|
previous_approval_callback = None
|
||||||
self._prepersist_user_message(session, message, conversation_history, profile)
|
self._prepersist_user_message(session, message, conversation_history, profile)
|
||||||
|
db_count_after_prepersist = self._session_db_message_count(session.session_id, profile)
|
||||||
if force_compress:
|
if force_compress:
|
||||||
compress = getattr(session.agent, "_compress_context", None)
|
compress = getattr(session.agent, "_compress_context", None)
|
||||||
if callable(compress):
|
if callable(compress):
|
||||||
@@ -802,6 +871,13 @@ class AgentPool:
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
result = _jsonable(result if isinstance(result, dict) else {"value": result})
|
result = _jsonable(result if isinstance(result, dict) else {"value": result})
|
||||||
|
self._sync_result_tail_to_session_db(
|
||||||
|
session,
|
||||||
|
result,
|
||||||
|
conversation_history,
|
||||||
|
profile,
|
||||||
|
db_count_after_prepersist,
|
||||||
|
)
|
||||||
with session.lock:
|
with session.lock:
|
||||||
if isinstance(result.get("messages"), list):
|
if isinstance(result.get("messages"), list):
|
||||||
session.history = result["messages"]
|
session.history = result["messages"]
|
||||||
|
|||||||
Reference in New Issue
Block a user