Add "Start Workflow" button to trigger CEO agent from web UI
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
All checks were successful
Build & Deploy / build-and-deploy (push) Successful in 49s
New endpoint POST /api/cases/{case_number}/start-workflow creates a
Paperclip issue, wakes the CEO agent via wakeup API, and transitions
case status to "processing". Button appears on case page only when
status is "new" or "documents_ready".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@ import os
|
||||
import uuid
|
||||
|
||||
import asyncpg
|
||||
import httpx
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -20,6 +21,9 @@ PAPERCLIP_DB_URL = os.environ.get(
|
||||
)
|
||||
|
||||
PLUGIN_ID = "53461b5a-7f58-411a-9952-72f9c8d4a328" # marcusgroup.legal-ai
|
||||
CEO_AGENT_ID = "752cebdd-6748-4a04-aacd-c7ab0294ef33"
|
||||
PAPERCLIP_API_URL = os.environ.get("PAPERCLIP_API_URL", "http://localhost:3100")
|
||||
PAPERCLIP_BOARD_API_KEY = os.environ.get("PAPERCLIP_BOARD_API_KEY", "")
|
||||
|
||||
# Company IDs from Paperclip DB
|
||||
COMPANIES = {
|
||||
@@ -251,3 +255,80 @@ async def get_project_url(case_number: str) -> str | None:
|
||||
return None
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
|
||||
async def create_workflow_issue(case_number: str, title: str) -> dict:
|
||||
"""Create a workflow issue in the existing Paperclip project for a case.
|
||||
|
||||
Returns dict with issue_id, identifier, project_url.
|
||||
Raises ValueError if no project found.
|
||||
"""
|
||||
conn = await asyncpg.connect(PAPERCLIP_DB_URL)
|
||||
try:
|
||||
# Find existing project
|
||||
row = await conn.fetchrow(
|
||||
"SELECT id, company_id FROM projects WHERE name LIKE $1",
|
||||
f"%{case_number}%",
|
||||
)
|
||||
if not row:
|
||||
raise ValueError(f"No Paperclip project found for case {case_number}")
|
||||
|
||||
project_id = str(row["id"])
|
||||
company_id = str(row["company_id"])
|
||||
|
||||
# Get company prefix
|
||||
comp_row = await conn.fetchrow(
|
||||
"SELECT issue_prefix FROM companies WHERE id = $1::uuid", company_id,
|
||||
)
|
||||
prefix = comp_row["issue_prefix"] if comp_row and comp_row["issue_prefix"] else "CMP"
|
||||
|
||||
# Create the workflow issue
|
||||
issue_id, identifier = await _create_issue(
|
||||
conn, company_id, project_id, case_number,
|
||||
f"התחל תהליך ניסוח — {title}"[:200], prefix,
|
||||
)
|
||||
|
||||
# Link to legal-ai case via plugin state
|
||||
await _link_case_to_issue(conn, issue_id, case_number)
|
||||
|
||||
project_url = f"https://pc.nautilus.marcusgroup.org/{prefix}/projects/{project_id}/issues"
|
||||
logger.info("Created workflow issue %s for case %s", identifier, case_number)
|
||||
|
||||
return {
|
||||
"issue_id": issue_id,
|
||||
"identifier": identifier,
|
||||
"project_url": project_url,
|
||||
}
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
|
||||
async def wake_ceo_agent(issue_id: str, case_number: str) -> dict:
|
||||
"""Wake the CEO agent via Paperclip's wakeup API.
|
||||
|
||||
MUST use API, never direct DB insert (agent won't wake from DB insert).
|
||||
"""
|
||||
if not PAPERCLIP_BOARD_API_KEY:
|
||||
raise RuntimeError("PAPERCLIP_BOARD_API_KEY not set — cannot wake CEO agent")
|
||||
|
||||
url = f"{PAPERCLIP_API_URL}/api/agents/{CEO_AGENT_ID}/wakeup"
|
||||
payload = {
|
||||
"source": "web-ui",
|
||||
"triggerDetail": "user",
|
||||
"reason": f"start_workflow_{case_number}",
|
||||
"payload": {
|
||||
"issueId": issue_id,
|
||||
"mutation": "workflow_start",
|
||||
},
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
resp = await client.post(
|
||||
url,
|
||||
json=payload,
|
||||
headers={"Authorization": f"Bearer {PAPERCLIP_BOARD_API_KEY}"},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
result = resp.json()
|
||||
logger.info("CEO agent wakeup for case %s: %s", case_number, result)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user