@gobing-ai/knowledge-kit 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/board/collect/index.css +447 -0
- package/dist/board/collect/index.js +2505 -453
- package/dist/board/daily-voice/index.css +447 -0
- package/dist/board/daily-voice/index.js +415 -8
- package/dist/board/itc/index.css +447 -0
- package/dist/board/itc/index.js +415 -8
- package/dist/index.js +475 -136
- package/package.json +6 -5
- package/plugins/generations/content-gen/dist/index.js +9 -9
- package/plugins/generations/core-facts-gen/dist/index.js +12 -12
- package/plugins/generations/daily-article-gen/dist/index.js +12 -12
- package/plugins/generations/dailynews-gen/dist/index.js +9 -9
- package/plugins/generations/episode-plan-gen/dist/index.js +12 -12
- package/plugins/generations/gemini-tts/dist/index.js +9 -9
- package/plugins/generations/image-gen/dist/index.js +28 -12
- package/plugins/generations/image-gen/src/compose/card.ts +19 -3
- package/plugins/generations/news-report-gen/dist/index.js +12 -12
- package/plugins/generations/voice-gen/dist/index.js +9 -9
- package/plugins/generations/voxcpm-tts/dist/index.js +9 -9
- package/plugins/ingestions/aihot-ingest/dist/index.js +12 -12
- package/plugins/ingestions/horizon-ingest/dist/index.js +12 -12
- package/plugins/ingestions/karakeep-local/dist/index.js +13 -13
- package/plugins/ingestions/last30days-ingest/dist/index.js +12 -12
- package/plugins/ingestions/web-search/dist/index.js +10 -10
- package/plugins/kk/decisions/kk-podcast.yaml +44 -0
- package/plugins/kk/decisions/kk-safety.yaml +46 -0
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/daily-stages.ts +117 -0
- package/plugins/kk/scripts/kk-workflow-stages.ts +10 -0
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +6 -3
- package/plugins/kk/workflows/kk-daily-safety.yaml +37 -10
- package/plugins/kk/workflows/kk-solo-podcast.yaml +65 -1
- package/plugins/publishings/bilibili-pub/dist/index.js +22 -22
- package/plugins/publishings/bilibili-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/cnblogs-pub/dist/index.js +22 -22
- package/plugins/publishings/cnblogs-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/csdn-pub/dist/index.js +22 -22
- package/plugins/publishings/csdn-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/emdash-pub/dist/index.js +9 -9
- package/plugins/publishings/infoq-pub/dist/index.js +22 -22
- package/plugins/publishings/infoq-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/jike-pub/dist/index.js +22 -22
- package/plugins/publishings/jike-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/juejin-pub/dist/index.js +22 -22
- package/plugins/publishings/juejin-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/medium-pub/dist/index.js +9 -9
- package/plugins/publishings/podcast-pub/dist/index.js +9 -9
- package/plugins/publishings/qiita-pub/dist/index.js +9 -9
- package/plugins/publishings/shipinhao-pub/dist/index.js +22 -22
- package/plugins/publishings/shipinhao-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/sspai-pub/dist/index.js +22 -22
- package/plugins/publishings/sspai-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/substack-pub/dist/index.js +22 -22
- package/plugins/publishings/substack-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/surfdash-pub/dist/index.js +9 -9
- package/plugins/publishings/threads-pub/dist/index.js +9 -9
- package/plugins/publishings/wechatmp-pub/dist/index.js +22 -22
- package/plugins/publishings/wechatmp-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/weibo-pub/dist/index.js +22 -22
- package/plugins/publishings/weibo-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/x-pub/dist/index.js +22 -22
- package/plugins/publishings/x-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/xhs-pub/dist/index.js +22 -22
- package/plugins/publishings/xhs-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/xiaoyuzhou-pub/dist/index.js +22 -22
- package/plugins/publishings/xiaoyuzhou-pub/dist/profile-check.js +22 -22
- package/plugins/publishings/zenn-pub/dist/index.js +9 -9
|
@@ -17,17 +17,35 @@ function storeItemsQueryString(query) {
|
|
|
17
17
|
}
|
|
18
18
|
if (query.selection !== undefined)
|
|
19
19
|
params.set("selection", query.selection);
|
|
20
|
+
if (query.search !== undefined && query.search.trim() !== "") {
|
|
21
|
+
params.set("search", query.search.trim());
|
|
22
|
+
}
|
|
23
|
+
return params.toString();
|
|
24
|
+
}
|
|
25
|
+
function storeSelectionsQueryString(query) {
|
|
26
|
+
const params = new URLSearchParams;
|
|
27
|
+
if (query.page !== undefined)
|
|
28
|
+
params.set("page", String(query.page));
|
|
29
|
+
if (query.topic !== undefined && query.topic !== "")
|
|
30
|
+
params.set("topic", query.topic);
|
|
31
|
+
if (query.status !== undefined)
|
|
32
|
+
params.set("status", query.status);
|
|
33
|
+
if (query.runId !== undefined && query.runId !== "")
|
|
34
|
+
params.set("runId", query.runId);
|
|
35
|
+
if (query.search !== undefined && query.search.trim() !== "") {
|
|
36
|
+
params.set("search", query.search.trim());
|
|
37
|
+
}
|
|
20
38
|
return params.toString();
|
|
21
39
|
}
|
|
22
40
|
var DEFAULT_READER_ORIGIN = "http://127.0.0.1:4340";
|
|
23
|
-
function readerOriginFrom(search) {
|
|
41
|
+
function readerOriginFrom(search, defaultOrigin = DEFAULT_READER_ORIGIN) {
|
|
24
42
|
const override = new URLSearchParams(search).get("kkApi");
|
|
25
43
|
if (override === null)
|
|
26
|
-
return { origin:
|
|
44
|
+
return { origin: defaultOrigin, diagnostic: null };
|
|
27
45
|
if (isLoopbackHttpOrigin(override))
|
|
28
46
|
return { origin: override, diagnostic: null };
|
|
29
47
|
return {
|
|
30
|
-
origin:
|
|
48
|
+
origin: defaultOrigin,
|
|
31
49
|
diagnostic: {
|
|
32
50
|
code: "board.reader.origin-invalid",
|
|
33
51
|
message: "Ignored a non-loopback kkApi origin; using the default reader."
|
|
@@ -52,6 +70,25 @@ function isLoopbackHttpOrigin(origin) {
|
|
|
52
70
|
function origin(base) {
|
|
53
71
|
return base.replace(/\/+$/, "");
|
|
54
72
|
}
|
|
73
|
+
function parseSpurDbRows(pageData) {
|
|
74
|
+
const { columns, rows } = pageData;
|
|
75
|
+
if (!columns || !rows)
|
|
76
|
+
return [];
|
|
77
|
+
return rows.map((rowCells) => {
|
|
78
|
+
const rowObj = {};
|
|
79
|
+
columns.forEach((col, idx) => {
|
|
80
|
+
const cell = rowCells[idx];
|
|
81
|
+
if (!cell || cell.t === "null") {
|
|
82
|
+
rowObj[col] = null;
|
|
83
|
+
} else if (cell.t === "num" || cell.t === "text") {
|
|
84
|
+
rowObj[col] = cell.v;
|
|
85
|
+
} else {
|
|
86
|
+
rowObj[col] = null;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return rowObj;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
55
92
|
function createBoardClient(options) {
|
|
56
93
|
if (!isLoopbackHttpOrigin(options.readerOrigin)) {
|
|
57
94
|
throw new Error(`reader origin must be loopback http, got '${options.readerOrigin}'`);
|
|
@@ -62,6 +99,7 @@ function createBoardClient(options) {
|
|
|
62
99
|
const reader = origin(options.readerOrigin);
|
|
63
100
|
const board = origin(options.boardOrigin);
|
|
64
101
|
const doFetch = options.fetchImpl ?? fetch;
|
|
102
|
+
const isNativeSpur = reader === board;
|
|
65
103
|
async function getJson(url) {
|
|
66
104
|
const response = await doFetch(url, { headers: { accept: "application/json" } });
|
|
67
105
|
if (!response.ok) {
|
|
@@ -69,10 +107,370 @@ function createBoardClient(options) {
|
|
|
69
107
|
}
|
|
70
108
|
return await response.json();
|
|
71
109
|
}
|
|
110
|
+
async function nativeStoreOverview(runIds) {
|
|
111
|
+
try {
|
|
112
|
+
const pageData = await getJson(`${board}/api/project/database/tables/collect_runs/rows?pageSize=100&sort=started_at&dir=desc`);
|
|
113
|
+
const dbRows = parseSpurDbRows(pageData);
|
|
114
|
+
const byId = new Map;
|
|
115
|
+
let maxFinishedAt = 0;
|
|
116
|
+
for (const row of dbRows) {
|
|
117
|
+
let sourceCounts = {};
|
|
118
|
+
try {
|
|
119
|
+
if (row.source_counts_json) {
|
|
120
|
+
const parsed = JSON.parse(row.source_counts_json);
|
|
121
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
122
|
+
sourceCounts = parsed;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch {
|
|
126
|
+
sourceCounts = {};
|
|
127
|
+
}
|
|
128
|
+
if (row.finished_at && typeof row.finished_at === "number" && row.finished_at > maxFinishedAt) {
|
|
129
|
+
maxFinishedAt = row.finished_at;
|
|
130
|
+
}
|
|
131
|
+
byId.set(row.run_id, {
|
|
132
|
+
runId: row.run_id,
|
|
133
|
+
sourceCounts,
|
|
134
|
+
inserted: row.inserted ?? 0,
|
|
135
|
+
updated: row.updated ?? 0,
|
|
136
|
+
labelRows: 0,
|
|
137
|
+
labeledItems: 0,
|
|
138
|
+
labelRowsBySource: {},
|
|
139
|
+
yield: { selected: 0, published: 0, dropped: 0 }
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const rowsMap = {};
|
|
143
|
+
for (const id of runIds) {
|
|
144
|
+
rowsMap[id] = byId.get(id) ?? null;
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
schemaVersion: 1,
|
|
148
|
+
availability: "available",
|
|
149
|
+
lastStoredAt: maxFinishedAt > 0 ? new Date(maxFinishedAt).toISOString() : null,
|
|
150
|
+
rows: rowsMap,
|
|
151
|
+
diagnostics: []
|
|
152
|
+
};
|
|
153
|
+
} catch {
|
|
154
|
+
return {
|
|
155
|
+
schemaVersion: 1,
|
|
156
|
+
availability: "available",
|
|
157
|
+
lastStoredAt: null,
|
|
158
|
+
rows: Object.fromEntries(runIds.map((id) => [id, null])),
|
|
159
|
+
diagnostics: []
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async function nativeStoreRun(runId) {
|
|
164
|
+
try {
|
|
165
|
+
const runRes = await getJson(`${board}/api/project/database/tables/collect_runs/rows?filterColumn=run_id&filter=${encodeURIComponent(runId)}`);
|
|
166
|
+
const runRows = parseSpurDbRows(runRes);
|
|
167
|
+
const rowData = runRows[0];
|
|
168
|
+
let runStoreRow = null;
|
|
169
|
+
if (rowData) {
|
|
170
|
+
let sourceCounts = {};
|
|
171
|
+
try {
|
|
172
|
+
if (rowData.source_counts_json) {
|
|
173
|
+
const parsed = JSON.parse(rowData.source_counts_json);
|
|
174
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
175
|
+
sourceCounts = parsed;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} catch {
|
|
179
|
+
sourceCounts = {};
|
|
180
|
+
}
|
|
181
|
+
runStoreRow = {
|
|
182
|
+
runId: rowData.run_id,
|
|
183
|
+
sourceCounts,
|
|
184
|
+
inserted: rowData.inserted ?? 0,
|
|
185
|
+
updated: rowData.updated ?? 0,
|
|
186
|
+
labelRows: 0,
|
|
187
|
+
labeledItems: 0,
|
|
188
|
+
labelRowsBySource: {},
|
|
189
|
+
yield: { selected: 0, published: 0, dropped: 0 }
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
let labelQuality = [];
|
|
193
|
+
try {
|
|
194
|
+
const labelsRes = await getJson(`${board}/api/project/database/tables/labels/rows?filterColumn=run_id&filter=${encodeURIComponent(runId)}&pageSize=200`);
|
|
195
|
+
const labelRows = parseSpurDbRows(labelsRes);
|
|
196
|
+
const decisionMap = new Map;
|
|
197
|
+
for (const l of labelRows) {
|
|
198
|
+
const dec = l.decision_id || "unknown";
|
|
199
|
+
const val = String(l.value ?? "none");
|
|
200
|
+
const conf = l.confidence || "none";
|
|
201
|
+
let valMap = decisionMap.get(dec);
|
|
202
|
+
if (!valMap) {
|
|
203
|
+
valMap = new Map;
|
|
204
|
+
decisionMap.set(dec, valMap);
|
|
205
|
+
}
|
|
206
|
+
let counts = valMap.get(val);
|
|
207
|
+
if (!counts) {
|
|
208
|
+
counts = { HIGH: 0, MEDIUM: 0, LOW: 0, none: 0 };
|
|
209
|
+
valMap.set(val, counts);
|
|
210
|
+
}
|
|
211
|
+
if (conf === "HIGH" || conf === "MEDIUM" || conf === "LOW") {
|
|
212
|
+
counts[conf] = (counts[conf] ?? 0) + 1;
|
|
213
|
+
} else {
|
|
214
|
+
counts.none = (counts.none ?? 0) + 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
labelQuality = Array.from(decisionMap.entries()).map(([decisionId, valMap]) => ({
|
|
218
|
+
decisionId,
|
|
219
|
+
run: Array.from(valMap.entries()).map(([value, counts]) => ({
|
|
220
|
+
value,
|
|
221
|
+
...counts
|
|
222
|
+
})),
|
|
223
|
+
effective: Array.from(valMap.entries()).map(([value, counts]) => ({
|
|
224
|
+
value,
|
|
225
|
+
count: counts.HIGH + counts.MEDIUM + counts.LOW + counts.none
|
|
226
|
+
}))
|
|
227
|
+
}));
|
|
228
|
+
} catch {
|
|
229
|
+
labelQuality = [];
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
schemaVersion: 1,
|
|
233
|
+
availability: "available",
|
|
234
|
+
runId,
|
|
235
|
+
row: runStoreRow,
|
|
236
|
+
labelQuality,
|
|
237
|
+
diagnostics: []
|
|
238
|
+
};
|
|
239
|
+
} catch {
|
|
240
|
+
return {
|
|
241
|
+
schemaVersion: 1,
|
|
242
|
+
availability: "available",
|
|
243
|
+
runId,
|
|
244
|
+
row: null,
|
|
245
|
+
labelQuality: [],
|
|
246
|
+
diagnostics: []
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async function nativeStoreItems(runId, query = {}) {
|
|
251
|
+
const pageNum = query.page ?? 1;
|
|
252
|
+
const params = new URLSearchParams({
|
|
253
|
+
page: String(pageNum),
|
|
254
|
+
pageSize: "25",
|
|
255
|
+
sort: "first_seen_at",
|
|
256
|
+
dir: "desc"
|
|
257
|
+
});
|
|
258
|
+
if (query.search?.trim()) {
|
|
259
|
+
params.set("filterColumn", "title");
|
|
260
|
+
params.set("filter", query.search.trim());
|
|
261
|
+
} else if (query.source) {
|
|
262
|
+
params.set("filterColumn", "source");
|
|
263
|
+
params.set("filter", query.source);
|
|
264
|
+
} else if (runId?.trim()) {
|
|
265
|
+
params.set("filterColumn", "first_seen_run");
|
|
266
|
+
params.set("filter", runId.trim());
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const pageData = await getJson(`${board}/api/project/database/tables/items/rows?${params.toString()}`);
|
|
270
|
+
const rows = parseSpurDbRows(pageData);
|
|
271
|
+
const itemsWithLabels = await Promise.all(rows.map(async (row) => {
|
|
272
|
+
const labels = {};
|
|
273
|
+
const labelDetails = {};
|
|
274
|
+
try {
|
|
275
|
+
const labRes = await getJson(`${board}/api/project/database/tables/labels/rows?filterColumn=item_id&filter=${encodeURIComponent(row.id)}&pageSize=50`);
|
|
276
|
+
const labRows = parseSpurDbRows(labRes);
|
|
277
|
+
for (const l of labRows) {
|
|
278
|
+
if (l.decision_id) {
|
|
279
|
+
labels[l.decision_id] = String(l.value ?? "");
|
|
280
|
+
labelDetails[l.decision_id] = {
|
|
281
|
+
value: String(l.value ?? ""),
|
|
282
|
+
confidence: l.confidence ?? null,
|
|
283
|
+
maker: l.maker ?? null,
|
|
284
|
+
score: typeof l.score === "number" ? l.score : null
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} catch {}
|
|
289
|
+
const url = row.canonical_url && /^https?:\/\//i.test(row.canonical_url) ? row.canonical_url : null;
|
|
290
|
+
const seen = row.first_seen_run && row.last_seen_run && row.first_seen_run !== row.last_seen_run ? "reseen" : "new";
|
|
291
|
+
return {
|
|
292
|
+
id: row.id,
|
|
293
|
+
title: (row.title || "").slice(0, 300),
|
|
294
|
+
url,
|
|
295
|
+
source: row.source || "unknown",
|
|
296
|
+
storyId: row.story_id ?? null,
|
|
297
|
+
seen,
|
|
298
|
+
labels,
|
|
299
|
+
labelDetails,
|
|
300
|
+
selection: "none",
|
|
301
|
+
domain: row.domain ?? null,
|
|
302
|
+
lang: row.lang ?? null,
|
|
303
|
+
bodyChars: row.body_chars ?? null,
|
|
304
|
+
engagement: row.engagement ?? null,
|
|
305
|
+
firstSeenAt: row.first_seen_at ?? null,
|
|
306
|
+
publishedAt: row.published_at ?? null
|
|
307
|
+
};
|
|
308
|
+
}));
|
|
309
|
+
return {
|
|
310
|
+
schemaVersion: 1,
|
|
311
|
+
availability: "available",
|
|
312
|
+
runId: runId ?? "",
|
|
313
|
+
page: pageNum,
|
|
314
|
+
pageSize: 25,
|
|
315
|
+
total: pageData.total ?? itemsWithLabels.length,
|
|
316
|
+
items: itemsWithLabels,
|
|
317
|
+
sources: ["aihot", "hackernews", "youtube", "reddit", "polymarket", "github", "grounding", "rss"],
|
|
318
|
+
diagnostics: []
|
|
319
|
+
};
|
|
320
|
+
} catch {
|
|
321
|
+
return {
|
|
322
|
+
schemaVersion: 1,
|
|
323
|
+
availability: "available",
|
|
324
|
+
runId: runId ?? "",
|
|
325
|
+
page: pageNum,
|
|
326
|
+
pageSize: 25,
|
|
327
|
+
total: 0,
|
|
328
|
+
items: [],
|
|
329
|
+
sources: [],
|
|
330
|
+
diagnostics: []
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async function nativeStoreSelections(query = {}) {
|
|
335
|
+
const pageNum = query.page ?? 1;
|
|
336
|
+
const params = new URLSearchParams({
|
|
337
|
+
page: String(pageNum),
|
|
338
|
+
pageSize: "25",
|
|
339
|
+
sort: "selected_at",
|
|
340
|
+
dir: "desc"
|
|
341
|
+
});
|
|
342
|
+
if (query.topic) {
|
|
343
|
+
params.set("filterColumn", "topic");
|
|
344
|
+
params.set("filter", query.topic);
|
|
345
|
+
} else if (query.status) {
|
|
346
|
+
params.set("filterColumn", "status");
|
|
347
|
+
params.set("filter", query.status);
|
|
348
|
+
} else if (query.runId) {
|
|
349
|
+
params.set("filterColumn", "run_id");
|
|
350
|
+
params.set("filter", query.runId);
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
const pageData = await getJson(`${board}/api/project/database/tables/selections/rows?${params.toString()}`);
|
|
354
|
+
const rows = parseSpurDbRows(pageData);
|
|
355
|
+
const selectionsWithItems = await Promise.all(rows.map(async (row) => {
|
|
356
|
+
let title = null;
|
|
357
|
+
let source = row.workflow ?? null;
|
|
358
|
+
let url = null;
|
|
359
|
+
try {
|
|
360
|
+
const itRes = await getJson(`${board}/api/project/database/tables/items/rows?filterColumn=id&filter=${encodeURIComponent(row.item_id)}&pageSize=1`);
|
|
361
|
+
const itRows = parseSpurDbRows(itRes);
|
|
362
|
+
if (itRows[0]) {
|
|
363
|
+
title = itRows[0].title ?? null;
|
|
364
|
+
source = itRows[0].source ?? source;
|
|
365
|
+
url = itRows[0].canonical_url && /^https?:\/\//i.test(itRows[0].canonical_url) ? itRows[0].canonical_url : null;
|
|
366
|
+
}
|
|
367
|
+
} catch {}
|
|
368
|
+
return {
|
|
369
|
+
topic: row.topic,
|
|
370
|
+
itemId: row.item_id,
|
|
371
|
+
runId: row.run_id,
|
|
372
|
+
storyId: row.story_id,
|
|
373
|
+
workflow: row.workflow ?? null,
|
|
374
|
+
rank: typeof row.rank === "number" ? row.rank : null,
|
|
375
|
+
reason: row.reason ?? null,
|
|
376
|
+
status: row.status ?? "selected",
|
|
377
|
+
selectedAt: row.selected_at,
|
|
378
|
+
publishedAt: row.published_at ?? null,
|
|
379
|
+
title: title || row.item_id,
|
|
380
|
+
source: source || "unknown",
|
|
381
|
+
url
|
|
382
|
+
};
|
|
383
|
+
}));
|
|
384
|
+
return {
|
|
385
|
+
schemaVersion: 1,
|
|
386
|
+
availability: "available",
|
|
387
|
+
page: pageNum,
|
|
388
|
+
pageSize: 25,
|
|
389
|
+
total: pageData.total ?? selectionsWithItems.length,
|
|
390
|
+
selections: selectionsWithItems,
|
|
391
|
+
topics: ["ai-news"],
|
|
392
|
+
diagnostics: []
|
|
393
|
+
};
|
|
394
|
+
} catch {
|
|
395
|
+
return {
|
|
396
|
+
schemaVersion: 1,
|
|
397
|
+
availability: "available",
|
|
398
|
+
page: pageNum,
|
|
399
|
+
pageSize: 25,
|
|
400
|
+
total: 0,
|
|
401
|
+
selections: [],
|
|
402
|
+
topics: ["ai-news"],
|
|
403
|
+
diagnostics: []
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
async function nativeResults(workflow, runId) {
|
|
408
|
+
try {
|
|
409
|
+
const runData = await getJson(`${board}/api/runs/${encodeURIComponent(runId)}`);
|
|
410
|
+
const totalDuration = runData.actions?.reduce((acc, a) => acc + (a.durationMs || 0), 0) ?? 0;
|
|
411
|
+
return {
|
|
412
|
+
schemaVersion: 1,
|
|
413
|
+
workflow,
|
|
414
|
+
runId,
|
|
415
|
+
availability: "available",
|
|
416
|
+
summary: {
|
|
417
|
+
status: runData.run?.status ?? "done",
|
|
418
|
+
startedAt: runData.run?.startedAt,
|
|
419
|
+
completedAt: runData.run?.completedAt,
|
|
420
|
+
durationMs: totalDuration,
|
|
421
|
+
actions: runData.actions?.length ?? 0,
|
|
422
|
+
phases: runData.phases?.length ?? 0
|
|
423
|
+
},
|
|
424
|
+
artifacts: [],
|
|
425
|
+
diagnostics: []
|
|
426
|
+
};
|
|
427
|
+
} catch {
|
|
428
|
+
return {
|
|
429
|
+
schemaVersion: 1,
|
|
430
|
+
workflow,
|
|
431
|
+
runId,
|
|
432
|
+
availability: "missing",
|
|
433
|
+
summary: {},
|
|
434
|
+
artifacts: [],
|
|
435
|
+
diagnostics: []
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async function nativeConfig(workflow, runId) {
|
|
440
|
+
try {
|
|
441
|
+
const runData = await getJson(`${board}/api/runs/${encodeURIComponent(runId)}`);
|
|
442
|
+
return {
|
|
443
|
+
schemaVersion: 1,
|
|
444
|
+
workflow,
|
|
445
|
+
runId,
|
|
446
|
+
capturedAt: runData.run?.startedAt ?? null,
|
|
447
|
+
settings: {
|
|
448
|
+
workflowName: runData.run?.workflowName ?? workflow,
|
|
449
|
+
status: runData.run?.status ?? "done",
|
|
450
|
+
mode: runData.run?.mode ?? "state-machine"
|
|
451
|
+
},
|
|
452
|
+
unavailableKeys: [],
|
|
453
|
+
diagnostics: []
|
|
454
|
+
};
|
|
455
|
+
} catch {
|
|
456
|
+
return {
|
|
457
|
+
schemaVersion: 1,
|
|
458
|
+
workflow,
|
|
459
|
+
runId,
|
|
460
|
+
capturedAt: null,
|
|
461
|
+
settings: {},
|
|
462
|
+
unavailableKeys: [],
|
|
463
|
+
diagnostics: []
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
}
|
|
72
467
|
return {
|
|
73
|
-
health: () => getJson(`${
|
|
74
|
-
|
|
75
|
-
|
|
468
|
+
health: () => isNativeSpur ? getJson(`${board}/api/health`).then(() => ({
|
|
469
|
+
schemaVersion: 1,
|
|
470
|
+
projectPath: "knowledge-kit"
|
|
471
|
+
})) : getJson(`${reader}/api/health`),
|
|
472
|
+
results: (workflow, runId) => isNativeSpur ? nativeResults(workflow, runId) : getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/results`),
|
|
473
|
+
config: (workflow, runId) => isNativeSpur ? nativeConfig(workflow, runId) : getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/config`),
|
|
76
474
|
artifactUrl: (workflow, runId, artifactId) => `${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/artifacts/${encodeURIComponent(artifactId)}`,
|
|
77
475
|
runs: (workflow, cursor) => {
|
|
78
476
|
const params = new URLSearchParams({ workflow, limit: "25" });
|
|
@@ -81,11 +479,20 @@ function createBoardClient(options) {
|
|
|
81
479
|
return getJson(`${board}/api/runs?${params.toString()}`);
|
|
82
480
|
},
|
|
83
481
|
storeOverview: (runIds) => {
|
|
482
|
+
if (isNativeSpur)
|
|
483
|
+
return nativeStoreOverview(runIds);
|
|
84
484
|
const params = new URLSearchParams({ runs: runIds.slice(0, MAX_OVERVIEW_RUNS).join(",") });
|
|
85
485
|
return getJson(`${reader}/api/workflows/kk-collect/store/overview?${params.toString()}`);
|
|
86
486
|
},
|
|
87
|
-
storeRun: (runId) => getJson(`${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store`),
|
|
88
|
-
storeItems: (runId, query = {}) =>
|
|
487
|
+
storeRun: (runId) => isNativeSpur ? nativeStoreRun(runId) : getJson(`${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store`),
|
|
488
|
+
storeItems: (runId, query = {}) => {
|
|
489
|
+
if (isNativeSpur)
|
|
490
|
+
return nativeStoreItems(runId, query);
|
|
491
|
+
const qs = storeItemsQueryString(query);
|
|
492
|
+
const path = runId !== undefined && runId.trim() !== "" ? `${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store/items?${qs}` : `${reader}/api/workflows/kk-collect/store/items?${qs}`;
|
|
493
|
+
return getJson(path);
|
|
494
|
+
},
|
|
495
|
+
storeSelections: (query = {}) => isNativeSpur ? nativeStoreSelections(query) : getJson(`${reader}/api/workflows/kk-collect/store/selections?${storeSelectionsQueryString(query)}`),
|
|
89
496
|
runDetail: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}`),
|
|
90
497
|
progress: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}/progress`)
|
|
91
498
|
};
|