feat(agent-office): issue_approve/reject/regen 콜백 처리
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -226,6 +226,38 @@ class InstaAgent(BaseAgent):
|
||||
return {"ok": False}
|
||||
await self._render_and_push(kid)
|
||||
return {"ok": True}
|
||||
if action in ("issue_approve", "issue_reject"):
|
||||
sid = int(params.get("slate_id") or 0)
|
||||
if not sid:
|
||||
return {"ok": False}
|
||||
decision = "approved" if action == "issue_approve" else "rejected"
|
||||
await service_proxy.insta_decision(sid, decision)
|
||||
if decision == "approved":
|
||||
slate = await service_proxy.insta_get_slate(sid)
|
||||
media = []
|
||||
for a in slate["assets"][:10]:
|
||||
data = await service_proxy.insta_get_asset_bytes(sid, a["page_index"])
|
||||
media.append({"type": "photo", "_bytes": data})
|
||||
cap = f"{slate.get('suggested_caption','')}\n\n{' '.join(slate.get('hashtags', []) or [])}".strip()
|
||||
await _send_media_group(media, caption=cap)
|
||||
await messaging.send_raw(f"✅ 발행 완료 (slate {sid})")
|
||||
else:
|
||||
await messaging.send_raw(f"❌ 반려됨 (slate {sid})")
|
||||
return {"ok": True}
|
||||
if action == "issue_regen":
|
||||
sid = int(params.get("slate_id") or 0)
|
||||
if not sid:
|
||||
return {"ok": False}
|
||||
slate = await service_proxy.insta_get_slate(sid)
|
||||
await service_proxy.insta_decision(sid, "rejected")
|
||||
await self._generate_and_preview({
|
||||
"id": 0,
|
||||
"keyword": slate["keyword"],
|
||||
"category": slate["category"],
|
||||
"final_score": None,
|
||||
"breakdown": {},
|
||||
})
|
||||
return {"ok": True}
|
||||
return {"ok": False}
|
||||
|
||||
async def on_approval(self, task_id: str, approved: bool, feedback: str = "") -> None:
|
||||
|
||||
@@ -47,3 +47,29 @@ async def test_autonomous_issue_previews_eligible(monkeypatch):
|
||||
await agent.on_schedule()
|
||||
assert preview.await_count == 1
|
||||
assert preview.await_args.args[0]["id"] == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_callback_approve_publishes_and_delivers(monkeypatch):
|
||||
agent = InstaAgent()
|
||||
monkeypatch.setattr("app.agents.insta.service_proxy.insta_decision",
|
||||
AsyncMock(return_value={"status": "published"}))
|
||||
monkeypatch.setattr("app.agents.insta.service_proxy.insta_get_slate", AsyncMock(return_value={
|
||||
"assets": [{"page_index": i} for i in range(1, 11)],
|
||||
"suggested_caption": "cap", "hashtags": ["#a"]}))
|
||||
monkeypatch.setattr("app.agents.insta.service_proxy.insta_get_asset_bytes", AsyncMock(return_value=b"png"))
|
||||
monkeypatch.setattr("app.agents.insta._send_media_group", AsyncMock(return_value={"ok": True}))
|
||||
monkeypatch.setattr("app.agents.insta.messaging.send_raw", AsyncMock())
|
||||
res = await agent.on_callback("issue_approve", {"slate_id": 8})
|
||||
assert res["ok"] is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_callback_reject_marks_rejected(monkeypatch):
|
||||
agent = InstaAgent()
|
||||
dec = AsyncMock(return_value={"status": "rejected"})
|
||||
monkeypatch.setattr("app.agents.insta.service_proxy.insta_decision", dec)
|
||||
monkeypatch.setattr("app.agents.insta.messaging.send_raw", AsyncMock())
|
||||
res = await agent.on_callback("issue_reject", {"slate_id": 8})
|
||||
assert res["ok"] is True
|
||||
dec.assert_awaited_once_with(8, "rejected")
|
||||
|
||||
Reference in New Issue
Block a user