chrome-ai-bridge 1.0.3 → 1.0.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/build/node_modules/chrome-devtools-frontend/front_end/core/common/Base64.js +20 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Gzip.js +11 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Object.js +6 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ParsedURL.js +3 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/ResourceType.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Settings.js +18 -8
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHostStub.js +3 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/ResourceLoader.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/host/UserMetrics.js +17 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/ArrayUtilities.js +10 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/StringUtilities.js +63 -12
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/CDPConnection.js +1 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/protocol_client/InspectorBackend.js +4 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMatchedStyles.js +44 -9
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMetadata.js +6 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DOMModel.js +169 -12
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DebuggerModel.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/IsolateManager.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkManager.js +18 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkRequest.js +7 -21
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/OverlayModel.js +17 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RehydratingConnection.js +5 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ResourceTreeModel.js +8 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMap.js +14 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapManager.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapScopesInfo.js +11 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Target.js +3 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/ARIAProperties.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.js +1 -16
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +35 -14
- package/build/node_modules/chrome-devtools-frontend/front_end/generated/SupportedCSSProperties.js +197 -101
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.js +2 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.js +10 -16
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js +97 -26
- package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AICallTree.js +35 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/annotations/AnnotationRepository.js +163 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/annotations/AnnotationType.js +10 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/annotations/annotations.js +5 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CompilerScriptMapping.js +5 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerWorkspaceBinding.js +7 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/DeviceModeModel.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/emulation/EmulatedDevices.js +14 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/FormatterWorkerPool.js +8 -5
- package/build/node_modules/chrome-devtools-frontend/front_end/models/greendev/Prototypes.js +33 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/greendev/greendev.js +4 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceImpl.js +70 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/stack_trace/StackTraceModel.js +82 -30
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/EventsSerializer.js +7 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/LanternComputationData.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/Processor.js +18 -19
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/Styles.js +12 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/Initiators.js +46 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/TraceTree.js +4 -3
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/extras/extras.js +1 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/LargestImagePaintHandler.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/LayoutShiftsHandler.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/MetaHandler.js +6 -0
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/NetworkRequestsHandler.js +10 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/PageLoadMetricsHandler.js +44 -27
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Timing.js +9 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/Common.js +1 -6
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPBreakdown.js +2 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/LCPDiscovery.js +2 -4
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/NetworkDependencyTree.js +3 -2
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/insights/RenderBlocking.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/types/TraceEvents.js +30 -11
- package/build/node_modules/chrome-devtools-frontend/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +28 -13
- package/build/node_modules/chrome-devtools-frontend/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +1 -1
- package/build/node_modules/chrome-devtools-frontend/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +4 -0
- package/build/src/tools/chatgpt-web.js +68 -49
- package/build/src/tools/gemini-web.js +66 -22
- package/build/src/tools/pages.js +0 -1
- package/package.json +1 -1
|
@@ -69,13 +69,12 @@ class Decoder {
|
|
|
69
69
|
decode() {
|
|
70
70
|
const iter = new TokenIterator(this.#encodedScopes);
|
|
71
71
|
while (iter.hasNext()) {
|
|
72
|
-
if (iter.peek() === ",") {
|
|
73
|
-
iter.nextChar(); // Consume ",".
|
|
74
|
-
this.#scopes.push(null); // Add an EmptyItem;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
72
|
const tag = iter.nextUnsignedVLQ();
|
|
78
73
|
switch (tag) {
|
|
74
|
+
case 0 /* Tag.EMPTY */: {
|
|
75
|
+
this.#scopes.push(null);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
79
78
|
case 1 /* Tag.ORIGINAL_SCOPE_START */: {
|
|
80
79
|
const item = {
|
|
81
80
|
flags: iter.nextUnsignedVLQ(),
|
|
@@ -158,6 +157,14 @@ class Decoder {
|
|
|
158
157
|
this.#handleGeneratedRangeCallSite(iter.nextUnsignedVLQ(), iter.nextUnsignedVLQ(), iter.nextUnsignedVLQ());
|
|
159
158
|
break;
|
|
160
159
|
}
|
|
160
|
+
case 99 /* Tag.VENDOR_EXTENSION */: {
|
|
161
|
+
const _extensionNameIdx = iter.nextUnsignedVLQ();
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
default: {
|
|
165
|
+
this.#throwInStrictMode(`Encountered illegal item tag ${tag}`);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
161
168
|
}
|
|
162
169
|
// Consume any trailing VLQ and the the ","
|
|
163
170
|
while (iter.hasNext() && iter.peek() !== ",")
|
|
@@ -165,10 +172,6 @@ class Decoder {
|
|
|
165
172
|
if (iter.hasNext())
|
|
166
173
|
iter.nextChar();
|
|
167
174
|
}
|
|
168
|
-
if (iter.currentChar() === ",") {
|
|
169
|
-
// Handle trailing EmptyItem.
|
|
170
|
-
this.#scopes.push(null);
|
|
171
|
-
}
|
|
172
175
|
if (this.#scopeStack.length > 0) {
|
|
173
176
|
this.#throwInStrictMode("Encountered ORIGINAL_SCOPE_START without matching END!");
|
|
174
177
|
}
|
|
@@ -285,7 +288,6 @@ class Decoder {
|
|
|
285
288
|
}
|
|
286
289
|
}
|
|
287
290
|
this.#rangeStack.push(range);
|
|
288
|
-
this.#subRangeBindingsForRange.clear();
|
|
289
291
|
}
|
|
290
292
|
#handleGeneratedRangeBindingsItem(valueIdxs) {
|
|
291
293
|
const range = this.#rangeStack.at(-1);
|
|
@@ -303,11 +305,21 @@ class Decoder {
|
|
|
303
305
|
}
|
|
304
306
|
}
|
|
305
307
|
#recordGeneratedSubRangeBindingItem(variableIndex, bindings) {
|
|
306
|
-
|
|
308
|
+
const range = this.#rangeStack.at(-1);
|
|
309
|
+
if (!range) {
|
|
310
|
+
this.#throwInStrictMode("Encountered GENERATED_RANGE_SUBRANGE_BINDING without surrounding GENERATED_RANGE_START");
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
let subRangeBindings = this.#subRangeBindingsForRange.get(range);
|
|
314
|
+
if (!subRangeBindings) {
|
|
315
|
+
subRangeBindings = new Map();
|
|
316
|
+
this.#subRangeBindingsForRange.set(range, subRangeBindings);
|
|
317
|
+
}
|
|
318
|
+
if (subRangeBindings.has(variableIndex)) {
|
|
307
319
|
this.#throwInStrictMode("Encountered multiple GENERATED_RANGE_SUBRANGE_BINDING items for the same variable");
|
|
308
320
|
return;
|
|
309
321
|
}
|
|
310
|
-
|
|
322
|
+
subRangeBindings.set(variableIndex, bindings);
|
|
311
323
|
}
|
|
312
324
|
#handleGeneratedRangeCallSite(sourceIndex, line, column) {
|
|
313
325
|
const range = this.#rangeStack.at(-1);
|
|
@@ -349,7 +361,10 @@ class Decoder {
|
|
|
349
361
|
}
|
|
350
362
|
}
|
|
351
363
|
#handleGeneratedRangeSubRangeBindings(range) {
|
|
352
|
-
|
|
364
|
+
const subRangeBindings = this.#subRangeBindingsForRange.get(range);
|
|
365
|
+
if (!subRangeBindings)
|
|
366
|
+
return;
|
|
367
|
+
for (const [variableIndex, bindings] of subRangeBindings) {
|
|
353
368
|
const value = range.values[variableIndex];
|
|
354
369
|
const subRanges = [];
|
|
355
370
|
range.values[variableIndex] = subRanges;
|
|
@@ -238,19 +238,47 @@ export const askChatGPTWeb = defineTool({
|
|
|
238
238
|
// Get or create a dedicated ChatGPT tab
|
|
239
239
|
const { page, needsNavigation } = await getOrCreateChatGPTPage(context);
|
|
240
240
|
try {
|
|
241
|
-
// Step 1:
|
|
241
|
+
// Step 1: Determine target URL (existing session or top page)
|
|
242
242
|
response.appendResponseLine('ChatGPTに接続中...');
|
|
243
|
-
|
|
244
|
-
|
|
243
|
+
let isNewChat = false;
|
|
244
|
+
let sessionChatId;
|
|
245
|
+
let targetUrl = CHATGPT_CONFIG.DEFAULT_URL;
|
|
246
|
+
if (!createNewChat) {
|
|
247
|
+
// Check for existing session first
|
|
248
|
+
const sessions = await loadChatSessions();
|
|
249
|
+
const projectSessions = sessions[project] || [];
|
|
250
|
+
if (projectSessions.length > 0) {
|
|
251
|
+
// Get the most recently used session
|
|
252
|
+
const sortedSessions = [...projectSessions].sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime());
|
|
253
|
+
const latestSession = sortedSessions[0];
|
|
254
|
+
sessionChatId = latestSession.chatId;
|
|
255
|
+
targetUrl = latestSession.url;
|
|
256
|
+
response.appendResponseLine(`既存のプロジェクトチャットを使用: ${latestSession.url}`);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
response.appendResponseLine('既存チャットが見つかりませんでした。新規作成します。');
|
|
260
|
+
isNewChat = true;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
isNewChat = true;
|
|
265
|
+
}
|
|
266
|
+
// Step 2: Navigate to target URL (skip if already there)
|
|
267
|
+
const currentUrl = page.url();
|
|
268
|
+
const isAlreadyOnTarget = sessionChatId
|
|
269
|
+
? currentUrl.includes(sessionChatId)
|
|
270
|
+
: currentUrl.includes('chatgpt.com') && !needsNavigation;
|
|
271
|
+
if (!isAlreadyOnTarget) {
|
|
272
|
+
await navigateWithRetry(page, targetUrl, {
|
|
245
273
|
waitUntil: 'networkidle2',
|
|
246
274
|
});
|
|
247
|
-
// Wait for page to fully render
|
|
275
|
+
// Wait for page to fully render
|
|
248
276
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
249
277
|
}
|
|
250
278
|
else {
|
|
251
279
|
response.appendResponseLine('✅ 既存のChatGPTタブを再利用');
|
|
252
280
|
}
|
|
253
|
-
// Step
|
|
281
|
+
// Step 3: Check login status
|
|
254
282
|
const loginStatus = await getLoginStatus(page, 'chatgpt');
|
|
255
283
|
if (loginStatus === LoginStatus.NEEDS_LOGIN) {
|
|
256
284
|
response.appendResponseLine('\n❌ ChatGPTへのログインが必要です');
|
|
@@ -287,54 +315,27 @@ export const askChatGPTWeb = defineTool({
|
|
|
287
315
|
}
|
|
288
316
|
}
|
|
289
317
|
response.appendResponseLine('✅ ログイン確認完了');
|
|
290
|
-
// Step
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
// Get the most recently used session
|
|
299
|
-
const sortedSessions = [...projectSessions].sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime());
|
|
300
|
-
const latestSession = sortedSessions[0];
|
|
301
|
-
response.appendResponseLine(`既存のプロジェクトチャットを使用: ${latestSession.url}`);
|
|
302
|
-
sessionChatId = latestSession.chatId;
|
|
303
|
-
// Skip navigation if already on the same chat
|
|
304
|
-
const currentUrl = page.url();
|
|
305
|
-
if (!currentUrl.includes(latestSession.chatId)) {
|
|
306
|
-
await navigateWithRetry(page, latestSession.url, {
|
|
307
|
-
waitUntil: 'networkidle2', // Wait for JS to finish loading
|
|
308
|
-
});
|
|
318
|
+
// Step 4: Wait for input field (for existing sessions)
|
|
319
|
+
if (sessionChatId) {
|
|
320
|
+
let inputFieldReady = false;
|
|
321
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
322
|
+
try {
|
|
323
|
+
await page.waitForSelector('.ProseMirror[contenteditable="true"]', { timeout: 5000 });
|
|
324
|
+
inputFieldReady = true;
|
|
325
|
+
break;
|
|
309
326
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
await page.waitForSelector('.ProseMirror[contenteditable="true"]', { timeout: 5000 });
|
|
315
|
-
inputFieldReady = true;
|
|
316
|
-
break;
|
|
327
|
+
catch {
|
|
328
|
+
if (attempt < 2) {
|
|
329
|
+
response.appendResponseLine(`⏳ 入力欄を待機中... (${attempt + 1}/3)`);
|
|
330
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
317
331
|
}
|
|
318
|
-
catch {
|
|
319
|
-
if (attempt < 2) {
|
|
320
|
-
response.appendResponseLine(`⏳ 入力欄を待機中... (${attempt + 1}/3)`);
|
|
321
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (!inputFieldReady) {
|
|
326
|
-
response.appendResponseLine('⚠️ 入力欄の準備に時間がかかっています。続行を試みます...');
|
|
327
332
|
}
|
|
328
333
|
}
|
|
329
|
-
|
|
330
|
-
response.appendResponseLine('
|
|
331
|
-
isNewChat = true;
|
|
334
|
+
if (!inputFieldReady) {
|
|
335
|
+
response.appendResponseLine('⚠️ 入力欄の準備に時間がかかっています。続行を試みます...');
|
|
332
336
|
}
|
|
333
337
|
}
|
|
334
|
-
|
|
335
|
-
isNewChat = true;
|
|
336
|
-
}
|
|
337
|
-
// Step 3: Create new chat if needed
|
|
338
|
+
// Step 5: Create new chat if needed
|
|
338
339
|
if (isNewChat) {
|
|
339
340
|
response.appendResponseLine('新規チャットを作成中...');
|
|
340
341
|
// Click "新しいチャット"
|
|
@@ -549,8 +550,26 @@ export const askChatGPTWeb = defineTool({
|
|
|
549
550
|
}
|
|
550
551
|
}
|
|
551
552
|
catch (error) {
|
|
552
|
-
const
|
|
553
|
-
|
|
553
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
554
|
+
// ケース分類:致命的エラーには明確なメッセージを表示
|
|
555
|
+
if (msg.includes('No page selected') || msg.includes('page is null')) {
|
|
556
|
+
response.appendResponseLine('❌ ブラウザタブがありません');
|
|
557
|
+
response.appendResponseLine('→ MCPサーバーを再起動してブラウザを開いてください');
|
|
558
|
+
}
|
|
559
|
+
else if (msg.includes('Target closed') ||
|
|
560
|
+
msg.includes('Session closed') ||
|
|
561
|
+
msg.includes('Connection closed')) {
|
|
562
|
+
response.appendResponseLine('❌ ブラウザ接続が切れました');
|
|
563
|
+
response.appendResponseLine('→ MCPサーバーを再起動してください');
|
|
564
|
+
}
|
|
565
|
+
else if (msg.includes('Protocol error') ||
|
|
566
|
+
msg.includes('Browser disconnected')) {
|
|
567
|
+
response.appendResponseLine('❌ ブラウザとの通信エラー');
|
|
568
|
+
response.appendResponseLine('→ MCPサーバーを再起動してください');
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
response.appendResponseLine(`❌ エラー: ${msg}`);
|
|
572
|
+
}
|
|
554
573
|
}
|
|
555
574
|
},
|
|
556
575
|
});
|
|
@@ -304,6 +304,10 @@ export const askGeminiWeb = defineTool({
|
|
|
304
304
|
return;
|
|
305
305
|
}
|
|
306
306
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
307
|
+
// 質問送信前に model-response 要素数を記録(ChatGPTと同じカウント方式)
|
|
308
|
+
const initialModelResponseCount = await page.evaluate(() => {
|
|
309
|
+
return document.querySelectorAll('model-response').length;
|
|
310
|
+
});
|
|
307
311
|
// Click send button - look for "プロンプトを送信" or similar
|
|
308
312
|
const sent = await page.evaluate(() => {
|
|
309
313
|
const buttons = Array.from(document.querySelectorAll('button'));
|
|
@@ -405,9 +409,17 @@ export const askGeminiWeb = defineTool({
|
|
|
405
409
|
});
|
|
406
410
|
return !!stopButton;
|
|
407
411
|
});
|
|
408
|
-
// Stop button/icon disappeared =
|
|
412
|
+
// Stop button/icon disappeared = check if new message appeared
|
|
409
413
|
if (!hasStopIndicator) {
|
|
410
|
-
|
|
414
|
+
// 追加: model-response 要素数が増えたか確認(ChatGPTと同じ方式)
|
|
415
|
+
const currentModelResponseCount = await page.evaluate(() => {
|
|
416
|
+
return document.querySelectorAll('model-response').length;
|
|
417
|
+
});
|
|
418
|
+
if (currentModelResponseCount > initialModelResponseCount) {
|
|
419
|
+
// ストップボタン消滅 AND 新規メッセージ出現で完了
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
// メッセージ数が増えていなければ、まだ待機続行
|
|
411
423
|
}
|
|
412
424
|
if (Date.now() - startTime > 180000) {
|
|
413
425
|
// 3 mins timeout
|
|
@@ -415,19 +427,24 @@ export const askGeminiWeb = defineTool({
|
|
|
415
427
|
break;
|
|
416
428
|
}
|
|
417
429
|
}
|
|
418
|
-
// Get the final response content
|
|
419
|
-
const responseText = await page.evaluate(
|
|
430
|
+
// Get the final response content (新規に追加された model-response のみを取得)
|
|
431
|
+
const responseText = await page.evaluate(initialCount => {
|
|
420
432
|
// Get content from model-response elements
|
|
421
433
|
const modelResponses = Array.from(document.querySelectorAll('model-response'));
|
|
434
|
+
if (modelResponses.length > initialCount) {
|
|
435
|
+
// 新規に追加された model-response を取得(ChatGPTと同じ方式)
|
|
436
|
+
const newResponse = modelResponses[initialCount];
|
|
437
|
+
return newResponse.textContent?.trim() || '';
|
|
438
|
+
}
|
|
439
|
+
// Fallback: get the last model response if any
|
|
422
440
|
if (modelResponses.length > 0) {
|
|
423
|
-
// Get the last model response
|
|
424
441
|
const lastResponse = modelResponses[modelResponses.length - 1];
|
|
425
442
|
return lastResponse.textContent?.trim() || '';
|
|
426
443
|
}
|
|
427
444
|
// Fallback: get text from main area
|
|
428
445
|
const main = document.querySelector('main');
|
|
429
446
|
return main?.innerText.slice(-5000) || '';
|
|
430
|
-
});
|
|
447
|
+
}, initialModelResponseCount);
|
|
431
448
|
response.appendResponseLine('✅ 回答完了');
|
|
432
449
|
// Always save/update session (not just for new chats)
|
|
433
450
|
const chatUrl = page.url();
|
|
@@ -468,23 +485,50 @@ export const askGeminiWeb = defineTool({
|
|
|
468
485
|
response.appendResponseLine(`📝 会話ログ保存: ${logPath}`);
|
|
469
486
|
}
|
|
470
487
|
catch (error) {
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
await fs.promises.writeFile(htmlPath, html, 'utf-8');
|
|
484
|
-
response.appendResponseLine(`📄 エラー時のHTML: ${htmlPath}`);
|
|
488
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
489
|
+
// ケース分類:致命的エラーには明確なメッセージを表示
|
|
490
|
+
const isFatalError = msg.includes('No page selected') ||
|
|
491
|
+
msg.includes('page is null') ||
|
|
492
|
+
msg.includes('Target closed') ||
|
|
493
|
+
msg.includes('Session closed') ||
|
|
494
|
+
msg.includes('Connection closed') ||
|
|
495
|
+
msg.includes('Protocol error') ||
|
|
496
|
+
msg.includes('Browser disconnected');
|
|
497
|
+
if (msg.includes('No page selected') || msg.includes('page is null')) {
|
|
498
|
+
response.appendResponseLine('❌ ブラウザタブがありません');
|
|
499
|
+
response.appendResponseLine('→ MCPサーバーを再起動してブラウザを開いてください');
|
|
485
500
|
}
|
|
486
|
-
|
|
487
|
-
|
|
501
|
+
else if (msg.includes('Target closed') ||
|
|
502
|
+
msg.includes('Session closed') ||
|
|
503
|
+
msg.includes('Connection closed')) {
|
|
504
|
+
response.appendResponseLine('❌ ブラウザ接続が切れました');
|
|
505
|
+
response.appendResponseLine('→ MCPサーバーを再起動してください');
|
|
506
|
+
}
|
|
507
|
+
else if (msg.includes('Protocol error') ||
|
|
508
|
+
msg.includes('Browser disconnected')) {
|
|
509
|
+
response.appendResponseLine('❌ ブラウザとの通信エラー');
|
|
510
|
+
response.appendResponseLine('→ MCPサーバーを再起動してください');
|
|
511
|
+
}
|
|
512
|
+
else {
|
|
513
|
+
response.appendResponseLine(`❌ エラー: ${msg}`);
|
|
514
|
+
}
|
|
515
|
+
// Error snapshot(致命的エラーの場合はスキップ)
|
|
516
|
+
if (!isFatalError) {
|
|
517
|
+
try {
|
|
518
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
519
|
+
const debugDir = path.join(process.cwd(), 'docs/ask/gemini/debug');
|
|
520
|
+
await fs.promises.mkdir(debugDir, { recursive: true });
|
|
521
|
+
const screenshotPath = path.join(debugDir, `error-${timestamp}.png`);
|
|
522
|
+
await page.screenshot({ path: screenshotPath });
|
|
523
|
+
response.appendResponseLine(`📸 エラー時のスクリーンショット: ${screenshotPath}`);
|
|
524
|
+
const htmlPath = path.join(debugDir, `error-${timestamp}.html`);
|
|
525
|
+
const html = await page.content();
|
|
526
|
+
await fs.promises.writeFile(htmlPath, html, 'utf-8');
|
|
527
|
+
response.appendResponseLine(`📄 エラー時のHTML: ${htmlPath}`);
|
|
528
|
+
}
|
|
529
|
+
catch (snapshotError) {
|
|
530
|
+
console.error('Failed to capture error snapshot:', snapshotError);
|
|
531
|
+
}
|
|
488
532
|
}
|
|
489
533
|
}
|
|
490
534
|
},
|
package/build/src/tools/pages.js
CHANGED
|
@@ -129,7 +129,6 @@ export const resizePage = defineTool({
|
|
|
129
129
|
},
|
|
130
130
|
handler: async (request, response, context) => {
|
|
131
131
|
const page = context.getSelectedPage();
|
|
132
|
-
// @ts-expect-error internal API for now.
|
|
133
132
|
await page.resize({
|
|
134
133
|
contentWidth: request.params.width,
|
|
135
134
|
contentHeight: request.params.height,
|
package/package.json
CHANGED