Anchor generated attachments to assistant messages
Deliverables now inherit the active assistant draft message ID so clients can render them beside the reply that produced them.
This commit is contained in:
+1
-1
@@ -309,7 +309,7 @@ adapter-managed storage and broadcasts:
|
||||
"kind": "image" | "voice" | "video" | "audio" | "document",
|
||||
"inline_image": false,
|
||||
"conversation_id": "a1b2…",
|
||||
"message_id": null,
|
||||
"message_id": "draft-8c1f…" | null,
|
||||
"created_at": "2026-09-02T18:30:00+00:00",
|
||||
"expires_at": "2026-09-09T18:30:00+00:00", // null when retention=0
|
||||
"download_path": "/attachments/e5f6…" },
|
||||
|
||||
@@ -379,11 +379,18 @@ class PhebyAdapter(BasePlatformAdapter):
|
||||
return SendResult(success=True, message_id=clarify_id)
|
||||
|
||||
# ── deliverables (attachments) ───────────────────────────────────────
|
||||
def _active_assistant_message_id(self, conversation_id: str) -> Optional[str]:
|
||||
"""Return the live assistant draft that a deliverable belongs beneath."""
|
||||
draft = self._drafts.get(conversation_id)
|
||||
message_id = draft.get("message_id") if isinstance(draft, dict) else None
|
||||
return str(message_id) if message_id else None
|
||||
|
||||
async def _register_and_broadcast(
|
||||
self,
|
||||
file_path: str,
|
||||
conversation_id: str,
|
||||
*,
|
||||
message_id: Optional[str] = None,
|
||||
kind_hint: Optional[str] = None,
|
||||
filename: Optional[str] = None,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
@@ -392,7 +399,7 @@ class PhebyAdapter(BasePlatformAdapter):
|
||||
desc = await self._server.store.register_file(
|
||||
file_path,
|
||||
conversation_id=conversation_id,
|
||||
message_id=None,
|
||||
message_id=message_id or self._active_assistant_message_id(conversation_id),
|
||||
filename=filename,
|
||||
kind_hint=kind_hint,
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ if str(_PLUGIN_DIR) not in sys.path:
|
||||
|
||||
from pheby import protocol as proto # noqa: E402
|
||||
from pheby.attachments import AttachmentStore, constant_time_equals # noqa: E402
|
||||
from pheby.adapter import PhebyAdapter # noqa: E402
|
||||
from pheby.config import load_config # noqa: E402
|
||||
from pheby.conversations import ConversationRouter # noqa: E402
|
||||
from pheby.server import PhebyServer # noqa: E402
|
||||
@@ -344,6 +345,13 @@ class TestConversations:
|
||||
# Attachments
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
class TestAttachments:
|
||||
def test_adapter_anchors_deliverable_to_active_assistant_draft(self):
|
||||
adapter = object.__new__(PhebyAdapter)
|
||||
adapter._drafts = {"conv": {"message_id": "draft-run-1", "text": ""}}
|
||||
|
||||
assert adapter._active_assistant_message_id("conv") == "draft-run-1"
|
||||
assert adapter._active_assistant_message_id("unknown") is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_register_describe_download_path(self, tmp_path):
|
||||
src = Path(tmp_path) / "report.pdf"
|
||||
|
||||
Reference in New Issue
Block a user