feature/gemini-web-provider #1
|
|
@ -132,10 +132,15 @@ func (p *PlaywrightProvider) Generate(ctx context.Context, model string, message
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("failed to navigate: %w", err)
|
return fmt.Errorf("failed to navigate: %w", err)
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 檢查登入狀態
|
// 3. 等待頁面完全載入(project-golem 策略)
|
||||||
|
fmt.Println("[GeminiWeb] Waiting for page to be ready...")
|
||||||
|
if err := p.waitForPageReady(); err != nil {
|
||||||
|
fmt.Printf("[GeminiWeb] Warning: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 檢查登入狀態
|
||||||
fmt.Println("[GeminiWeb] Checking login status...")
|
fmt.Println("[GeminiWeb] Checking login status...")
|
||||||
loggedIn := p.isLoggedIn()
|
loggedIn := p.isLoggedIn()
|
||||||
if !loggedIn {
|
if !loggedIn {
|
||||||
|
|
@ -151,11 +156,6 @@ func (p *PlaywrightProvider) Generate(ctx context.Context, model string, message
|
||||||
fmt.Println("[GeminiWeb] Logged in")
|
fmt.Println("[GeminiWeb] Logged in")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 等待頁面就緒
|
|
||||||
if err := p.waitForReady(); err != nil {
|
|
||||||
fmt.Printf("[GeminiWeb] Warning: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 建構提示詞
|
// 5. 建構提示詞
|
||||||
prompt := buildPromptFromMessagesPlaywright(messages)
|
prompt := buildPromptFromMessagesPlaywright(messages)
|
||||||
fmt.Printf("[GeminiWeb] Typing prompt (%d chars)...\n", len(prompt))
|
fmt.Printf("[GeminiWeb] Typing prompt (%d chars)...\n", len(prompt))
|
||||||
|
|
@ -201,6 +201,58 @@ func (p *PlaywrightProvider) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// waitForPageReady 等待頁面完全就緒(project-golem 策略)
|
||||||
|
func (p *PlaywrightProvider) waitForPageReady() error {
|
||||||
|
fmt.Println("[GeminiWeb] Checking for ready state...")
|
||||||
|
|
||||||
|
// 1. 等待停止按鈕消失(如果存在)
|
||||||
|
_, _ = p.page.WaitForSelector("button[aria-label*='Stop'], button[aria-label*='停止']", playwright.PageWaitForSelectorOptions{
|
||||||
|
State: playwright.WaitForSelectorStateDetached,
|
||||||
|
Timeout: playwright.Float(5000),
|
||||||
|
})
|
||||||
|
|
||||||
|
// 2. 等待輸入框出現(關鍵!)
|
||||||
|
inputSelectors := []string{
|
||||||
|
".ProseMirror",
|
||||||
|
"rich-textarea",
|
||||||
|
"div[role='textbox']",
|
||||||
|
"div[contenteditable='true']",
|
||||||
|
"textarea",
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastErr error
|
||||||
|
for _, sel := range inputSelectors {
|
||||||
|
fmt.Printf(" Checking for: %s\n", sel)
|
||||||
|
locator := p.page.Locator(sel)
|
||||||
|
if err := locator.WaitFor(playwright.LocatorWaitForOptions{
|
||||||
|
Timeout: playwright.Float(10000),
|
||||||
|
State: playwright.WaitForSelectorStateVisible,
|
||||||
|
}); err == nil {
|
||||||
|
fmt.Printf(" ✓ Input field found: %s\n", sel)
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
lastErr = err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 如果都找不到,給頁面更多時間
|
||||||
|
fmt.Println("[GeminiWeb] Input not found immediately, waiting longer...")
|
||||||
|
time.Sleep(3 * time.Second)
|
||||||
|
|
||||||
|
for _, sel := range inputSelectors {
|
||||||
|
locator := p.page.Locator(sel)
|
||||||
|
if err := locator.WaitFor(playwright.LocatorWaitForOptions{
|
||||||
|
Timeout: playwright.Float(5000),
|
||||||
|
State: playwright.WaitForSelectorStateVisible,
|
||||||
|
}); err == nil {
|
||||||
|
fmt.Printf(" ✓ Input field found after wait: %s\n", sel)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("input field not ready: %w", lastErr)
|
||||||
|
}
|
||||||
|
|
||||||
// isLoggedIn 檢查是否已登入
|
// isLoggedIn 檢查是否已登入
|
||||||
func (p *PlaywrightProvider) isLoggedIn() bool {
|
func (p *PlaywrightProvider) isLoggedIn() bool {
|
||||||
// 嘗試找輸入框(登入狀態的主要特徵)
|
// 嘗試找輸入框(登入狀態的主要特徵)
|
||||||
|
|
@ -213,29 +265,14 @@ func (p *PlaywrightProvider) isLoggedIn() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sel := range selectors {
|
for _, sel := range selectors {
|
||||||
if _, err := p.page.WaitForSelector(sel, playwright.PageWaitForSelectorOptions{
|
locator := p.page.Locator(sel)
|
||||||
Timeout: playwright.Float(3000),
|
if count, _ := locator.Count(); count > 0 {
|
||||||
}); err == nil {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForReady 等待頁面就緒
|
|
||||||
func (p *PlaywrightProvider) waitForReady() error {
|
|
||||||
fmt.Println("[GeminiWeb] Checking if page is ready...")
|
|
||||||
|
|
||||||
// 等待停止按鈕消失(如果存在)
|
|
||||||
_, _ = p.page.WaitForSelector("button[aria-label*='Stop']", playwright.PageWaitForSelectorOptions{
|
|
||||||
State: playwright.WaitForSelectorStateDetached,
|
|
||||||
Timeout: playwright.Float(5000),
|
|
||||||
})
|
|
||||||
|
|
||||||
fmt.Println("[GeminiWeb] Page is ready")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// typeInput 輸入文字(使用 Playwright 的 Auto-wait)
|
// typeInput 輸入文字(使用 Playwright 的 Auto-wait)
|
||||||
func (p *PlaywrightProvider) typeInput(text string) error {
|
func (p *PlaywrightProvider) typeInput(text string) error {
|
||||||
fmt.Println("[GeminiWeb] Looking for input field...")
|
fmt.Println("[GeminiWeb] Looking for input field...")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue