@lightcone-ai/daemon 0.15.37 → 0.15.39
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.
|
@@ -123,6 +123,9 @@ export class BilibiliAdapter {
|
|
|
123
123
|
if (!loggedIn) throw new Error('LOGIN_EXPIRED: B站登录已过期,请重新扫码连接');
|
|
124
124
|
|
|
125
125
|
if (images.length > 0) {
|
|
126
|
+
// The file input only appears after clicking the image button in the editor toolbar
|
|
127
|
+
await this._clickImageToolbarButton();
|
|
128
|
+
await sleep(1_000);
|
|
126
129
|
await this._waitForSelector(ARTICLE_IMAGE_FILE_SELECTOR, 15_000);
|
|
127
130
|
await this._uploadFiles(images, 'image');
|
|
128
131
|
await this._waitForUploadSettled(180_000);
|
|
@@ -326,6 +329,45 @@ export class BilibiliAdapter {
|
|
|
326
329
|
await sleep(400);
|
|
327
330
|
}
|
|
328
331
|
|
|
332
|
+
async _clickImageToolbarButton() {
|
|
333
|
+
const result = await this._cdp.send('Runtime.evaluate', {
|
|
334
|
+
expression: `
|
|
335
|
+
(function() {
|
|
336
|
+
const selectors = [
|
|
337
|
+
'.ql-image',
|
|
338
|
+
'[class*="toolbar-image"]',
|
|
339
|
+
'[class*="toolbar"] [class*="image"]',
|
|
340
|
+
'[class*="toolbar"] [class*="pic"]',
|
|
341
|
+
'[aria-label="图片"]',
|
|
342
|
+
'[aria-label*="插入图片"]',
|
|
343
|
+
'[title="图片"]',
|
|
344
|
+
'[title*="插入图片"]',
|
|
345
|
+
'[class*="bf-icon-image"]',
|
|
346
|
+
'[data-action="uploadImage"]',
|
|
347
|
+
'[data-type="image"]',
|
|
348
|
+
];
|
|
349
|
+
for (const sel of selectors) {
|
|
350
|
+
const el = document.querySelector(sel);
|
|
351
|
+
if (el) { el.click(); return sel; }
|
|
352
|
+
}
|
|
353
|
+
// Heuristic: any toolbar button whose title/aria-label mentions image/图片
|
|
354
|
+
for (const el of document.querySelectorAll('[class*="toolbar"] button, [class*="toolbar"] [role="button"], [class*="toolbar"] span, [class*="editor-toolbar"] *')) {
|
|
355
|
+
const hint = [el.getAttribute('title'), el.getAttribute('aria-label'), el.className?.toString?.()].filter(Boolean).join(' ').toLowerCase();
|
|
356
|
+
if (hint.includes('image') || hint.includes('图片') || hint.includes('pic')) {
|
|
357
|
+
el.click();
|
|
358
|
+
return 'toolbar-heuristic:' + hint.slice(0, 60);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
})()
|
|
363
|
+
`,
|
|
364
|
+
returnByValue: true,
|
|
365
|
+
});
|
|
366
|
+
const clicked = result.result?.value;
|
|
367
|
+
console.error(`[BilibiliAdapter] _clickImageToolbarButton: ${clicked ?? 'not found'}`);
|
|
368
|
+
return !!clicked;
|
|
369
|
+
}
|
|
370
|
+
|
|
329
371
|
async _clickByTextCandidates(candidates = []) {
|
|
330
372
|
for (const text of candidates) {
|
|
331
373
|
const clicked = await this._clickByText(text);
|
|
@@ -128,7 +128,19 @@ export class KuaishouAdapter {
|
|
|
128
128
|
const deadline = Date.now() + timeoutMs;
|
|
129
129
|
while (Date.now() < deadline) {
|
|
130
130
|
const result = await this._cdp.send('Runtime.evaluate', {
|
|
131
|
-
expression:
|
|
131
|
+
expression: `
|
|
132
|
+
(function() {
|
|
133
|
+
const sel = ${JSON.stringify(selector)};
|
|
134
|
+
if (document.querySelector(sel)) return true;
|
|
135
|
+
for (const f of document.querySelectorAll('iframe')) {
|
|
136
|
+
try {
|
|
137
|
+
const d = f.contentDocument || f.contentWindow?.document;
|
|
138
|
+
if (d && d.querySelector(sel)) return true;
|
|
139
|
+
} catch(e) {}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
})()
|
|
143
|
+
`,
|
|
132
144
|
returnByValue: true,
|
|
133
145
|
});
|
|
134
146
|
if (result.result?.value) return;
|
|
@@ -136,12 +148,16 @@ export class KuaishouAdapter {
|
|
|
136
148
|
}
|
|
137
149
|
// Dump diagnostic info to help debug page state on timeout
|
|
138
150
|
try {
|
|
139
|
-
const [urlR, titleR, bodyR, inputR, uploadR] = await Promise.all([
|
|
151
|
+
const [urlR, titleR, bodyR, inputR, uploadR, iframeR] = await Promise.all([
|
|
140
152
|
this._cdp.send('Runtime.evaluate', { expression: 'location.href', returnByValue: true }),
|
|
141
153
|
this._cdp.send('Runtime.evaluate', { expression: 'document.title', returnByValue: true }),
|
|
142
154
|
this._cdp.send('Runtime.evaluate', { expression: 'document.body?.innerText?.slice(0,400)', returnByValue: true }),
|
|
143
155
|
this._cdp.send('Runtime.evaluate', { expression: `!!document.querySelector('input[type="file"]')`, returnByValue: true }),
|
|
144
156
|
this._cdp.send('Runtime.evaluate', { expression: `document.querySelectorAll('[class*="upload"],[class*="Upload"]').length`, returnByValue: true }),
|
|
157
|
+
this._cdp.send('Runtime.evaluate', {
|
|
158
|
+
expression: `(function(){const frames=document.querySelectorAll('iframe');let found=false;for(const f of frames){try{const d=f.contentDocument||f.contentWindow?.document;if(d&&d.querySelector('input[type="file"]')){found=true;break;}}catch(e){}}return JSON.stringify({iframes:frames.length,fileInIframe:found})})()`,
|
|
159
|
+
returnByValue: true,
|
|
160
|
+
}),
|
|
145
161
|
]);
|
|
146
162
|
console.error(`[KuaishouAdapter] selector timeout diagnostics:`);
|
|
147
163
|
console.error(` url=${urlR.result?.value}`);
|
|
@@ -149,6 +165,7 @@ export class KuaishouAdapter {
|
|
|
149
165
|
console.error(` input[type=file] present=${inputR.result?.value}`);
|
|
150
166
|
console.error(` upload-class elements=${uploadR.result?.value}`);
|
|
151
167
|
console.error(` body text: ${bodyR.result?.value}`);
|
|
168
|
+
console.error(` iframe info: ${iframeR.result?.value}`);
|
|
152
169
|
} catch (diagErr) {
|
|
153
170
|
console.error(`[KuaishouAdapter] diagnostic failed: ${diagErr.message}`);
|
|
154
171
|
}
|
|
@@ -196,12 +213,27 @@ export class KuaishouAdapter {
|
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
async _uploadFiles(filePaths) {
|
|
199
|
-
// Wait up to 10s for the file input
|
|
216
|
+
// Wait up to 10s for the file input; check main document and same-origin iframes
|
|
200
217
|
const deadline = Date.now() + 10000;
|
|
201
218
|
let objectId = null;
|
|
202
219
|
while (Date.now() < deadline) {
|
|
203
220
|
const result = await this._cdp.send('Runtime.evaluate', {
|
|
204
|
-
expression: `
|
|
221
|
+
expression: `
|
|
222
|
+
(function() {
|
|
223
|
+
const el = document.querySelector('input[type="file"]');
|
|
224
|
+
if (el) return el;
|
|
225
|
+
for (const f of document.querySelectorAll('iframe')) {
|
|
226
|
+
try {
|
|
227
|
+
const d = f.contentDocument || f.contentWindow?.document;
|
|
228
|
+
if (d) {
|
|
229
|
+
const found = d.querySelector('input[type="file"]');
|
|
230
|
+
if (found) return found;
|
|
231
|
+
}
|
|
232
|
+
} catch(e) {}
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
})()
|
|
236
|
+
`,
|
|
205
237
|
returnByValue: false,
|
|
206
238
|
});
|
|
207
239
|
if (result.result?.objectId) { objectId = result.result.objectId; break; }
|
package/package.json
CHANGED
package/src/chat-bridge.js
CHANGED
|
@@ -426,10 +426,22 @@ function cacheKeyFor(method, apiPath, body, {
|
|
|
426
426
|
return createHash('sha256').update(payload, 'utf8').digest('hex');
|
|
427
427
|
}
|
|
428
428
|
|
|
429
|
+
const DATA_URI_PREFIX = 'data:';
|
|
430
|
+
const GOVERNANCE_BINARY_PLACEHOLDER = '[binary content stripped]';
|
|
431
|
+
|
|
432
|
+
function stripBinaryContent(body) {
|
|
433
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) return body;
|
|
434
|
+
const stripped = { ...body };
|
|
435
|
+
if (typeof stripped.content === 'string' && stripped.content.startsWith(DATA_URI_PREFIX)) {
|
|
436
|
+
stripped.content = GOVERNANCE_BINARY_PLACEHOLDER;
|
|
437
|
+
}
|
|
438
|
+
return stripped;
|
|
439
|
+
}
|
|
440
|
+
|
|
429
441
|
function toolInputFor(apiPath, body) {
|
|
430
442
|
return {
|
|
431
443
|
...queryParamsFromPath(apiPath),
|
|
432
|
-
...(body && typeof body === 'object' ? body : {}),
|
|
444
|
+
...stripBinaryContent(body && typeof body === 'object' ? body : {}),
|
|
433
445
|
};
|
|
434
446
|
}
|
|
435
447
|
|