@dai_ming/plugin-deliverables 1.1.7 → 1.1.9
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/index.js +105 -27
- package/openclaw-plugin.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1802,6 +1802,30 @@ function extractDeliverableURL(line) {
|
|
|
1802
1802
|
return "";
|
|
1803
1803
|
}
|
|
1804
1804
|
|
|
1805
|
+
function extractAllDeliverableURLs(line) {
|
|
1806
|
+
const text = String(line || "").trim();
|
|
1807
|
+
if (!text) {
|
|
1808
|
+
return [];
|
|
1809
|
+
}
|
|
1810
|
+
const urls = [];
|
|
1811
|
+
const seen = new Set();
|
|
1812
|
+
const markdownLinks = text.matchAll(/\((https?:\/\/[^)\s]+)\)/giu);
|
|
1813
|
+
for (const m of markdownLinks) {
|
|
1814
|
+
const url = m[1].trim();
|
|
1815
|
+
if (url && !seen.has(url)) {
|
|
1816
|
+
seen.add(url);
|
|
1817
|
+
urls.push(url);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
if (urls.length === 0) {
|
|
1821
|
+
const rawLink = text.match(/https?:\/\/\S+/iu);
|
|
1822
|
+
if (rawLink && rawLink[0]) {
|
|
1823
|
+
urls.push(rawLink[0].trim());
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
return urls;
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1805
1829
|
function configuredKBHosts() {
|
|
1806
1830
|
const cfg = loadDeliverableConfig();
|
|
1807
1831
|
const values = [
|
|
@@ -1943,10 +1967,12 @@ function splitDeliverableMessage(text) {
|
|
|
1943
1967
|
const normalizedLine = stripBulletPrefix(line).trim();
|
|
1944
1968
|
if (normalizedLine) {
|
|
1945
1969
|
linkLines.push(normalizedLine);
|
|
1946
|
-
const
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1970
|
+
const urls = extractAllDeliverableURLs(normalizedLine);
|
|
1971
|
+
for (const url of urls) {
|
|
1972
|
+
if (isTrustedDeliverableURL(url)) {
|
|
1973
|
+
linkUrls.push(url);
|
|
1974
|
+
linkItems.push({ line: normalizedLine, url });
|
|
1975
|
+
}
|
|
1950
1976
|
}
|
|
1951
1977
|
}
|
|
1952
1978
|
}
|
|
@@ -1965,6 +1991,7 @@ function splitDeliverableMessage(text) {
|
|
|
1965
1991
|
linkItems,
|
|
1966
1992
|
primaryLinkUrl: linkUrls.length > 0 ? linkUrls[0] : "",
|
|
1967
1993
|
fileLinkUrl: selectPalzFileURL(linkItems),
|
|
1994
|
+
deduplicatedItems: deduplicateLinkItems(linkItems),
|
|
1968
1995
|
};
|
|
1969
1996
|
}
|
|
1970
1997
|
|
|
@@ -2007,6 +2034,31 @@ function selectPalzFileURL(linkItems) {
|
|
|
2007
2034
|
return (preview && preview.url) || linkItems[0].url || "";
|
|
2008
2035
|
}
|
|
2009
2036
|
|
|
2037
|
+
function deduplicateLinkItems(linkItems) {
|
|
2038
|
+
if (!Array.isArray(linkItems) || linkItems.length === 0) {
|
|
2039
|
+
return { fileItems: [], textItems: [] };
|
|
2040
|
+
}
|
|
2041
|
+
const byIdentity = new Map();
|
|
2042
|
+
const textItems = [];
|
|
2043
|
+
for (const item of linkItems) {
|
|
2044
|
+
const identity = extractDeliverableIdentity(item && item.url);
|
|
2045
|
+
if (!identity) {
|
|
2046
|
+
textItems.push(item);
|
|
2047
|
+
continue;
|
|
2048
|
+
}
|
|
2049
|
+
const existing = byIdentity.get(identity);
|
|
2050
|
+
if (!existing) {
|
|
2051
|
+
byIdentity.set(identity, item);
|
|
2052
|
+
} else if (/\/documents\/preview\//u.test(String(item.url || ""))) {
|
|
2053
|
+
byIdentity.set(identity, item);
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
return {
|
|
2057
|
+
fileItems: Array.from(byIdentity.values()),
|
|
2058
|
+
textItems,
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2010
2062
|
function cloneBody(body, content, suffix) {
|
|
2011
2063
|
const next = {};
|
|
2012
2064
|
Object.keys(body).forEach((key) => {
|
|
@@ -2063,6 +2115,7 @@ function shouldSplitPalzPayload(body) {
|
|
|
2063
2115
|
links: split.links,
|
|
2064
2116
|
primaryLinkUrl: split.primaryLinkUrl,
|
|
2065
2117
|
fileLinkUrl: split.fileLinkUrl,
|
|
2118
|
+
deduplicatedItems: split.deduplicatedItems,
|
|
2066
2119
|
};
|
|
2067
2120
|
}
|
|
2068
2121
|
return split;
|
|
@@ -2157,16 +2210,15 @@ function installPalzFetchPatch(api) {
|
|
|
2157
2210
|
return originalFetch(input, init);
|
|
2158
2211
|
}
|
|
2159
2212
|
|
|
2213
|
+
const dedup = split.deduplicatedItems || { fileItems: [], textItems: [] };
|
|
2214
|
+
const hasFileItems = dedup.fileItems.length > 0;
|
|
2215
|
+
const hasTextItems = dedup.textItems.length > 0;
|
|
2216
|
+
|
|
2160
2217
|
const summaryBody = cloneBody(parsed, split.summary, "__summary");
|
|
2161
|
-
const fileLinkUrl = split.fileLinkUrl || "";
|
|
2162
|
-
const linksBody = fileLinkUrl
|
|
2163
|
-
? cloneBodyAsFileLink(parsed, fileLinkUrl, "__links")
|
|
2164
|
-
: cloneBody(parsed, split.links, "__links");
|
|
2165
2218
|
const summaryBodyStr = JSON.stringify(summaryBody);
|
|
2166
|
-
const linksBodyStr = JSON.stringify(linksBody);
|
|
2167
2219
|
|
|
2168
2220
|
api.logger.info?.(
|
|
2169
|
-
`[plugin-deliverables] split deliverable reply injected by plugin-deliverables target=${String(parsed.conversation_id || "")} summaryMsgId=${String(summaryBody.msg_id || "")}
|
|
2221
|
+
`[plugin-deliverables] split deliverable reply injected by plugin-deliverables target=${String(parsed.conversation_id || "")} summaryMsgId=${String(summaryBody.msg_id || "")} fileLinks=${dedup.fileItems.length} textLinks=${dedup.textItems.length}`,
|
|
2170
2222
|
);
|
|
2171
2223
|
api.logger.info?.(
|
|
2172
2224
|
`[plugin-deliverables] palz summary request body_length=${summaryBodyStr.length}\n request_body=${summaryBodyStr}`,
|
|
@@ -2176,28 +2228,54 @@ function installPalzFetchPatch(api) {
|
|
|
2176
2228
|
const summaryInit = Object.assign({}, baseInit, {
|
|
2177
2229
|
body: summaryBodyStr,
|
|
2178
2230
|
});
|
|
2179
|
-
const linksInit = Object.assign({}, baseInit, {
|
|
2180
|
-
body: linksBodyStr,
|
|
2181
|
-
});
|
|
2182
2231
|
|
|
2183
|
-
const
|
|
2184
|
-
const
|
|
2232
|
+
const summaryResponse = await originalFetch(input, summaryInit);
|
|
2233
|
+
const summaryResponseText = await readResponseText(summaryResponse);
|
|
2185
2234
|
api.logger.info?.(
|
|
2186
|
-
`[plugin-deliverables] palz summary response status=${
|
|
2235
|
+
`[plugin-deliverables] palz summary response status=${summaryResponse ? summaryResponse.status : "unknown"} ok=${Boolean(summaryResponse && summaryResponse.ok)}\n response_body=${previewText(summaryResponseText)}`,
|
|
2187
2236
|
);
|
|
2188
|
-
if (!
|
|
2189
|
-
return
|
|
2237
|
+
if (!summaryResponse || !summaryResponse.ok) {
|
|
2238
|
+
return summaryResponse;
|
|
2190
2239
|
}
|
|
2191
2240
|
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
)
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2241
|
+
let lastResponse = summaryResponse;
|
|
2242
|
+
|
|
2243
|
+
for (let idx = 0; idx < dedup.fileItems.length; idx += 1) {
|
|
2244
|
+
const item = dedup.fileItems[idx];
|
|
2245
|
+
const fileBody = cloneBodyAsFileLink(parsed, item.url, `__links_${idx}`);
|
|
2246
|
+
const fileBodyStr = JSON.stringify(fileBody);
|
|
2247
|
+
api.logger.info?.(
|
|
2248
|
+
`[plugin-deliverables] palz file_url request [${idx}] body_length=${fileBodyStr.length} url=${item.url}\n request_body=${fileBodyStr}`,
|
|
2249
|
+
);
|
|
2250
|
+
const fileInit = Object.assign({}, baseInit, { body: fileBodyStr });
|
|
2251
|
+
const fileResponse = await originalFetch(input, fileInit);
|
|
2252
|
+
const fileResponseText = await readResponseText(fileResponse);
|
|
2253
|
+
api.logger.info?.(
|
|
2254
|
+
`[plugin-deliverables] palz file_url response [${idx}] status=${fileResponse ? fileResponse.status : "unknown"} ok=${Boolean(fileResponse && fileResponse.ok)}\n response_body=${previewText(fileResponseText)}`,
|
|
2255
|
+
);
|
|
2256
|
+
if (!fileResponse || !fileResponse.ok) {
|
|
2257
|
+
return fileResponse;
|
|
2258
|
+
}
|
|
2259
|
+
lastResponse = fileResponse;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
if (hasTextItems) {
|
|
2263
|
+
const textContent = dedup.textItems.map((item) => item.line).join("\n");
|
|
2264
|
+
const textBody = cloneBody(parsed, textContent, "__links_text");
|
|
2265
|
+
const textBodyStr = JSON.stringify(textBody);
|
|
2266
|
+
api.logger.info?.(
|
|
2267
|
+
`[plugin-deliverables] palz text links request body_length=${textBodyStr.length}\n request_body=${textBodyStr}`,
|
|
2268
|
+
);
|
|
2269
|
+
const textInit = Object.assign({}, baseInit, { body: textBodyStr });
|
|
2270
|
+
const textResponse = await originalFetch(input, textInit);
|
|
2271
|
+
const textResponseText = await readResponseText(textResponse);
|
|
2272
|
+
api.logger.info?.(
|
|
2273
|
+
`[plugin-deliverables] palz text links response status=${textResponse ? textResponse.status : "unknown"} ok=${Boolean(textResponse && textResponse.ok)}\n response_body=${previewText(textResponseText)}`,
|
|
2274
|
+
);
|
|
2275
|
+
lastResponse = textResponse;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
return lastResponse;
|
|
2201
2279
|
};
|
|
2202
2280
|
|
|
2203
2281
|
globalThis.fetch = patchedFetch;
|
package/openclaw-plugin.json
CHANGED
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "plugin-deliverables",
|
|
3
3
|
"name": "Deliverables",
|
|
4
4
|
"description": "Deliverables runtime guard for upload-first file delivery with Palz split-send diagnostics.",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.9",
|
|
6
6
|
"skills": ["./skills"],
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/package.json
CHANGED