mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-12 06:50:48 +08:00
feat(chat): image specialist legacy lane, Responses fixes, ACL + UI attachments
- Image expert: DashScope-style /chat/completions via image_legacy_client; early exit in direct_loop when skill_binding_role is image; shared placeholder helper; docs/IMAGE_SPECIALIST_LANE.md. - Strict attachment ACL: link_attachment_acl on assistant chat_message rows (sqlite_store); chat attachment rate limit when user_id empty; admin chat tests updated. - Admin chat UI: aggregate bubbles render assistant_text attachments (image_ref); WS expand path. - turn_runner: persisted_chat_attachments_nonempty for final_msg selection. - OpenAI Responses transport + agent_messages/agent_core_attempt adjustments; env docs and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
d1bcc4debe
commit
faeb067856
21 changed files with 2516 additions and 331 deletions
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import threading
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
|
@ -13,6 +14,28 @@ from oclaw.platform.config.paths import db_path
|
|||
from oclaw.platform.persistence.sqlite_store import SqliteStore
|
||||
|
||||
|
||||
def _persisted_chat_attachments_nonempty(raw: Any) -> bool:
|
||||
"""True when chat_message.attachments has at least one JSON object (list or dict or encoded string)."""
|
||||
if raw is None:
|
||||
return False
|
||||
if isinstance(raw, list):
|
||||
return len(raw) > 0
|
||||
if isinstance(raw, dict):
|
||||
return bool(raw)
|
||||
s = str(raw).strip()
|
||||
if not s or s.lower() == "null":
|
||||
return False
|
||||
try:
|
||||
parsed = json.loads(s)
|
||||
if isinstance(parsed, list):
|
||||
return len(parsed) > 0
|
||||
if isinstance(parsed, dict):
|
||||
return bool(parsed)
|
||||
except Exception:
|
||||
return bool(s)
|
||||
return False
|
||||
|
||||
|
||||
async def run_agent_turn_via_bridge(
|
||||
*,
|
||||
conn: Any,
|
||||
|
|
@ -533,12 +556,13 @@ async def run_agent_turn_via_bridge(
|
|||
pass
|
||||
elif run_status != "failed":
|
||||
try:
|
||||
persisted = store.get_messages(session_id=session_id, limit=12)
|
||||
persisted = store.get_messages(session_id=session_id, limit=64)
|
||||
for m in reversed(list(persisted or [])):
|
||||
if str(getattr(m, "role", "") or "").lower() != "assistant":
|
||||
continue
|
||||
content = str(getattr(m, "content", "") or "")
|
||||
if not content.strip():
|
||||
atraw = getattr(m, "attachments", None)
|
||||
if not content.strip() and not _persisted_chat_attachments_nonempty(atraw):
|
||||
continue
|
||||
final_text = content
|
||||
final_msg = {
|
||||
|
|
@ -547,7 +571,7 @@ async def run_agent_turn_via_bridge(
|
|||
"content": content,
|
||||
"timestamp": str(getattr(m, "timestamp", "") or ""),
|
||||
"tool_calls": getattr(m, "tool_calls", None),
|
||||
"attachments": getattr(m, "attachments", None),
|
||||
"attachments": atraw,
|
||||
}
|
||||
break
|
||||
except Exception:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue