1 | import createClient, { type Middleware } from "openapi-fetch"; |
2 |
|
3 | type Nextcloud = { |
4 | baseUrl: string, |
5 | userId: string, |
6 | token: string |
7 | }; |
8 |
|
9 | const TASK_TYPE_SUMMARY = "core:text2text:summary"; |
10 | const POLL_INTERVAL_MS = 1000; |
11 | const DEFAULT_POLL_TIMEOUT_MS = 600_000; |
12 |
|
13 | |
14 | * Creates a summarization task via the Nextcloud OCS Task Processing API, |
15 | * polls until the task completes, and returns the summarized text. |
16 | */ |
17 | export async function main( |
18 | ncResource: Nextcloud, |
19 | text: string, |
20 | model: string | null = null, |
21 | timeout_ms: number = DEFAULT_POLL_TIMEOUT_MS, |
22 | interval_ms: number = POLL_INTERVAL_MS, |
23 | ) { |
24 | if (timeout_ms < 1) { |
25 | timeout_ms = DEFAULT_POLL_TIMEOUT_MS; |
26 | } |
27 | if (interval_ms < 1) { |
28 | interval_ms = POLL_INTERVAL_MS; |
29 | } |
30 | const client = createClient({ baseUrl: ncResource.baseUrl }) as any; |
31 | const authMiddleware: Middleware = { |
32 | async onRequest({ request, options }) { |
33 | request.headers.set("Authorization", `Basic ${btoa(ncResource.userId + ':' + ncResource.token)}`); |
34 | return request; |
35 | }, |
36 | }; |
37 | client.use(authMiddleware); |
38 |
|
39 | const input: Record<string, string> = { |
40 | input: text, |
41 | }; |
42 |
|
43 | if (model !== null && model !== "") { |
44 | input.model = model |
45 | } |
46 | console.log(input) |
47 |
|
48 | |
49 | const { data: scheduleData, error: scheduleError } = await client.POST( |
50 | "/ocs/v2.php/taskprocessing/schedule", |
51 | { |
52 | params: { |
53 | header: { |
54 | "OCS-APIRequest": true, |
55 | }, |
56 | query: { |
57 | format: "json", |
58 | }, |
59 | }, |
60 | body: { |
61 | type: TASK_TYPE_SUMMARY, |
62 | input, |
63 | appId: "windmill", |
64 | }, |
65 | }, |
66 | ); |
67 |
|
68 | if (scheduleError) { |
69 | throw new Error(`Failed to schedule summarization task: ${JSON.stringify(scheduleError)}`); |
70 | } |
71 | const taskId = scheduleData?.ocs?.data?.task?.id; |
72 |
|
73 | |
74 | const deadline = Date.now() + timeout_ms; |
75 | while (Date.now() < deadline) { |
76 | console.log("Polling task output") |
77 | const { data: taskData, error: taskError } = await client.GET( |
78 | "/ocs/v2.php/taskprocessing/task/{id}", |
79 | { |
80 | params: { |
81 | header: { |
82 | "OCS-APIRequest": true, |
83 | }, |
84 | query: { |
85 | format: "json", |
86 | }, |
87 | path: { |
88 | id: taskId, |
89 | }, |
90 | }, |
91 | }, |
92 | ); |
93 |
|
94 | if (taskError) { |
95 | throw new Error(`Failed to get task ${taskId}: ${JSON.stringify(taskError)}`); |
96 | } |
97 | const task = taskData.ocs?.data?.task; |
98 | const status = task.status; |
99 |
|
100 | if (status === "STATUS_SUCCESSFUL") { |
101 | const output = task.output; |
102 | if (output && typeof output.output === "string") { |
103 | return { summarizedText: output.output, taskId }; |
104 | } |
105 | return { summarizedText: output, taskId }; |
106 | } |
107 |
|
108 | if (status === "STATUS_FAILED" || status === "STATUS_CANCELLED") { |
109 | const msg = JSON.stringify(task); |
110 | throw new Error(`Summarization task failed: ${msg}`); |
111 | } |
112 | if (!["STATUS_SCHEDULED", "STATUS_RUNNING"].includes(status)) { |
113 | const msg = JSON.stringify(task); |
114 | throw new Error(`Summarization task failed with unknown status: ${msg}`) |
115 | } |
116 | await new Promise((r) => setTimeout(r, interval_ms)); |
117 | } |
118 |
|
119 | throw new Error( |
120 | `Summarization task did not complete within ${timeout_ms}ms (taskId: ${taskId})`, |
121 | ); |
122 | } |
123 |
|