Skip to content

feat(agent): add silent scheduled task runs#983

Closed
Nikhil (shadowfax92) wants to merge 1 commit into
devfrom
polecat/ruby/bosmain-445@moxnmc0t
Closed

feat(agent): add silent scheduled task runs#983
Nikhil (shadowfax92) wants to merge 1 commit into
devfrom
polecat/ruby/bosmain-445@moxnmc0t

Conversation

@shadowfax92
Copy link
Copy Markdown
Contributor

Fixes #447

Verification:

  • Passed: bun test apps/agent/lib/messaging/server/buildChatRequestBody.test.ts
  • Passed: bun run test:cleanup && bun --env-file=.env.development test ./tests/agent/prompt.test.ts ./tests/api/services/chat-service.test.ts ./tests/browser/browser.test.ts
  • Passed: bunx biome check on changed files
  • Passed: git diff --check origin/dev...HEAD
  • Local blocked: server bun run typecheck cannot find tsc; tracked as bosmain-woi.
  • Local blocked: agent bun run typecheck cannot find wxt; tracked as bosmain-090.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 9, 2026

✅ Tests passed — 1223/1227

Suite Passed Failed Skipped
agent 81/81 0 0
build 9/9 0 0
eval 93/93 0 0
server-agent 262/262 0 0
server-api 204/204 0 0
server-browser 1/1 0 0
server-integration 9/10 0 1
server-lib 242/242 0 0
server-root 60/63 0 3
server-skills 31/31 0 0
server-tools 231/231 0 0

View workflow run

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 9, 2026

Greptile Summary

This PR adds a "Run silently" toggle to scheduled tasks, letting users opt into a visible browser run instead of the existing hidden-page background mode. It also refactors Browser.newPage to pass hidden directly to the CDP createTab call, removing the intermediate hidden-window creation step.

  • UI & type changes: ScheduledJob gains an optional runSilently field (default true); the task dialog exposes a checkbox and the task card shows "Silent run" / "Visible run".
  • Server-side routing: chat-service.ts skips hidden-page setup when runSilently is false, and the system prompt omits hidden-page constraints for visible runs.
  • browser.ts simplification: resolveWindowIdForNewPage is removed; hidden is forwarded directly to createTab, verified by a new unit test.

Confidence Score: 3/5

The core silent/visible routing logic is sound, but the sync path will silently overwrite a user's visible-run preference on any remote update.

The remoteToLocal function always hardcodes runSilently: true when updating a local job from the backend. Because runSilently is intentionally kept out of the remote schema and comparison fields, there is no mechanism to preserve a user's "Visible run" choice across a remote sync. Any time the backend timestamp is newer than the local copy the preference is overwritten without any indication to the user.

packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts — specifically the remoteToLocal function and the update-from-remote path.

Important Files Changed

Filename Overview
packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts Adds runSilently to IGNORED_FIELDS (correct, not in remote schema) but remoteToLocal always hardcodes runSilently: true, causing the user's "Visible run" preference to be overwritten whenever a remote sync updates the local job.
packages/browseros-agent/apps/server/src/browser/browser.ts Removes resolveWindowIdForNewPage helper and passes hidden directly to cdp.Browser.createTab, simplifying hidden-page creation and eliminating the intermediate hidden-window step. Covered by a new integration test.
packages/browseros-agent/apps/server/src/api/services/chat-service.ts Hidden-page creation gated on runSilently !== false; visible-mode path reuses the provided browser context. New test covers both branches.
packages/browseros-agent/apps/server/src/agent/prompt.ts System-prompt instructions for scheduled tasks now branch on scheduledTaskRunSilently, omitting hidden-page constraints for visible runs and substituting visible-browsing guidance. Tests verify both prompt branches.
packages/browseros-agent/apps/agent/entrypoints/app/scheduled-tasks/NewScheduledTaskDialog.tsx Adds runSilently checkbox field (default true) to the form schema and UI; existing tasks default via ?? true.
packages/browseros-agent/apps/agent/lib/schedules/scheduleTypes.ts Adds optional runSilently?: boolean to ScheduledJob interface.
packages/browseros-agent/apps/server/tests/browser/browser.test.ts New test confirming createTab receives hidden: true and createWindow is never called for hidden-page creation.

