feat(ext): add agent heart beat check
This commit is contained in:
@@ -5,12 +5,26 @@ import { TabsController } from './TabsController'
|
||||
import SYSTEM_PROMPT from './system_prompt.md?raw'
|
||||
import { createTabTools } from './tabTools'
|
||||
|
||||
/**
|
||||
* MultiPageAgent
|
||||
* - use with extension
|
||||
* - can be used from a side panel or a content script
|
||||
*/
|
||||
export class MultiPageAgent extends PageAgentCore {
|
||||
constructor(config: Omit<PageAgentConfig, 'pageController'>) {
|
||||
const tabsController = new TabsController()
|
||||
const pageController = new RemotePageController(tabsController)
|
||||
const customTools = createTabTools(tabsController)
|
||||
|
||||
/**
|
||||
* When the agent is in side-panel and user closed the side-panel.
|
||||
* There is no chance for isAgentRunning to be set false.
|
||||
* (unload event doesn't work well in side panel.)
|
||||
* (I'm trying not to use long-lived connection because the lifecycle of a sw is hard to predict.)
|
||||
* This heartbeat mechanism acts as a backup.
|
||||
*/
|
||||
let heartBeatInterval: null | number = null
|
||||
|
||||
super({
|
||||
...config,
|
||||
pageController: pageController as any,
|
||||
@@ -20,18 +34,34 @@ export class MultiPageAgent extends PageAgentCore {
|
||||
onBeforeTask: async (agent) => {
|
||||
await tabsController.init(agent.task)
|
||||
|
||||
heartBeatInterval = window.setInterval(() => {
|
||||
chrome.storage.local.set({
|
||||
agentHeartbeat: Date.now(),
|
||||
})
|
||||
}, 1_000)
|
||||
|
||||
await chrome.storage.local.set({
|
||||
isAgentRunning: true,
|
||||
})
|
||||
},
|
||||
|
||||
onAfterTask: async () => {
|
||||
if (heartBeatInterval) {
|
||||
window.clearInterval(heartBeatInterval)
|
||||
heartBeatInterval = null
|
||||
}
|
||||
|
||||
await chrome.storage.local.set({
|
||||
isAgentRunning: false,
|
||||
})
|
||||
},
|
||||
|
||||
onDispose: () => {
|
||||
if (heartBeatInterval) {
|
||||
window.clearInterval(heartBeatInterval)
|
||||
heartBeatInterval = null
|
||||
}
|
||||
|
||||
chrome.storage.local.set({
|
||||
isAgentRunning: false,
|
||||
})
|
||||
|
||||
@@ -21,17 +21,14 @@ export function initPageController() {
|
||||
}
|
||||
|
||||
intervalID = window.setInterval(async () => {
|
||||
const agentHeartbeat = (await chrome.storage.local.get('agentHeartbeat')).agentHeartbeat
|
||||
const now = Date.now()
|
||||
const agentInTouch = typeof agentHeartbeat === 'number' && now - agentHeartbeat < 2_000
|
||||
|
||||
const isAgentRunning = (await chrome.storage.local.get('isAgentRunning')).isAgentRunning
|
||||
const currentTabId = (await chrome.storage.local.get('currentTabId')).currentTabId
|
||||
|
||||
const shouldShowMask = isAgentRunning && currentTabId === (await myTabIdPromise)
|
||||
|
||||
// console.log('[RemotePageController] polling:', {
|
||||
// isAgentRunning,
|
||||
// currentTabId,
|
||||
// myTabId: await myTabIdPromise,
|
||||
// shouldShowMask,
|
||||
// })
|
||||
const shouldShowMask = isAgentRunning && agentInTouch && currentTabId === (await myTabIdPromise)
|
||||
|
||||
if (shouldShowMask) {
|
||||
const pc = getPC()
|
||||
@@ -45,13 +42,13 @@ export function initPageController() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAgentRunning) {
|
||||
if (!isAgentRunning && agentInTouch) {
|
||||
if (pageController) {
|
||||
pageController.dispose()
|
||||
pageController = null
|
||||
}
|
||||
}
|
||||
}, 1_000)
|
||||
}, 500)
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse): true | undefined => {
|
||||
if (message.type !== 'PAGE_CONTROL') {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { handlePageControlMessage } from '@/agent/RemotePageController.background'
|
||||
import { handleTabControlMessage } from '@/agent/TabsController.background'
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse): true | undefined => {
|
||||
if (message.type === 'TAB_CONTROL') {
|
||||
return handleTabControlMessage(message, sender, sendResponse)
|
||||
} else if (message.type === 'PAGE_CONTROL') {
|
||||
|
||||
Reference in New Issue
Block a user