60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
"""
|
|
title: UltiAI NC Sync
|
|
author: ulti-suite
|
|
version: 0.1.0
|
|
description: Sync completed chats to Nextcloud via ulti-backend.
|
|
"""
|
|
|
|
from typing import Optional
|
|
import os
|
|
import json
|
|
import urllib.request
|
|
|
|
|
|
class Pipeline:
|
|
def __init__(self):
|
|
self.ultid_api = os.environ.get("ULTID_API_URL", "http://ultid:8080/api/v1").rstrip("/")
|
|
self.sync_token = os.environ.get("ULTI_AI_SYNC_TOKEN", "")
|
|
|
|
async def on_shutdown(self):
|
|
pass
|
|
|
|
async def inlet(self, body: dict, user: Optional[dict] = None) -> dict:
|
|
return body
|
|
|
|
async def outlet(self, body: dict, user: Optional[dict] = None) -> dict:
|
|
chat = body.get("chat") or body.get("messages")
|
|
if not chat:
|
|
return body
|
|
chat_id = body.get("chat_id") or body.get("id")
|
|
if not chat_id:
|
|
return body
|
|
record = {
|
|
"id": chat_id,
|
|
"title": body.get("title") or "Conversation",
|
|
"source": "openwebui",
|
|
"openwebui_chat_id": chat_id,
|
|
"messages": body.get("messages") or [],
|
|
"meta": {
|
|
"model": body.get("model"),
|
|
"context": body.get("context") or "standalone",
|
|
},
|
|
}
|
|
try:
|
|
payload = json.dumps(record).encode("utf-8")
|
|
req = urllib.request.Request(
|
|
f"{self.ultid_api}/ai/chats/sync",
|
|
data=payload,
|
|
headers={
|
|
"Content-Type": "application/json",
|
|
"Authorization": f"Bearer {self.sync_token}" if self.sync_token else "",
|
|
},
|
|
method="POST",
|
|
)
|
|
with urllib.request.urlopen(req, timeout=15) as resp:
|
|
if resp.status >= 400:
|
|
print(f"[ulti-nc-sync] sync failed: {resp.status}")
|
|
except Exception as exc:
|
|
print(f"[ulti-nc-sync] sync error: {exc}")
|
|
return body
|