Sequence Diagram

sequenceDiagram
    participant UI as NewScheduledTaskDialog
    participant Storage as scheduledJobStorage
    participant Runner as scheduledJobRuns
    participant CS as ChatService
    participant Browser as Browser.newPage
    participant Server as AiSdkAgent / prompt.ts

    UI->>Storage: save job (runSilently: true/false)
    Runner->>Storage: read job on alarm fire
    Runner->>CS: "getChatServerResponse({ runSilently })"
    CS->>CS: "isScheduledTask && runSilently !== false?"
    alt "Silent run (runSilently = true)"
        CS->>Browser: newPage about:blank hidden:true
        Browser->>Browser: cdp.Browser.createTab hidden:true
        CS->>Server: buildSystemPrompt scheduledTaskRunSilently:true
        Note over Server: Hidden-page constraints in prompt
    else "Visible run (runSilently = false)"
        CS->>CS: use provided browserContext as-is
        CS->>Server: buildSystemPrompt scheduledTaskRunSilently:false
        Note over Server: Visible-browsing guidance in prompt
    end
Loading

Comments Outside Diff (1)

  1. packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts, line 139-145 (link)

    P1 runSilently preference silently reset on every remote sync

    remoteToLocal always hardcodes runSilently: true (line 66). When the backend has a newer updatedAt than the local copy — a normal occurrence after any remote write — the code calls remoteToLocal and overwrites the full local record, wiping any user-set runSilently: false preference. Because runSilently is in IGNORED_FIELDS, the comparison at line 186 never detects the drift, so the preference is irreversibly lost. A user who changes a task from "Silent run" to "Visible run" and then triggers a sync (login on another device, app restart, any remote edit) will silently revert to silent mode.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts
    Line: 139-145
    
    Comment:
    **`runSilently` preference silently reset on every remote sync**
    
    `remoteToLocal` always hardcodes `runSilently: true` (line 66). When the backend has a newer `updatedAt` than the local copy — a normal occurrence after any remote write — the code calls `remoteToLocal` and overwrites the full local record, wiping any user-set `runSilently: false` preference. Because `runSilently` is in `IGNORED_FIELDS`, the comparison at line 186 never detects the drift, so the preference is irreversibly lost. A user who changes a task from "Silent run" to "Visible run" and then triggers a sync (login on another device, app restart, any remote edit) will silently revert to silent mode.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/browseros-agent/apps/agent/lib/schedules/syncSchedulesToBackend.ts:139-145
**`runSilently` preference silently reset on every remote sync**

`remoteToLocal` always hardcodes `runSilently: true` (line 66). When the backend has a newer `updatedAt` than the local copy — a normal occurrence after any remote write — the code calls `remoteToLocal` and overwrites the full local record, wiping any user-set `runSilently: false` preference. Because `runSilently` is in `IGNORED_FIELDS`, the comparison at line 186 never detects the drift, so the preference is irreversibly lost. A user who changes a task from "Silent run" to "Visible run" and then triggers a sync (login on another device, app restart, any remote edit) will silently revert to silent mode.

Reviews (1): Last reviewed commit: "feat: add silent scheduled task runs (bo..." | Re-trigger Greptile

@shadowfax92
Copy link
Copy Markdown
Contributor Author

Refinery rejected this merge request after CI gate. GitHub Tests / server-browser failed because the new tests/browser/browser.test.ts mocks @browseros/shared/constants/limits with only CONTENT_LIMITS, causing tests/browser/backends/cdp.test.ts to fail importing CDP_LIMITS from the mocked module. Source issue bosmain-445 has been reopened for rework; this branch is not merged.

@shadowfax92 Nikhil (shadowfax92) deleted the polecat/ruby/bosmain-445@moxnmc0t branch May 9, 2026 01:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Option for Scheduled Tasks to Run Silently (No New Window Popup)

1 participant