@projectservan8n/cnapse 0.6.2 → 0.6.3
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/dist/index.js +48 -8
- package/package.json +1 -1
- package/src/lib/tasks.ts +64 -10
package/dist/index.js
CHANGED
|
@@ -2671,13 +2671,15 @@ ${existingResult.output}`;
|
|
|
2671
2671
|
const [site, ...questionParts] = params.split("|");
|
|
2672
2672
|
const question = questionParts.join("|");
|
|
2673
2673
|
const sites = {
|
|
2674
|
-
perplexity: { url: "https://www.perplexity.ai",
|
|
2675
|
-
chatgpt: { url: "https://chat.openai.com",
|
|
2676
|
-
claude: { url: "https://claude.ai",
|
|
2677
|
-
google: { url: "https://www.google.com",
|
|
2678
|
-
bing: { url: "https://www.bing.com",
|
|
2674
|
+
perplexity: { url: "https://www.perplexity.ai", loadTime: 3, responseTime: 10 },
|
|
2675
|
+
chatgpt: { url: "https://chat.openai.com", loadTime: 4, responseTime: 15 },
|
|
2676
|
+
claude: { url: "https://claude.ai", loadTime: 4, responseTime: 15 },
|
|
2677
|
+
google: { url: "https://www.google.com", loadTime: 2, responseTime: 3 },
|
|
2678
|
+
bing: { url: "https://www.bing.com", loadTime: 2, responseTime: 3 },
|
|
2679
|
+
bard: { url: "https://bard.google.com", loadTime: 3, responseTime: 12 },
|
|
2680
|
+
copilot: { url: "https://copilot.microsoft.com", loadTime: 3, responseTime: 12 }
|
|
2679
2681
|
};
|
|
2680
|
-
const siteConfig = sites[site.toLowerCase()] || { url: `https://${site}`,
|
|
2682
|
+
const siteConfig = sites[site.toLowerCase()] || { url: `https://${site}`, loadTime: 3, responseTime: 10 };
|
|
2681
2683
|
if (process.platform === "win32") {
|
|
2682
2684
|
await runCommand(`start "" "${siteConfig.url}"`, 5e3);
|
|
2683
2685
|
} else if (process.platform === "darwin") {
|
|
@@ -2685,11 +2687,49 @@ ${existingResult.output}`;
|
|
|
2685
2687
|
} else {
|
|
2686
2688
|
await runCommand(`xdg-open "${siteConfig.url}"`, 5e3);
|
|
2687
2689
|
}
|
|
2688
|
-
await sleep(siteConfig.
|
|
2690
|
+
await sleep(siteConfig.loadTime * 1e3);
|
|
2689
2691
|
await typeText(question);
|
|
2690
2692
|
await sleep(300);
|
|
2691
2693
|
await pressKey("Return");
|
|
2692
|
-
|
|
2694
|
+
await sleep(siteConfig.responseTime * 1e3);
|
|
2695
|
+
const extractedParts = [];
|
|
2696
|
+
const maxScrolls = 5;
|
|
2697
|
+
for (let scrollIndex = 0; scrollIndex < maxScrolls; scrollIndex++) {
|
|
2698
|
+
const screenResult = await describeScreen();
|
|
2699
|
+
const extractPrompt = `You are looking at screenshot ${scrollIndex + 1} of ${site}. The user asked: "${question}"
|
|
2700
|
+
|
|
2701
|
+
Extract ONLY the AI's response/answer text visible on screen. Do NOT include:
|
|
2702
|
+
- The user's question
|
|
2703
|
+
- Any UI elements, buttons, navigation, or headers
|
|
2704
|
+
- Any disclaimers, suggestions, or "related questions"
|
|
2705
|
+
- Any "Sources" or citation links
|
|
2706
|
+
- Any text you already extracted (avoid duplicates)
|
|
2707
|
+
|
|
2708
|
+
${scrollIndex > 0 ? `Previous parts already extracted:
|
|
2709
|
+
${extractedParts.join("\n---\n")}
|
|
2710
|
+
|
|
2711
|
+
Only extract NEW text that continues from where we left off.` : ""}
|
|
2712
|
+
|
|
2713
|
+
Just give me the actual answer text, word for word as it appears. If there's no more response text visible, respond with exactly: "END_OF_RESPONSE"`;
|
|
2714
|
+
const extractResponse = await chat([{ role: "user", content: extractPrompt }]);
|
|
2715
|
+
const extracted = extractResponse.content.trim();
|
|
2716
|
+
if (extracted === "END_OF_RESPONSE" || extracted.includes("END_OF_RESPONSE")) {
|
|
2717
|
+
break;
|
|
2718
|
+
}
|
|
2719
|
+
if (extracted.toLowerCase().includes("response not ready") || extracted.toLowerCase().includes("no response visible") || extracted.toLowerCase().includes("no additional text")) {
|
|
2720
|
+
if (scrollIndex === 0) {
|
|
2721
|
+
extractedParts.push("Response not ready yet or page still loading.");
|
|
2722
|
+
}
|
|
2723
|
+
break;
|
|
2724
|
+
}
|
|
2725
|
+
extractedParts.push(extracted);
|
|
2726
|
+
await scrollMouse(-5);
|
|
2727
|
+
await sleep(1e3);
|
|
2728
|
+
}
|
|
2729
|
+
const fullResponse = extractedParts.join("\n\n");
|
|
2730
|
+
step.result = `\u{1F4DD} ${site.charAt(0).toUpperCase() + site.slice(1)} says:
|
|
2731
|
+
|
|
2732
|
+
${fullResponse}`;
|
|
2693
2733
|
break;
|
|
2694
2734
|
}
|
|
2695
2735
|
case "screenshot":
|
package/package.json
CHANGED
package/src/lib/tasks.ts
CHANGED
|
@@ -557,16 +557,18 @@ ${existingResult.output}`;
|
|
|
557
557
|
const [site, ...questionParts] = params.split('|');
|
|
558
558
|
const question = questionParts.join('|');
|
|
559
559
|
|
|
560
|
-
// Site-specific URLs and
|
|
561
|
-
const sites: Record<string, { url: string;
|
|
562
|
-
perplexity: { url: 'https://www.perplexity.ai',
|
|
563
|
-
chatgpt: { url: 'https://chat.openai.com',
|
|
564
|
-
claude: { url: 'https://claude.ai',
|
|
565
|
-
google: { url: 'https://www.google.com',
|
|
566
|
-
bing: { url: 'https://www.bing.com',
|
|
560
|
+
// Site-specific URLs and response wait times
|
|
561
|
+
const sites: Record<string, { url: string; loadTime: number; responseTime: number }> = {
|
|
562
|
+
perplexity: { url: 'https://www.perplexity.ai', loadTime: 3, responseTime: 10 },
|
|
563
|
+
chatgpt: { url: 'https://chat.openai.com', loadTime: 4, responseTime: 15 },
|
|
564
|
+
claude: { url: 'https://claude.ai', loadTime: 4, responseTime: 15 },
|
|
565
|
+
google: { url: 'https://www.google.com', loadTime: 2, responseTime: 3 },
|
|
566
|
+
bing: { url: 'https://www.bing.com', loadTime: 2, responseTime: 3 },
|
|
567
|
+
bard: { url: 'https://bard.google.com', loadTime: 3, responseTime: 12 },
|
|
568
|
+
copilot: { url: 'https://copilot.microsoft.com', loadTime: 3, responseTime: 12 },
|
|
567
569
|
};
|
|
568
570
|
|
|
569
|
-
const siteConfig = sites[site.toLowerCase()] || { url: `https://${site}`,
|
|
571
|
+
const siteConfig = sites[site.toLowerCase()] || { url: `https://${site}`, loadTime: 3, responseTime: 10 };
|
|
570
572
|
|
|
571
573
|
// Open the site
|
|
572
574
|
if (process.platform === 'win32') {
|
|
@@ -578,7 +580,7 @@ ${existingResult.output}`;
|
|
|
578
580
|
}
|
|
579
581
|
|
|
580
582
|
// Wait for page to load
|
|
581
|
-
await sleep(siteConfig.
|
|
583
|
+
await sleep(siteConfig.loadTime * 1000);
|
|
582
584
|
|
|
583
585
|
// Type the question (most sites have autofocus on search/input)
|
|
584
586
|
await computer.typeText(question);
|
|
@@ -587,7 +589,59 @@ ${existingResult.output}`;
|
|
|
587
589
|
// Press Enter to submit
|
|
588
590
|
await computer.pressKey('Return');
|
|
589
591
|
|
|
590
|
-
|
|
592
|
+
// Wait for AI to generate response
|
|
593
|
+
await sleep(siteConfig.responseTime * 1000);
|
|
594
|
+
|
|
595
|
+
// Capture multiple screenshots by scrolling to get full response
|
|
596
|
+
const extractedParts: string[] = [];
|
|
597
|
+
const maxScrolls = 5; // Maximum number of scroll captures
|
|
598
|
+
|
|
599
|
+
for (let scrollIndex = 0; scrollIndex < maxScrolls; scrollIndex++) {
|
|
600
|
+
// Capture current view
|
|
601
|
+
const screenResult = await describeScreen();
|
|
602
|
+
|
|
603
|
+
// Ask AI to extract just the response text from what it sees
|
|
604
|
+
const extractPrompt = `You are looking at screenshot ${scrollIndex + 1} of ${site}. The user asked: "${question}"
|
|
605
|
+
|
|
606
|
+
Extract ONLY the AI's response/answer text visible on screen. Do NOT include:
|
|
607
|
+
- The user's question
|
|
608
|
+
- Any UI elements, buttons, navigation, or headers
|
|
609
|
+
- Any disclaimers, suggestions, or "related questions"
|
|
610
|
+
- Any "Sources" or citation links
|
|
611
|
+
- Any text you already extracted (avoid duplicates)
|
|
612
|
+
|
|
613
|
+
${scrollIndex > 0 ? `Previous parts already extracted:\n${extractedParts.join('\n---\n')}\n\nOnly extract NEW text that continues from where we left off.` : ''}
|
|
614
|
+
|
|
615
|
+
Just give me the actual answer text, word for word as it appears. If there's no more response text visible, respond with exactly: "END_OF_RESPONSE"`;
|
|
616
|
+
|
|
617
|
+
const extractResponse = await chat([{ role: 'user', content: extractPrompt }]);
|
|
618
|
+
const extracted = extractResponse.content.trim();
|
|
619
|
+
|
|
620
|
+
// Check if we've reached the end
|
|
621
|
+
if (extracted === 'END_OF_RESPONSE' || extracted.includes('END_OF_RESPONSE')) {
|
|
622
|
+
break;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Check for "no response" indicators
|
|
626
|
+
if (extracted.toLowerCase().includes('response not ready') ||
|
|
627
|
+
extracted.toLowerCase().includes('no response visible') ||
|
|
628
|
+
extracted.toLowerCase().includes('no additional text')) {
|
|
629
|
+
if (scrollIndex === 0) {
|
|
630
|
+
extractedParts.push('Response not ready yet or page still loading.');
|
|
631
|
+
}
|
|
632
|
+
break;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
extractedParts.push(extracted);
|
|
636
|
+
|
|
637
|
+
// Scroll down to see more content
|
|
638
|
+
await computer.scrollMouse(-5); // Scroll down
|
|
639
|
+
await sleep(1000); // Wait for scroll animation
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Combine all extracted parts
|
|
643
|
+
const fullResponse = extractedParts.join('\n\n');
|
|
644
|
+
step.result = `📝 ${site.charAt(0).toUpperCase() + site.slice(1)} says:\n\n${fullResponse}`;
|
|
591
645
|
break;
|
|
592
646
|
}
|
|
593
647
|
|