ai-helper-agent 1.15.3 → 1.15.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.
@@ -13,13 +13,13 @@ ${e.map(e=>{let t=e.function.parameters?.properties,n=t?Object.keys(t).slice(0,3
13
13
 
14
14
  Output in JSON format:
15
15
  - For direct answers: {"type": "answer", "data": "your answer text"}
16
- - When tools are needed: {"type": "tools", "data": ["tool_name_1", "tool_name_2"]}`}function ht(e){if(!e||typeof e!=`string`)return null;let t=e.trim();try{let e=JSON.parse(t);if(e&&typeof e==`object`&&e.type&&`data`in e){if(e.type===`answer`&&typeof e.data==`string`)return{type:`answer`,content:e.data};if(e.type===`tools`&&Array.isArray(e.data))return{type:`tools`,tools:e.data}}}catch{}let n=gt(t);return n?{type:`tools`,tools:n}:null}function gt(e){if(!e||typeof e!=`string`)return null;let t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);if(t){let e=_t(t[1].trim());if(e)return r.debug(`[ToolPreselector] from code blockmentionedfetch JSON successful`),e}let n=e.indexOf(`[`);if(n!==-1){let t=0,i=-1;for(let r=n;r<e.length;r++)if(e[r]===`[`&&t++,e[r]===`]`&&(t--,t===0)){i=r;break}if(i!==-1){let t=_t(e.substring(n,i+1));if(t)return r.debug(`[ToolPreselector] from textmentionedfetch JSON group successful`),t}}let i=e.match(/\[[\s\S]*?\]/g);if(i)for(let e of i){let t=_t(e);if(t)return r.debug(`[ToolPreselector] via regexmentionedfetch JSON group successful`),t}return null}function _t(e){if(!e||typeof e!=`string`)return null;let t=e.trim();try{let e=JSON.parse(t);if(Array.isArray(e))return e}catch{}try{let e=t.replace(/,\s*\]/g,`]`),n=JSON.parse(e);if(Array.isArray(n))return n}catch{}try{let e=t.replace(/\[([\s\S]*)\]/g,(e,t)=>`[${t.split(`,`).map(e=>{let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t:`"${t}"`}).join(`, `)}]`),n=JSON.parse(e);if(Array.isArray(n))return n}catch{}return null}async function vt(e,n,i,a={},o=1){let s=i.length,c=crypto.randomUUID(),l=new Date().toISOString(),u=(e,n={})=>({id:c,iteration:0,timestamp:l,nodeType:`preselect`,nodeName:t(`preselector.nodeName`),...n,status:e}),d=await z(),f=d.reactConfig?.preselectMinToolCount??3;if(s<=f)return r.debug(`[ToolPreselector] tool count count ${s} <= ${f},skip pre-filter`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`skip`,params:{reason:t(`preselector.reasonFewTools`),toolCount:s}},duration:1})]};let p=ft(e);if(!p)return r.warn(`[ToolPreselector] cannot extractuseraskquestion,using alltool`),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:t(`preselector.reasonExtractFailed`)})]};let m=pt(e),h=mt(i);r.debug(`[ToolPreselector] start pre-filter,full count tool: ${s} ,with historymessage: ${m.length} `);let g=Date.now();try{let e=d,a=`${e.apiBase}/chat/completions`,o=[{role:`system`,content:h},...m,{role:`user`,content:`User question: ${p}`}],c={model:n||e.modelName,messages:o,stream:!1,temperature:.1,max_tokens:Math.min(4096,Math.max(1024,s*30)),response_format:{type:`json_object`}},l=await dr(a,{method:`POST`,headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(c)},e.reactConfig.apiTimeout,e.reactConfig.apiRetryCount,e.reactConfig.apiRetryBaseDelay),f=Date.now()-g;if(!l.ok)return r.warn(`[ToolPreselector] API request failed,using alltool`),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:t(`preselector.reasonApiFailed`,{status:l.status}),duration:f})]};let _=((await l.json()).choices?.[0]?.message?.content||``).trim();r.debug(`[ToolPreselector] largemodelreturn:`,_);let v=ht(_);if(v){if(v.type===`answer`)return r.debug(`[ToolPreselector] modeldirect answer (newformat),no secondarycall with `),{type:`answer`,content:v.content,executionLog:[u(`success`,{thought:v.content,duration:f})]};let e=v.tools;if(e.length===0)return r.warn(`[ToolPreselector] returned empty toolgroup,using alltool`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`all_tools`,params:{reason:t(`preselector.reasonEmptyResult`)}},duration:f})]};let n=new Set(e.map(e=>String(e).toLowerCase())),a=i.filter(e=>n.has(e.function.name.toLowerCase()));if(p.includes(`proto_`)){for(let e of[`preview_ui`])if(!a.some(t=>t.function.name===e)){let t=i.find(t=>t.function.name===e);t&&(a.push(t),r.debug(`[ToolPreselector] fallback appendprototypetool: ${e}`))}}return a.length===0?(r.warn(`[ToolPreselector] filter after toolempty,using alltool`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`all_tools`,params:{reason:t(`preselector.reasonNoMatch`)}},duration:f})]}):(r.debug(`[ToolPreselector] pre-filter complete: ${s} → ${a.length} tool`,a.map(e=>e.function.name)),{type:`tools`,tools:a,executionLog:[u(`success`,{action:{name:`preselect`,params:{selected:a.map(e=>e.function.name)}},apiRequest:{model:c.model,messageCount:o.length,toolCount:s},apiResponse:{toolCountAfter:a.length},duration:f})]})}return r.debug(`[ToolPreselector] modeldirect answer,no secondarycall with `),{type:`answer`,content:_,executionLog:[u(`success`,{thought:_,duration:f})]}}catch(e){let t=Date.now()-g;return r.warn(`[ToolPreselector] pre-filter exception,using alltool:`,e.message),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:e.message,duration:t})]}}}async function yt({sessionId:e,model:t,usage:n,callType:i}){if(!n||!n.prompt_tokens&&!n.total_tokens)return;let a=x(t);try{await N({sessionId:e||`unknown`,model:t||`unknown`,promptTokens:n.prompt_tokens||0,completionTokens:n.completion_tokens||0,totalTokens:n.total_tokens||0,contextWindow:a,callType:i||`unknown`})}catch(e){r.warn(`[TokenRecorder] record token stats failed:`,e.message)}}var bt=200,xt=500,St=150;function Ct(e){if(!e||typeof e!=`object`||Object.keys(e).length===0)return``;let t=Object.keys(e);if(t.length===0)return``;let n=[`path`,`query`,`url`,`command`,`name`,`pattern`,`filePath`,`content`],r=t.filter(e=>n.includes(e)).slice(0,2);if(r.length===0){let n=t.find(t=>e[t]!=null&&e[t]!==``);if(!n)return``;r.push(n)}return r.map(t=>`${t}=${(typeof e[t]==`string`?e[t]:JSON.stringify(e[t])).substring(0,St)}`).join(`, `)}async function wt(e,t,n,i={}){if(!e||e.length<2)return r.debug(`[ContextSummarizer] round timesmessage not sufficient,skip summary`),null;let a=e.find(e=>e.role===`assistant`&&e.tool_calls);if(!a)return r.debug(`[ContextSummarizer] not found assistant(tool_calls),skip summary`),null;let o=`Summarize the execution of the following tool calls in one sentence, extracting key findings:
16
+ - When tools are needed: {"type": "tools", "data": ["tool_name_1", "tool_name_2"]}`}function ht(e){if(!e||typeof e!=`string`)return null;let t=e.trim();try{let e=JSON.parse(t);if(e&&typeof e==`object`&&e.type&&`data`in e){if(e.type===`answer`&&typeof e.data==`string`)return{type:`answer`,content:e.data};if(e.type===`tools`&&Array.isArray(e.data))return{type:`tools`,tools:e.data}}}catch{}let n=gt(t);return n?{type:`tools`,tools:n}:null}function gt(e){if(!e||typeof e!=`string`)return null;let t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);if(t){let e=_t(t[1].trim());if(e)return r.debug(`[ToolPreselector] from code blockmentionedfetch JSON successful`),e}let n=e.indexOf(`[`);if(n!==-1){let t=0,i=-1;for(let r=n;r<e.length;r++)if(e[r]===`[`&&t++,e[r]===`]`&&(t--,t===0)){i=r;break}if(i!==-1){let t=_t(e.substring(n,i+1));if(t)return r.debug(`[ToolPreselector] from textmentionedfetch JSON group successful`),t}}let i=e.match(/\[[\s\S]*?\]/g);if(i)for(let e of i){let t=_t(e);if(t)return r.debug(`[ToolPreselector] via regexmentionedfetch JSON group successful`),t}return null}function _t(e){if(!e||typeof e!=`string`)return null;let t=e.trim();try{let e=JSON.parse(t);if(Array.isArray(e))return e}catch{}try{let e=t.replace(/,\s*\]/g,`]`),n=JSON.parse(e);if(Array.isArray(n))return n}catch{}try{let e=t.replace(/\[([\s\S]*)\]/g,(e,t)=>`[${t.split(`,`).map(e=>{let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t:`"${t}"`}).join(`, `)}]`),n=JSON.parse(e);if(Array.isArray(n))return n}catch{}return null}async function vt(e,n,i,a={},o=1){let s=i.length,c=crypto.randomUUID(),l=new Date().toISOString(),u=(e,n={})=>({id:c,iteration:0,timestamp:l,nodeType:`preselect`,nodeName:t(`preselector.nodeName`),...n,status:e}),d=await z(),f=d.reactConfig?.preselectMinToolCount??3;if(s<=f)return r.debug(`[ToolPreselector] tool count count ${s} <= ${f},skip pre-filter`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`skip`,params:{reason:t(`preselector.reasonFewTools`),toolCount:s}},duration:1})]};let p=ft(e);if(!p)return r.warn(`[ToolPreselector] cannot extractuseraskquestion,using alltool`),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:t(`preselector.reasonExtractFailed`)})]};let m=pt(e),h=mt(i);r.debug(`[ToolPreselector] start pre-filter,full count tool: ${s} ,with historymessage: ${m.length} `);let g=Date.now();try{let e=d,a=`${e.apiBase}/chat/completions`,o=[{role:`system`,content:h},...m,{role:`user`,content:`User question: ${p}`}],c={model:n||e.modelName,messages:o,stream:!1,temperature:.1,max_tokens:Math.min(4096,Math.max(1024,s*30)),response_format:{type:`json_object`}},l=await pr(a,{method:`POST`,headers:{Authorization:`Bearer ${e.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(c)},e.reactConfig.apiTimeout,e.reactConfig.apiRetryCount,e.reactConfig.apiRetryBaseDelay),f=Date.now()-g;if(!l.ok)return r.warn(`[ToolPreselector] API request failed,using alltool`),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:t(`preselector.reasonApiFailed`,{status:l.status}),duration:f})]};let _=((await l.json()).choices?.[0]?.message?.content||``).trim();r.debug(`[ToolPreselector] largemodelreturn:`,_);let v=ht(_);if(v){if(v.type===`answer`)return r.debug(`[ToolPreselector] modeldirect answer (newformat),no secondarycall with `),{type:`answer`,content:v.content,executionLog:[u(`success`,{thought:v.content,duration:f})]};let e=v.tools;if(e.length===0)return r.warn(`[ToolPreselector] returned empty toolgroup,using alltool`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`all_tools`,params:{reason:t(`preselector.reasonEmptyResult`)}},duration:f})]};let n=new Set(e.map(e=>String(e).toLowerCase())),a=i.filter(e=>n.has(e.function.name.toLowerCase()));if(p.includes(`proto_`)){for(let e of[`preview_ui`])if(!a.some(t=>t.function.name===e)){let t=i.find(t=>t.function.name===e);t&&(a.push(t),r.debug(`[ToolPreselector] fallback appendprototypetool: ${e}`))}}return a.length===0?(r.warn(`[ToolPreselector] filter after toolempty,using alltool`),{type:`tools`,tools:i,executionLog:[u(`success`,{action:{name:`all_tools`,params:{reason:t(`preselector.reasonNoMatch`)}},duration:f})]}):(r.debug(`[ToolPreselector] pre-filter complete: ${s} → ${a.length} tool`,a.map(e=>e.function.name)),{type:`tools`,tools:a,executionLog:[u(`success`,{action:{name:`preselect`,params:{selected:a.map(e=>e.function.name)}},apiRequest:{model:c.model,messageCount:o.length,toolCount:s},apiResponse:{toolCountAfter:a.length},duration:f})]})}return r.debug(`[ToolPreselector] modeldirect answer,no secondarycall with `),{type:`answer`,content:_,executionLog:[u(`success`,{thought:_,duration:f})]}}catch(e){let t=Date.now()-g;return r.warn(`[ToolPreselector] pre-filter exception,using alltool:`,e.message),{type:`tools`,tools:i,executionLog:[u(`failed`,{error:e.message,duration:t})]}}}async function yt({sessionId:e,model:t,usage:n,callType:i}){if(!n||!n.prompt_tokens&&!n.total_tokens)return;let a=x(t);try{await N({sessionId:e||`unknown`,model:t||`unknown`,promptTokens:n.prompt_tokens||0,completionTokens:n.completion_tokens||0,totalTokens:n.total_tokens||0,contextWindow:a,callType:i||`unknown`})}catch(e){r.warn(`[TokenRecorder] record token stats failed:`,e.message)}}var bt=200,xt=500,St=150;function Ct(e){if(!e||typeof e!=`object`||Object.keys(e).length===0)return``;let t=Object.keys(e);if(t.length===0)return``;let n=[`path`,`query`,`url`,`command`,`name`,`pattern`,`filePath`,`content`],r=t.filter(e=>n.includes(e)).slice(0,2);if(r.length===0){let n=t.find(t=>e[t]!=null&&e[t]!==``);if(!n)return``;r.push(n)}return r.map(t=>`${t}=${(typeof e[t]==`string`?e[t]:JSON.stringify(e[t])).substring(0,St)}`).join(`, `)}async function wt(e,t,n,i={}){if(!e||e.length<2)return r.debug(`[ContextSummarizer] round timesmessage not sufficient,skip summary`),null;let a=e.find(e=>e.role===`assistant`&&e.tool_calls);if(!a)return r.debug(`[ContextSummarizer] not found assistant(tool_calls),skip summary`),null;let o=`Summarize the execution of the following tool calls in one sentence, extracting key findings:
17
17
 
18
18
  ${a.tool_calls.map((t,n)=>{let r=t.function?.name||t.name||`unknown`,i=Ct(typeof t.function?.arguments==`string`?(()=>{try{return JSON.parse(t.function.arguments)}catch{return{}}})():t.function?.arguments||{}),o=e.find(e=>e.role===`tool`&&e.tool_call_id===(t.id||a.tool_calls[n]?.id)),s=(o?typeof o.content==`string`?o.content:JSON.stringify(o.content):`(no return)`).substring(0,xt);return`Tool: ${r}${i?` (${i})`:``}\nResult: ${s}`}).join(`
19
19
 
20
20
  `)}
21
21
 
22
- Output requirements: Summarize in one sentence what this round of operations did and what key information was found. No more than 150 characters.`;try{let e=await dr(`${t.apiBase}/chat/completions`,{method:`POST`,headers:{Authorization:`Bearer ${t.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:n||t.modelName,messages:[{role:`user`,content:o}],stream:!1,max_tokens:bt,temperature:.1}),signal:i.signal},i.timeout||15e3,1,500);if(!e.ok)return r.warn(`[ContextSummarizer] API request failed: ${e.status}`),null;let a=((await e.json()).choices?.[0]?.message?.content||``).trim();return a?(r.debug(`[ContextSummarizer] summary complete: ${a.substring(0,100)}`),a):(r.warn(`[ContextSummarizer] summary returnedempty`),null)}catch(e){return r.warn(`[ContextSummarizer] summary requestexception:`,e.message),null}}e(`zh`,{reflection:{qualityAssessment:`质量评估`,qualityAssessmentScore:`质量评估: {score}/10 ({decision})`,decisionPassed:`通过`,decisionRevised:`已修订`,decisionNeedsImprovement:`需改进`,postNodeName:`质量评估 {round}/{maxRounds}`,subtaskNodeName:`子任务反思: {name}`,lowScoreRevised:`⚠️ 原答案评分过低,已由反思修订`,retrySuggestion:`建议:重新执行任务,基于反思问题调整工具选择和执行策略`}}),e(`en`,{reflection:{qualityAssessment:`Quality Assessment`,qualityAssessmentScore:`Quality Assessment: {score}/10 ({decision})`,decisionPassed:`Passed`,decisionRevised:`Revised`,decisionNeedsImprovement:`Needs Improvement`,postNodeName:`Quality Assessment {round}/{maxRounds}`,subtaskNodeName:`Subtask Reflection: {name}`,lowScoreRevised:`⚠️ Original score too low, revised by reflection`,retrySuggestion:`Suggestion: Re-execute the task, adjust tool selection and execution strategy based on reflection issues`}});function Tt(e,t){return!t&&!!(e.some(e=>e.nodeType===`tool_exec`&&e.action?.name===`plan_task`&&e.status===`success`)||e.some(e=>e.nodeType===`tool_exec`&&e.status===`failed`)||e.filter(e=>e.nodeType===`tool_exec`).length>=2)}function Et(e,t,n){let r=0;return(t.includes(`"success":false`)||t.includes(`error`)||t.includes(`失败`))&&(r+=10),n>=2&&(r+=n*5),[`fill_form`,`interact_element`,`download_file`,`manage_cookies`,`clear_data`].includes(e)&&(r+=3),(!t||t.trim()===``||t===`{}`)&&(r+=2),r}function Dt(e,t,n){if(!n?.enabled||!n?.toolReflection?.enabled)return!1;let r=n.toolReflection;return!!(r.triggerOnConsecutiveFails&&t>=r.triggerOnConsecutiveFails||r.triggerOnError&&(e.includes(`"success":false`)||e.includes(`error`)||e.includes(`失败`))||r.triggerOnEmpty&&(!e||e.trim()===``||e===`{}`)||r.triggerOnOversized&&e.length>r.oversizeThreshold)}function Ot(e,t,n,r=1){let i=e.filter(e=>e.role===`user`),a=i.length>0?T(i[i.length-1].content):`unknown`,o=n.filter(e=>e.nodeType===`api_call`).length,s=n.filter(e=>e.nodeType===`tool_exec`),c=s.map(e=>{let t=e.action?.params||{},n=Object.keys(t).length>0?`params: ${JSON.stringify(t)}`:``,r=e.observation?`result summary: ${String(e.observation).substring(0,200)}`:``;return` ${e.status===`success`?`✅`:`❌`} ${e.action?.name||e.nodeName} ${n} ${r}`.trim()}).join(`
22
+ Output requirements: Summarize in one sentence what this round of operations did and what key information was found. No more than 150 characters.`;try{let e=await pr(`${t.apiBase}/chat/completions`,{method:`POST`,headers:{Authorization:`Bearer ${t.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:n||t.modelName,messages:[{role:`user`,content:o}],stream:!1,max_tokens:bt,temperature:.1}),signal:i.signal},i.timeout||15e3,1,500);if(!e.ok)return r.warn(`[ContextSummarizer] API request failed: ${e.status}`),null;let a=((await e.json()).choices?.[0]?.message?.content||``).trim();return a?(r.debug(`[ContextSummarizer] summary complete: ${a.substring(0,100)}`),a):(r.warn(`[ContextSummarizer] summary returnedempty`),null)}catch(e){return r.warn(`[ContextSummarizer] summary requestexception:`,e.message),null}}e(`zh`,{reflection:{qualityAssessment:`质量评估`,qualityAssessmentScore:`质量评估: {score}/10 ({decision})`,decisionPassed:`通过`,decisionRevised:`已修订`,decisionNeedsImprovement:`需改进`,postNodeName:`质量评估 {round}/{maxRounds}`,subtaskNodeName:`子任务反思: {name}`,lowScoreRevised:`⚠️ 原答案评分过低,已由反思修订`,retrySuggestion:`建议:重新执行任务,基于反思问题调整工具选择和执行策略`}}),e(`en`,{reflection:{qualityAssessment:`Quality Assessment`,qualityAssessmentScore:`Quality Assessment: {score}/10 ({decision})`,decisionPassed:`Passed`,decisionRevised:`Revised`,decisionNeedsImprovement:`Needs Improvement`,postNodeName:`Quality Assessment {round}/{maxRounds}`,subtaskNodeName:`Subtask Reflection: {name}`,lowScoreRevised:`⚠️ Original score too low, revised by reflection`,retrySuggestion:`Suggestion: Re-execute the task, adjust tool selection and execution strategy based on reflection issues`}});function Tt(e,t){return!t&&!!(e.some(e=>e.nodeType===`tool_exec`&&e.action?.name===`plan_task`&&e.status===`success`)||e.some(e=>e.nodeType===`tool_exec`&&e.status===`failed`)||e.filter(e=>e.nodeType===`tool_exec`).length>=2)}function Et(e,t,n){let r=0;return(t.includes(`"success":false`)||t.includes(`error`)||t.includes(`失败`))&&(r+=10),n>=2&&(r+=n*5),[`fill_form`,`interact_element`,`download_file`,`manage_cookies`,`clear_data`].includes(e)&&(r+=3),(!t||t.trim()===``||t===`{}`)&&(r+=2),r}function Dt(e,t,n){if(!n?.enabled||!n?.toolReflection?.enabled)return!1;let r=n.toolReflection;return!!(r.triggerOnConsecutiveFails&&t>=r.triggerOnConsecutiveFails||r.triggerOnError&&(e.includes(`"success":false`)||e.includes(`error`)||e.includes(`失败`))||r.triggerOnEmpty&&(!e||e.trim()===``||e===`{}`)||r.triggerOnOversized&&e.length>r.oversizeThreshold)}function Ot(e,t,n,r=1){let i=e.filter(e=>e.role===`user`),a=i.length>0?T(i[i.length-1].content):`unknown`,o=n.filter(e=>e.nodeType===`api_call`).length,s=n.filter(e=>e.nodeType===`tool_exec`),c=s.map(e=>{let t=e.action?.params||{},n=Object.keys(t).length>0?`params: ${JSON.stringify(t)}`:``,r=e.observation?`result summary: ${String(e.observation).substring(0,200)}`:``;return` ${e.status===`success`?`✅`:`❌`} ${e.action?.name||e.nodeName} ${n} ${r}`.trim()}).join(`
23
23
  `);s.length>0&&s.map(e=>`${e.action?.name||e.nodeName} (${e.status})`).join(`, `);let l=n.filter(e=>e.nodeType===`tool_exec`&&e.action?.name===`plan_task`),u=l.length>0?`, ${l[0].subtaskCount||0} subtasks decomposed`:``,d=n.filter(e=>e.nodeType===`reflection`&&e.reflectionType===`tool`),f=d.length>0?d.map(e=>` ${e.useful?`✅useful`:`⚠️invalid`} - ${e.nodeName}: ${e.reasoning||``} ${e.suggestion?`(suggestion: ${e.suggestion})`:``}`).join(`
24
24
  `):`none`,p=`API calls: ${o}${u}.`,m=t.length>3e3?t.substring(0,3e3)+`...`:t;return`Please strictly evaluate the quality of the following AI assistant's answer to the user's question${r>1?` (this is round ${r} of evaluation; the revised answer from the previous round is shown in "Final Answer" below)`:``}.
25
25
 
@@ -58,7 +58,7 @@ Please output in strict JSON format (do not include markdown code block markers)
58
58
  "issues": ["specific issue 1", "specific issue 2"],
59
59
  "suggestions": ["specific improvement suggestion 1", "specific improvement suggestion 2"],
60
60
  "refinedAnswer": "If the answer has obvious flaws, output the complete revised answer (must be complete, not just the modified parts); otherwise set to null"
61
- }`}function kt(e){let t={overallScore:7,dimensions:{},issues:[],suggestions:[],refinedAnswer:null};if(!e)return t;try{let t=JSON.parse(e.trim());return{overallScore:typeof t.overallScore==`number`?t.overallScore:7,dimensions:t.dimensions||{},issues:Array.isArray(t.issues)?t.issues:[],suggestions:Array.isArray(t.suggestions)?t.suggestions:[],refinedAnswer:typeof t.refinedAnswer==`string`?t.refinedAnswer:null}}catch{let t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);if(t)try{let e=JSON.parse(t[1].trim());return{overallScore:typeof e.overallScore==`number`?e.overallScore:7,dimensions:e.dimensions||{},issues:Array.isArray(e.issues)?e.issues:[],suggestions:Array.isArray(e.suggestions)?e.suggestions:[],refinedAnswer:typeof e.refinedAnswer==`string`?e.refinedAnswer:null}}catch{}}return r.warn(`[Background] cannot parsereflection result,using default value`),t}async function At(e,n,i,a,o,s,c,l,u,d,f,p=0){let m=s.postReflection;if(!s?.enabled||!m?.enabled||m.maxRounds<1)return{content:n,reflectionLog:[],status:`skipped`,overallScore:null,wasRevised:!1};let h=[],g=Math.min(Math.max(1,m.maxRounds),10-p),_=Date.now(),v=n,y=null,b=`passed`,x=!1;l(t(`reflection.qualityAssessment`),`processing`);try{let n=`${o.apiBase}/chat/completions`,s=m.model||a||o.modelName;for(let r=1;r<=g;r++){p++;let a=Date.now(),c=crypto.randomUUID(),l=Ot(e,v,i,r),d=await dr(n,{method:`POST`,headers:{Authorization:`Bearer ${o.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:s,messages:[{role:`system`,content:`You are a strict quality evaluator. Output the evaluation result in JSON format; do not include markdown code block markers.`},{role:`user`,content:l}],stream:!1,temperature:m.temperature,max_tokens:m.maxTokens,response_format:{type:`json_object`}})},3e4,1,1e3);if(!d.ok)throw Error(`Reflection API error: ${d.status}`);let _=await d.json(),S=_.choices?.[0]?.message?.content||``,C=kt(S),w=Date.now()-a;y=C.overallScore;let T,E=v;if(C.overallScore>=m.qualityThreshold?(T=`passed`,E=C.refinedAnswer||v,C.refinedAnswer&&C.refinedAnswer!==v&&(x=!0)):C.overallScore>=m.refineThreshold?(T=`revised`,C.refinedAnswer&&(E=C.refinedAnswer,x=!0)):C.refinedAnswer?(T=`revised`,E=C.refinedAnswer,x=!0,C.issues=C.issues||[],C.issues.some(e=>e.includes(`反思修订`))||C.issues.unshift(t(`reflection.lowScoreRevised`))):(T=`needs_improvement`,C.suggestions=C.suggestions||[],C.suggestions.some(e=>e.includes(`重新执行`)||e.includes(`retry`))||C.suggestions.push(t(`reflection.retrySuggestion`))),b=T,t(T===`passed`?`reflection.decisionPassed`:T===`revised`?`reflection.decisionRevised`:`reflection.decisionNeedsImprovement`),h.push({id:c,iteration:u?.value||0,timestamp:new Date().toISOString(),status:`success`,nodeType:`reflection`,nodeName:t(`reflection.postNodeName`,{round:r,maxRounds:g}),reflectionType:`post`,round:r,overallScore:C.overallScore,dimensions:C.dimensions,issues:C.issues,suggestions:C.suggestions,prompt:l,rawContent:S,apiRequest:{model:s,messageCount:2,temperature:m.temperature,maxTokens:m.maxTokens},apiResponse:{tokenUsage:_.usage||null},action:{decision:T,refinedAnswer:C.refinedAnswer&&C.refinedAnswer!==v?C.refinedAnswer:null},duration:w}),_.usage&&yt({sessionId:f,model:s,usage:_.usage,callType:`reflection`}).catch(()=>{}),T===`passed`){v=E;break}v=E}let c=Date.now()-_,d=h[h.length-1],S=y??d?.overallScore,C=b||d?.action?.decision||`passed`,w=t(C===`passed`?`reflection.decisionPassed`:C===`revised`?`reflection.decisionRevised`:`reflection.decisionNeedsImprovement`);return l(t(`reflection.qualityAssessmentScore`,{score:S,decision:w}),`success`),r.debug(`[Background] reflection complete: score ${S}/10, decision: ${w}, revise: ${x}, total time: ${c}ms`),{content:v,reflectionLog:h,status:C,overallScore:S,wasRevised:x}}catch(e){r.warn(`[Background] reflection API call with failed:`,e.message);let i=Date.now()-_;return h.push({id:crypto.randomUUID(),iteration:u?.value||0,timestamp:new Date().toISOString(),status:`failed`,nodeType:`reflection`,nodeName:t(`reflection.qualityAssessment`),reflectionType:`post`,error:e.message,duration:i}),{content:n,reflectionLog:h,status:`reflection_failed`,overallScore:null,wasRevised:!1}}}async function jt(e,t,n,i,a,o,s,c,l){if(!o?.enabled)return null;let u=o.toolReflection;if(!u?.enabled||s.filter(e=>e.nodeType===`reflection`&&e.reflectionType===`tool`&&e.iteration===c).length>=u.maxPerIteration)return null;let d=`You are executing a browser automation task. The tool "${e}" was just called with parameters ${JSON.stringify(n)}.
61
+ }`}function kt(e){let t={overallScore:7,dimensions:{},issues:[],suggestions:[],refinedAnswer:null};if(!e)return t;try{let t=JSON.parse(e.trim());return{overallScore:typeof t.overallScore==`number`?t.overallScore:7,dimensions:t.dimensions||{},issues:Array.isArray(t.issues)?t.issues:[],suggestions:Array.isArray(t.suggestions)?t.suggestions:[],refinedAnswer:typeof t.refinedAnswer==`string`?t.refinedAnswer:null}}catch{let t=e.match(/```(?:json)?\s*\n?([\s\S]*?)\n?\s*```/);if(t)try{let e=JSON.parse(t[1].trim());return{overallScore:typeof e.overallScore==`number`?e.overallScore:7,dimensions:e.dimensions||{},issues:Array.isArray(e.issues)?e.issues:[],suggestions:Array.isArray(e.suggestions)?e.suggestions:[],refinedAnswer:typeof e.refinedAnswer==`string`?e.refinedAnswer:null}}catch{}}return r.warn(`[Background] cannot parsereflection result,using default value`),t}async function At(e,n,i,a,o,s,c,l,u,d,f,p=0){let m=s.postReflection;if(!s?.enabled||!m?.enabled||m.maxRounds<1)return{content:n,reflectionLog:[],status:`skipped`,overallScore:null,wasRevised:!1};let h=[],g=Math.min(Math.max(1,m.maxRounds),10-p),_=Date.now(),v=n,y=null,b=`passed`,x=!1;l(t(`reflection.qualityAssessment`),`processing`);try{let n=`${o.apiBase}/chat/completions`,s=m.model||a||o.modelName;for(let r=1;r<=g;r++){p++;let a=Date.now(),c=crypto.randomUUID(),l=Ot(e,v,i,r),d=await pr(n,{method:`POST`,headers:{Authorization:`Bearer ${o.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:s,messages:[{role:`system`,content:`You are a strict quality evaluator. Output the evaluation result in JSON format; do not include markdown code block markers.`},{role:`user`,content:l}],stream:!1,temperature:m.temperature,max_tokens:m.maxTokens,response_format:{type:`json_object`}})},3e4,1,1e3);if(!d.ok)throw Error(`Reflection API error: ${d.status}`);let _=await d.json(),S=_.choices?.[0]?.message?.content||``,C=kt(S),w=Date.now()-a;y=C.overallScore;let T,E=v;if(C.overallScore>=m.qualityThreshold?(T=`passed`,E=C.refinedAnswer||v,C.refinedAnswer&&C.refinedAnswer!==v&&(x=!0)):C.overallScore>=m.refineThreshold?(T=`revised`,C.refinedAnswer&&(E=C.refinedAnswer,x=!0)):C.refinedAnswer?(T=`revised`,E=C.refinedAnswer,x=!0,C.issues=C.issues||[],C.issues.some(e=>e.includes(`反思修订`))||C.issues.unshift(t(`reflection.lowScoreRevised`))):(T=`needs_improvement`,C.suggestions=C.suggestions||[],C.suggestions.some(e=>e.includes(`重新执行`)||e.includes(`retry`))||C.suggestions.push(t(`reflection.retrySuggestion`))),b=T,t(T===`passed`?`reflection.decisionPassed`:T===`revised`?`reflection.decisionRevised`:`reflection.decisionNeedsImprovement`),h.push({id:c,iteration:u?.value||0,timestamp:new Date().toISOString(),status:`success`,nodeType:`reflection`,nodeName:t(`reflection.postNodeName`,{round:r,maxRounds:g}),reflectionType:`post`,round:r,overallScore:C.overallScore,dimensions:C.dimensions,issues:C.issues,suggestions:C.suggestions,prompt:l,rawContent:S,apiRequest:{model:s,messageCount:2,temperature:m.temperature,maxTokens:m.maxTokens},apiResponse:{tokenUsage:_.usage||null},action:{decision:T,refinedAnswer:C.refinedAnswer&&C.refinedAnswer!==v?C.refinedAnswer:null},duration:w}),_.usage&&yt({sessionId:f,model:s,usage:_.usage,callType:`reflection`}).catch(()=>{}),T===`passed`){v=E;break}v=E}let c=Date.now()-_,d=h[h.length-1],S=y??d?.overallScore,C=b||d?.action?.decision||`passed`,w=t(C===`passed`?`reflection.decisionPassed`:C===`revised`?`reflection.decisionRevised`:`reflection.decisionNeedsImprovement`);return l(t(`reflection.qualityAssessmentScore`,{score:S,decision:w}),`success`),r.debug(`[Background] reflection complete: score ${S}/10, decision: ${w}, revise: ${x}, total time: ${c}ms`),{content:v,reflectionLog:h,status:C,overallScore:S,wasRevised:x}}catch(e){r.warn(`[Background] reflection API call with failed:`,e.message);let i=Date.now()-_;return h.push({id:crypto.randomUUID(),iteration:u?.value||0,timestamp:new Date().toISOString(),status:`failed`,nodeType:`reflection`,nodeName:t(`reflection.qualityAssessment`),reflectionType:`post`,error:e.message,duration:i}),{content:n,reflectionLog:h,status:`reflection_failed`,overallScore:null,wasRevised:!1}}}async function jt(e,t,n,i,a,o,s,c,l){if(!o?.enabled)return null;let u=o.toolReflection;if(!u?.enabled||s.filter(e=>e.nodeType===`reflection`&&e.reflectionType===`tool`&&e.iteration===c).length>=u.maxPerIteration)return null;let d=`You are executing a browser automation task. The tool "${e}" was just called with parameters ${JSON.stringify(n)}.
62
62
 
63
63
  Tool returned result (truncated):
64
64
  ${t.substring(0,2e3)}
@@ -72,7 +72,7 @@ Output in JSON format (do not include markdown code blocks):
72
72
  "suggestion": null
73
73
  }
74
74
 
75
- If the result is not helpful, set useful to false and provide a suggestion.`;try{let e=await dr(`${i.apiBase}/chat/completions`,{method:`POST`,headers:{Authorization:`Bearer ${i.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:a||i.modelName,messages:[{role:`system`,content:`You are a tool execution result evaluator. Output only JSON.`},{role:`user`,content:d}],stream:!1,temperature:.1,max_tokens:512,response_format:{type:`json_object`}})},15e3,1,1e3);if(!e.ok)return null;let t=await e.json();t.usage&&yt({sessionId:l||`unknown`,model:a||i.modelName,usage:t.usage,callType:`tool_reflection`}).catch(()=>{});let n=t.choices?.[0]?.message?.content||``;try{let e=JSON.parse(n.trim());return{useful:e.useful!==!1,reasoning:e.reasoning||``,suggestion:e.suggestion||null}}catch{let e=n.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]);return{useful:t.useful!==!1,reasoning:t.reasoning||``,suggestion:t.suggestion||null}}}return null}catch(e){return r.warn(`[Background] toolreflection call failed:`,e.message),null}}async function Mt(e,n,i,a,o,s,c,l,u,d){let f=Date.now(),p=[],m=s.dimensions||[`completeness`,`relevance`],h={completeness:`whether the task is fully completed`,relevance:`whether the result is relevant to the task goal`,accuracy:`whether the result is accurate without errors`,efficiency:`whether the execution process is efficient`},g=m.map(e=>`- ${e}: ${h[e]||e}`).join(`
75
+ If the result is not helpful, set useful to false and provide a suggestion.`;try{let e=await pr(`${i.apiBase}/chat/completions`,{method:`POST`,headers:{Authorization:`Bearer ${i.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:a||i.modelName,messages:[{role:`system`,content:`You are a tool execution result evaluator. Output only JSON.`},{role:`user`,content:d}],stream:!1,temperature:.1,max_tokens:512,response_format:{type:`json_object`}})},15e3,1,1e3);if(!e.ok)return null;let t=await e.json();t.usage&&yt({sessionId:l||`unknown`,model:a||i.modelName,usage:t.usage,callType:`tool_reflection`}).catch(()=>{});let n=t.choices?.[0]?.message?.content||``;try{let e=JSON.parse(n.trim());return{useful:e.useful!==!1,reasoning:e.reasoning||``,suggestion:e.suggestion||null}}catch{let e=n.match(/\{[\s\S]*\}/);if(e){let t=JSON.parse(e[0]);return{useful:t.useful!==!1,reasoning:t.reasoning||``,suggestion:t.suggestion||null}}}return null}catch(e){return r.warn(`[Background] toolreflection call failed:`,e.message),null}}async function Mt(e,n,i,a,o,s,c,l,u,d){let f=Date.now(),p=[],m=s.dimensions||[`completeness`,`relevance`],h={completeness:`whether the task is fully completed`,relevance:`whether the result is relevant to the task goal`,accuracy:`whether the result is accurate without errors`,efficiency:`whether the execution process is efficient`},g=m.map(e=>`- ${e}: ${h[e]||e}`).join(`
76
76
  `),_=`You are evaluating the execution result of a subtask.
77
77
 
78
78
  Subtask name: ${l}
@@ -93,9 +93,9 @@ Output the evaluation result in JSON format (do not include markdown code blocks
93
93
  "issues": ["discovered issue 1", "discovered issue 2"],
94
94
  "suggestions": ["improvement suggestion 1"],
95
95
  "refinedAnswer": null // if revision is needed, provide the revised answer here
96
- }`;try{let e=`${o.apiBase}/chat/completions`,i=s.model||a||o.modelName,c=await dr(e,{method:`POST`,headers:{Authorization:`Bearer ${o.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:i,messages:[{role:`system`,content:`You are a strict quality evaluator. Output the evaluation result in JSON format; do not include markdown code block markers.`},{role:`user`,content:_}],stream:!1,temperature:s.temperature||.3,max_tokens:s.maxTokens||1024})},3e4,1,1e3);if(!c.ok)throw Error(`Subtask reflection API error: ${c.status}`);let u=await c.json(),m=u.choices?.[0]?.message?.content||``,h=kt(m),g=Date.now()-f;return p.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`success`,nodeType:`reflection`,nodeName:t(`reflection.subtaskNodeName`,{name:l}),reflectionType:`subtask`,overallScore:h.overallScore,dimensions:h.dimensions,issues:h.issues,suggestions:h.suggestions,prompt:_,rawContent:m,apiRequest:{model:i,messageCount:2,temperature:s.temperature||.3,maxTokens:s.maxTokens||1024},apiResponse:{tokenUsage:u.usage||null},duration:g}),r.debug(`[Background] subtask reflectioncomplete: ${l}, score: ${h.overallScore}/10, elapsed: ${g}ms`),u.usage&&yt({sessionId:d,model:i,usage:u.usage,callType:`subtask_reflection`}).catch(()=>{}),{score:h.overallScore,refinedContent:h.refinedAnswer&&h.refinedAnswer!==n?h.refinedAnswer:null,reflectionLog:p}}catch(e){r.warn(`[Background] subtask reflection failed:`,e.message);let n=Date.now()-f;return p.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`failed`,nodeType:`reflection`,nodeName:t(`reflection.subtaskNodeName`,{name:l}),reflectionType:`subtask`,error:e.message,duration:n}),{score:null,refinedContent:null,reflectionLog:p}}}e(`zh`,{reactLoop:{apiCallNode:`API调用 (第{count}次{subtask})`,apiCallSubtask:`, 子任务第{iteration}次`,preparing:`准备开始执行...`,toolExec:`工具执行:{name}`,toolExecStart:`执行工具: {name}`,taskPlanDone:`任务规划完成`,executionDone:`执行完成`,userDenied:`用户拒绝了此操作`,subtaskRolledBack:`子任务 {name} (已回滚)`,subtaskRollbackFailed:`子任务 {name} (回滚失败)`,subtaskCount:`已拆解为 {count} 个子任务`,toolReflection:`工具反思: {name}`,subtaskNode:`子任务 {index}: {name}`,subtaskCompleted:`子任务 {index}: {name} (完成)`,subtaskFailed:`子任务 {index}: {name} (失败)`,userCancelled:`用户取消`,skippedAfterPlanTask:`已跳过(plan_task 已拆分子任务,本轮其他工具调用不再执行)`,toolError:`错误: {message}`,loopTimeout:`ReAct 循环总超时 ({timeout}ms,不含澄清等待时间)`,apiInvalidJson:`API 响应不是有效的 JSON (HTTP {status}): {error}。响应前100字符: {preview}`,infiniteLoopDetected:`连续{count}次执行完全相同的工具调用(入参和返参均相同),疑似陷入死循环,已自动终止。请更换策略或缩小任务范围后重试。`,maxIterationsExceeded:`ReAct 循环超过最大迭代次数 ({maxIterations})`,toolTimeout:`工具执行超时 ({timeout}ms): {tool}`,toolAborted:`工具执行已被用户终止: {tool}`,jsonParseFailed:`JSON 解析失败 (HTTP {status}): {error}。响应前100字符: {preview}`}}),e(`en`,{reactLoop:{apiCallNode:`API Call (#{count}{subtask})`,apiCallSubtask:`, Subtask #{iteration}`,preparing:`Preparing to execute...`,toolExec:`Tool Exec:{name}`,toolExecStart:`Executing: {name}`,taskPlanDone:`Task planning completed`,executionDone:`Execution completed`,userDenied:`User denied this operation`,subtaskRolledBack:`Subtask {name} (rolled back)`,subtaskRollbackFailed:`Subtask {name} (rollback failed)`,subtaskCount:`Broken down into {count} subtasks`,toolReflection:`Tool Reflection: {name}`,subtaskNode:`Subtask {index}: {name}`,subtaskCompleted:`Subtask {index}: {name} (completed)`,subtaskFailed:`Subtask {index}: {name} (failed)`,skippedAfterPlanTask:`Skipped (plan_task has decomposed subtasks, other tool calls in this round are no longer executed)`,toolError:`Error: {message}`,loopTimeout:`ReAct loop total timeout ({timeout}ms, excluding clarification wait time)`,apiInvalidJson:`API response is not valid JSON (HTTP {status}): {error}. First 100 chars: {preview}`,infiniteLoopDetected:`Executed the exact same tool call {count} times in a row (both inputs and outputs identical), likely stuck in an infinite loop. Automatically terminated. Please change strategy or narrow the task scope and retry.`,maxIterationsExceeded:`ReAct loop exceeded maximum iterations ({maxIterations})`,toolTimeout:`Tool execution timed out ({timeout}ms): {tool}`,toolAborted:`Tool execution was aborted by user: {tool}`,jsonParseFailed:`JSON parse failed (HTTP {status}): {error}. First 100 chars: {preview}`}});var Nt=new Set,Pt=new Set,Ft={manage_cookies:`sensitiveTool.manage_cookies`,clear_data:`sensitiveTool.clear_data`,download_file:`sensitiveTool.download_file`,manage_tab:`sensitiveTool.manage_tab`,agent_file:`sensitiveTool.agent_file`};async function It(e,n,i,a){let o=Ft[e],s=o?t(o):e,c=3e5;r.debug(`[Background] requesting user confirmation for tool operation: ${e}`,n);let l=``;if(e===`manage_tab`&&n.action===`close`&&n.tabId!==void 0)try{let e=await chrome.tabs.get(parseInt(n.tabId,10));l=t(`sensitiveTool.tabInfo`,{title:e.title||t(`sensitiveTool.untitled`),url:e.url||t(`sensitiveTool.unknownUrl`)})}catch(e){l=t(`sensitiveTool.tabInfoError`,{error:e.message})}return new Promise(i=>{let o=t=>{t.type===`TOOL_CONFIRMATION_RESPONSE`&&t.toolCallId===e&&(chrome.runtime.onMessage.removeListener(o),clearTimeout(u),r.debug(`[Background] userconfirmresult: ${e} = ${t.confirmed}, scope: ${t.scope}`),t.confirmed&&t.scope===`loop`&&(Pt.add(a),r.debug(`[Background] session ${a} set as current taskallow`)),i(t.confirmed))};chrome.runtime.onMessage.addListener(o);let u=setTimeout(()=>{chrome.runtime.onMessage.removeListener(o),r.debug(`[Background] confirmtimeout,defaultdeny: ${e}`),i(!1)},c);chrome.runtime.sendMessage({type:`SHOW_CONFIRM_DIALOG`,data:{toolName:e,toolLabel:s,args:n,toolCallId:e,sessionId:a,timeout:c,message:l?t(`dialog.confirmAction`,{name:s})+l:void 0}}).catch(e=>{r.debug(`[Background] sendconfirm dialogmessage failed:`,e.message),chrome.runtime.onMessage.removeListener(o),clearTimeout(u),i(!0)})})}function Lt(e,t){let n=Error(e);return n.executionLog=t,n}async function Rt(e,t){if(e)try{if(await D({sessionId:e,...t})){r.debug(`[Background] checkpoint saved (sessionId=${e}, iteration=${t.iteration}, reason=${t.interruptedReason})`);try{let t=await P(e);t?r.debug(`[Background] checkpoint write verifypassed,message=${t.currentMessages?.length||0}`):r.error(`[Background] ⚠️ checkpoint write returned successfulbut read-back empty!sessionId=${e}, possibly is DB store does not exist or transaction not committed`)}catch(e){r.error(`[Background] checkpoint read-backverify failed:`,e.message)}}else r.error(`[Background] checkpoint save returned false (sessionId=${e}, iteration=${t.iteration}), possibly is reactCheckpoints store not found,DB upgrade blocked`)}catch(e){r.error(`[Background] save checkpoint failed:`,e.message,e.stack)}}async function zt(e){if(e)try{await ie(e),r.debug(`[Background] checkpoint cleaned (sessionId=${e})`)}catch(e){r.warn(`[Background] cleanup checkpoint failed:`,e.message)}}function Bt(e){if(!e||e.length===0)return e;let t=[],n=0;for(;n<e.length;){let i=e[n];if(i.role===`tool`){let t=n>0?e[n-1]:null;if(!t||t.role!==`assistant`||!t.tool_calls){r.warn(`[Background] cleanupIncompleteMessagePairs: skip orphaned tool message (index=`+n+`)`),n++;continue}}if(i.role===`assistant`&&i.tool_calls&&i.tool_calls.length>0){let a=n+1<e.length?e[n+1]:null;if(!a||a.role!==`tool`){r.warn(`[Background] cleanupIncompleteMessagePairs: orphaned assistant(tool_calls),clear tool_calls (index=`+n+`)`),t.push({...i,tool_calls:void 0}),n++;continue}}t.push(i),n++}return t.length!==e.length&&r.debug(`[Background] cleanupIncompleteMessagePairs: cleanup complete,message:`,e.length,`→`,t.length),t}async function Vt(e,t=``,n=null){if(!e)return null;let i=await P(e);if(!i){r.warn(`[Background] not found sessionId=${e} checkpoint, no way to restore`);try{let e=await le();e.length===0?r.warn(`[Background] IndexedDB contains no checkpoint record (may never have been saved successful)`):(r.warn(`[Background] current IndexedDB checkpoint column table:`,e.map(e=>({sessionId:e.sessionId,iteration:e.iteration,updatedAt:new Date(e.updatedAt).toISOString(),reason:e.interruptedReason}))),`${e.length}${e.map(e=>e.sessionId).join(`, `)}`)}catch(e){r.error(`[Background] read checkpoint column table failed:`,e),`${e.message}`}return null}r.debug(`[Background] from checkpoint restore ReAct loop: sessionId=${e}, iteration=${i.iteration}, messages=${i.currentMessages?.length}, userGuidance=${t?` has `:` no `}, resumeCallId=${n}`);let a=JSON.parse(JSON.stringify(i.currentMessages||[]));if(a=Bt(a),t&&t.trim()){let e={role:`user`,content:`[Task Resume Notice] The task was previously interrupted during execution and is now resuming from the checkpoint.\n\nAdditional user instructions: ${t.trim()}\n\nPlease continue completing the task based on the previous tool call results, taking the above instructions into account. Do not repeat already completed steps.`};a.push(e),r.debug(`[Background] injected user additionaldescription,messagetotal:`,a.length)}else a.push({role:`user`,content:`[Task Resume Notice] The task was previously interrupted during execution and is now resuming from the checkpoint. Please continue completing the task based on the previous tool call results. Do not repeat already completed steps.`}),r.debug(`[Background] injected defaultrestoreprompt,messagetotal:`,a.length);let o=await Ht(a,i.model,await Ln(),i.tabId,i.apiParams||{},e,null,null,i.globalIteration||{value:i.iteration||0},i.executionLog||[],n||i.callId||null);return await zt(e),o}async function Ht(e,n,i,o,c={},u=null,d=null,f=null,p={value:0},m=[],h=null){u&&Nt.add(u);let g=0,v=0,T=[...e],D=new Map,ee=null,k=0,A=null,j=null,ie=e=>{if(j===null){let t=S(typeof T[0]?.content==`string`?T[0].content:JSON.stringify(T[0]?.content||``)),n=S(JSON.stringify(i.map(e=>{let{id:t,...n}=e;return n}))),a=x(e,0,fe.customModelMap);j=a-t-n-4096-2e3,j<1e3&&(r.warn(`[Background] ReAct Token budget too low: ${j},using minimumbudget 1000`),j=1e3),r.debug(`[Background] ReAct Token budget: ${j} tokens (model: ${e}, actualsystem promptword: ${t}, actual tooldefinition: ${n}, context window: ${a})`)}return j},ae=6e3,oe=5e4,se=async()=>{let e=ie(n||`default`),t=_(y(T));if(t<=e)return;let i=T.length,a=t,o=T[0]?.role===`system`?[T[0]]:[],s=o.length?[...T.slice(1)]:[...T],c=e=>{let t=e.map(e=>({...e,content:w(e.content)}));return _(y(t))};for(let i=0;i<3&&(t=c([...o,...s]),!(t<=e));i++){let e=-1,t=-1;for(let n=0;n<s.length;n++)if(s[n].role===`assistant`&&Array.isArray(s[n].tool_calls)&&s[n].tool_calls.length>0){for(e=n,t=n+1;t<s.length&&s[t].role===`tool`;)t++;break}if(e===-1)break;let l=s.slice(e,t);r.debug(`[Background] attemptsummarystep ${i+1} round (message ${e}-${t-1})`);let u=await wt(l,I,n,{signal:de,timeout:15e3});if(!u){r.debug(`[Background] summary failed,downgraded to weight-based trimming`);break}let d=(A?.match(/Round \d+:/g)?.length||0)+1;A=(A||``)+`Round ${d}: ${u}\n`;let f=s.findIndex(e=>e.role===`user`),p={role:`user`,content:`[History Summary] The following is a summary of previous steps:\n${A.trim()}`,_isSummary:!0},m=s.findIndex(e=>e._isSummary);if(m>=0){s.splice(m,1);let e=s.findIndex(e=>e.role===`user`);s.splice(e+1,0,p)}else s.splice(f+1,0,p);let h=s.findIndex(e=>e===l[0]);h>=0&&s.splice(h,l.length);let g=c([...o,...s]);r.debug(`[Background] summary complete: ${a} → ${g} tokens (${l.length} → 1summary)`)}if(t=c([...o,...s]),t>e){r.debug(`[Background] still exceeding after summary (${t} > ${e}),enablefallbacktrimming`);let n=e=>e._reflection?3:e.role===`tool`?2:1;for(;s.length>0&&!(c([...o,...s])<=e);){let e=-1,t=0;for(let r=0;r<s.length;r++){let i=n(s[r]);if(i>t&&(t=i,e=r),t>=3)break}(e<0||t===0)&&(e=0);let r=s.splice(e,1)[0];if(r?.role===`assistant`&&r.tool_calls)for(;s.length>0&&s[e]?.role===`tool`;)s.splice(e,1);else if(r?.role===`tool`)for(let t=e-1;t>=0&&s[t]?.role===`assistant`&&s[t]?.tool_calls;t--){let e=s[t+1];(!e||e.role!==`tool`)&&delete s[t].tool_calls}}}T=[...o,...s];let l=c(T);r.debug(`[Background] ReAct Token trimming: ${a} → ${l} tokens (${i} → ${T.length} )`)},M=[...m],N=null,le=0,P=1500;async function F(e=``,t=!1){if(d){r.debug(`[Background] saveCheckpointNow skip (subtask): reason=${e}`);return}if(!u){r.warn(`[Background] saveCheckpointNow skip (sessionId empty)`);return}let i=Date.now();if(!t&&i-le<P){r.debug(`[Background] saveCheckpointNow throttlestreamskip: reason=${e}, since last save ${i-le}ms < ${P}ms`);return}le=i,r.debug(`[Background] saveCheckpointNow start saving: sessionId=${u}, reason=${e}, force=${t}, iteration=${g}, messages=${T.length}, callId=${h}`),await Rt(u,{currentMessages:T.map(e=>{let t={...e};return typeof t.content==`function`&&(t.content=String(t.content)),t}),executionLog:[...M],iteration:g,globalIteration:{value:p?.value||g},subtaskPlan:N,currentSubtaskIndex:null,totalReflectionRounds:v,model:n||I?.modelName,apiParams:c,taskContext:null,tabId:o,callId:h,interruptedReason:e||`in_progress`})}ge(u||o),ye(o);let ue=u?_e(u,!d):null,de=ue?.signal,I=await z(),fe=await Ee();c&&c.imageApiBase&&(I.apiBase=c.imageApiBase),c&&c.imageApiKey&&(I.apiKey=c.imageApiKey);let L=I.reactConfig,he=L.maxIterations,ve=L.apiTimeout,be=L.loopTimeout,xe=L.toolTimeout,Se=L.clarifyTimeout,Ce=d&&(d.subtaskId||d.type===`subagent`),we=Ce?{...I.streamConfig,streamEnabled:!1}:I.streamConfig;r.debug(`[Background] reactLoop configuration:`,L),r.debug(`[Background] reactLoop received tool column table:`,i.map(e=>e.function.name),`count:`,i.length),r.debug(`[Background] reactLoop tasktext:`,d?`subtask ${d.subtaskId||` no `} (${d.subtaskName||`maintask`})`:` no `);let Te=0,B=``,V=new Map;function H(e,t){try{let n=Date.now();if(typeof f==`function`&&f([...M]),e===B&&n-Te<200)return;Te=n,B=e;let i=[];for(let e of M){let t=V.get(e.id);(!t||t.status!==e.status||t.nodeName!==e.nodeName)&&(i.push(e),V.set(e.id,{status:e.status,nodeName:e.nodeName}))}let a={type:`EXECUTION_STATUS_UPDATE`,nodeName:e,status:t,callId:h,executionLog:i};u&&(a.sessionId=u),chrome.runtime.sendMessage(a).catch(e=>{r.debug(`[Background] sendexecution statusupdate failed:`,e.message)})}catch(e){r.debug(`[Background] sendexecution statusupdate exception:`,e.message)}}let De=Date.now(),Oe=0,U=null,W=!1;H(t(`reactLoop.preparing`),`processing`),await F(`initial`,!0);function ke(){W||(U=Date.now(),W=!0,r.debug(`[Background] overall looptimeoutpaused`))}function Ae(){let e=Date.now()-De;return be+Oe-e}function G(){if(W&&U!==null){let e=Date.now()-U;Oe+=e,U=null,W=!1,r.debug(`[Background] overall looptimeoutrestored,pause duration:`,Math.round(e/1e3),`s,remaining time:`,Math.round(Ae()/1e3),`s`)}}ge(u||o);try{for(;g<he;){if(R(o)||u&&R(u))throw Lt(t(`bg.reactCancelled`),M);let e=Date.now()-De,f=be+Oe;if(e>f)throw Lt(t(`reactLoop.loopTimeout`,{timeout:be}),M);g++,pe(u);let m=f-e;r.debug(`[Background] ReAct loopstep ${g} times,remaining time: ${Math.round(m/1e3)}s (paused: ${Math.round(Oe/1e3)}s)`);let A,le=Date.now(),P=O(T);for(let e=0;e<P.length-1;e++)P[e]={...P[e],content:w(P[e].content)};let he=crypto.randomUUID(),ge=me(u),_e=i.some(e=>e.function?.name===`plan_task`),ye=i;_e&&r.debug(`[Background] current iterationcontains plan_task,using Agent limittool into task decomposition,tool count :`,ye.length);let Te=y(P),Ee=_(Te),B=x(n||I.modelName,0,fe.customModelMap),U=S(JSON.stringify(ye.map(e=>{let{id:t,...n}=e;return n}))),W=_(U),Ae=Ee+W+4096,K=Te+U,je=E(Ae,B);if(je.level!==`safe`&&(r.warn(`[Background] context pressure: ${je.level} (${Math.round(je.ratio*100)}% used, message: ${Ee}, tool: ${W}, estimated total: ${Ae}/${B} tokens)`),je.level===`critical`||Ae>B*.85)){let e=ie(n||`default`),t=Math.floor(e*.75);r.warn(`[Background] context pressure too high,maindynamictrimmingmessage: current ${Ee} tokens → target budget ${t}`);let i=ce(T,Math.max(t,2e3));if(i.trimmedCount>0){T=i.messages,P=O(T);for(let e=0;e<P.length-1;e++)P[e]={...P[e],content:w(P[e].content)};r.warn(`[Background] maindynamictrimmingcomplete: ${i.trimmedCount} messageremove,remaining ${T.length} , ${y(P)} tokens`)}}M.push({id:he,iteration:g,globalIteration:ge,timestamp:new Date().toISOString(),status:`processing`,nodeType:`api_call`,nodeName:t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),apiRequest:{messageCount:P.length,toolCount:ye.length}}),H(t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),`processing`);let Me;try{let e=`${I.apiBase}/chat/completions`;r.debug(`[Background] API requesttool count count :`,ye.length);let i={model:n||I.modelName,messages:b(P),tools:ye.map(e=>{let{id:t,...n}=e;return n}),stream:we.streamEnabled!==!1};i.stream&&(i.stream_options={include_usage:!0}),r.debug(`[Background] API requestbody stream mode:`,i.stream,`tool count count :`,i.tools.length,`messagecount:`,i.messages.length,`model:`,i.model),c.temperature!==void 0&&(i.temperature=c.temperature),c.top_p!==void 0&&(i.top_p=c.top_p);let a=Math.max(m-3e4,ve);Me=setTimeout(()=>{r.warn(`[Background] ⚠️ API call outertimeoutprotection triggered (${Math.round(a/1e3)}s),force abort`),ue?.abort()},a),we.streamEnabled!==!1&&(chrome.runtime.sendMessage({type:`STREAM_START`,sessionId:u,callId:h}).catch(()=>{}),r.debug(`[Background] STREAM_START sent (API call with before )`));let o=await dr(e,{method:`POST`,headers:{Authorization:`Bearer ${I.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(i),signal:de},ve,L.apiRetryCount,L.apiRetryBaseDelay,(e,t)=>{r.warn(`[Background] API retry ${e} times after :`,t.message)});if(clearTimeout(Me),!o.ok){let e=await o.text();throw r.error(`[Background] API response error:`,o.status,e),Error(`HTTP error! status: ${o.status}, message: ${e.substring(0,500)}`)}if(we.streamEnabled!==!1&&o.body){r.debug(`[Background] enteringstreamingmode,streamEnabled:`,we.streamEnabled);let e=new ct(u,we,{callId:h,preStarted:!0}),t=await lt(o.body.getReader(),e,de);r.debug(`[Background] streaming API responsecomplete,content length:`,t.content.length,`tool_calls:`,t.toolCalls?.length,`usage:`,t.usage);let n=t.toolCalls?t.toolCalls.map(e=>({...e,id:e.id||`tc_fb_${crypto.randomUUID().slice(0,8)}`})):null;A={choices:[{message:{role:`assistant`,content:t.content||``,reasoning_content:t.reasoningContent,...n?{tool_calls:n}:{}},finish_reason:t.status===`tool_calls`?`tool_calls`:t.truncated?`length`:`stop`}],usage:t.usage}}else{let e=await o.text();r.debug(`[Background] API responsestate:`,o.status,`originaltext length:`,e.length,`preview:`,e.substring(0,200));try{A=JSON.parse(e)}catch(n){throw r.error(`[Background] JSON parse failed:`,n),r.error(`[Background] originalresponse:`,e),Error(t(`reactLoop.apiInvalidJson`,{status:o.status,error:n.message,preview:e.substring(0,100)}))}let n=A.choices?.[0]?.message?.tool_calls;if(n&&n.length>0){let e=n.map(e=>({...e,id:e.id||`tc_fb_${crypto.randomUUID().slice(0,8)}`}));A.choices[0].message.tool_calls=e}}}catch(e){clearTimeout(Me);let i=e.name===`AbortError`;i?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e);let a=M.findIndex(e=>e.id===he);throw a!==-1&&(M[a]={...M[a],duration:Date.now()-le,status:i?`cancelled`:`failed`,apiRequest:{...M[a].apiRequest,model:n||I.modelName,temperature:c.temperature,top_p:c.top_p,messageCount:P.length,toolCount:ye.length},error:i?t(`reactLoop.userCancelled`):e.message}),Lt(i?t(`bg.requestCancelled`):e.message,M)}let Ne=Date.now()-le,q=A.choices?.[0]?.message;A.choices?.[0]?.finish_reason===`length`&&r.warn(`[Background] API response reason token limit truncated (finish_reason: length),contentmay be incomplete`);let Pe=M.findIndex(e=>e.id===he);if(Pe!==-1&&(M[Pe]={...M[Pe],duration:Ne,status:`success`,thought:q?.content||``,action:q?.tool_calls?.length>0?{name:q.tool_calls[0].function?.name||q.tool_calls[0].name,params:(()=>{try{return JSON.parse(q.tool_calls[0].function?.arguments||`{}`)}catch{return{}}})()}:null,apiRequest:{...M[Pe].apiRequest,model:n||I.modelName,temperature:c.temperature,top_p:c.top_p,messageCount:P.length,toolCount:ye.length},apiResponse:{finishReason:A.choices?.[0]?.finish_reason,tokenUsage:A.usage}}),A.usage&&(yt({sessionId:u,model:n||I.modelName,usage:A.usage,callType:`react_loop`}).catch(()=>{}),K>0&&A.usage.prompt_tokens>0)){ne(K,A.usage.prompt_tokens);let e=te();e.active&&r.debug(`[Background] Tokencalibration activated: factor=${e.factor.toFixed(3)}, samples=${e.samples}`)}if(H(t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),`success`),q?.tool_calls&&q.tool_calls.length>0){r.debug(`[Background] recei to tool call:`,q.tool_calls);let e=JSON.stringify(q.tool_calls.map(e=>({name:e.function?.name||e.name,args:typeof e.function?.arguments==`string`?(()=>{try{return JSON.parse(e.function.arguments)}catch{return e.function.arguments}})():e.function?.arguments||{}})));r.debug(`[Background] this roundtool callinput fingerprint:`,e.substring(0,200)),T.push(q),await se();let d=[],f=L.reflection;async function m(e,o,u,m,g,_,v,y,b){if(R(o)||_&&R(_))throw Lt(t(`bg.reactCancelled`),y);let x=e.function?.name||e.name,w=Date.now(),T=e.function?.arguments;r.debug(`[Background] executeSingleToolCall recei to tool call:`,JSON.stringify({name:x,argsType:typeof T,argsRaw:typeof T==`string`?T.substring(0,200):JSON.stringify(T).substring(0,200),id:e.id}));let E=(()=>{if(!T)return{};if(typeof T==`object`)return T;try{return JSON.parse(T||`{}`)}catch{return{}}})(),O=e.id||`tc_fallback_${crypto.randomUUID()}`,ee=a.has(x),te=l[x]?.includes(E.action);if((ee||te)&&L.toolConfirmationEnabled){if(_&&Pt.has(_))r.debug(`[Background] session ${_} got currenttaskallow,skip confirm: ${x}`);else{ke(),chrome.runtime.sendMessage({type:`TOOL_CONFIRM_START`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send TOOL_CONFIRM_START message failed:`,e.message)});let n;try{n=await It(x,E,o,_)}finally{G(),chrome.runtime.sendMessage({type:`TOOL_CONFIRM_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send TOOL_CONFIRM_END message failed:`,e.message)})}if(!n){let n=crypto.randomUUID();return y.push({id:n,iteration:v,timestamp:new Date().toISOString(),status:`cancelled`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:t(`reactLoop.userDenied`)}),H(t(`reactLoop.toolExec`,{name:x}),`cancelled`),b.push({role:`tool`,content:`The user declined this operation.`,tool_call_id:O}),await se(),{toolCall:e,result:{success:!1,content:`The user declined this operation.`,error:`user_denied`},toolResultStr:`The user declined this operation.`,toolLogEntry:{id:n,iteration:v,timestamp:new Date().toISOString(),status:`cancelled`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:t(`reactLoop.userDenied`)}}}}}let k=`${x}:${JSON.stringify(E)}`;if(D.has(k)){let e=D.get(k);if(Date.now()-e.timestamp<6e4){if(s.has(x))return{...e,fromCache:!0};D.clear()}else D.delete(k)}s.has(x)||D.clear(),await new Promise(e=>setTimeout(e,0));let ne=crypto.randomUUID();y.push({id:ne,iteration:v,timestamp:new Date().toISOString(),status:`processing`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExecStart`,{name:x})}),H(t(`reactLoop.toolExecStart`,{name:x}),`processing`),x===`clarify_question`&&(ke(),chrome.runtime.sendMessage({type:`CLARIFY_START`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_START message failed:`,e.message)}));let A;try{if(A=await qt(e,o,u,m,g,_),x===`clarify_question`){G(),chrome.runtime.sendMessage({type:`CLARIFY_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_END message failed:`,e.message)}),r.debug(`[Background] clarification complete,re-filteringtool...`);try{let e=await Ln(),t=await z(),a=t.reactConfig.enableToolPreselect,o=t.reactConfig.preselectMinToolCount||3;if(a&&e.length>o){let t=await vt(b,n,e,c);t.type===`tools`&&(i=t.tools,j=null,r.debug(`[Background] clarification after toolre-filtercomplete:`,i.map(e=>e.function.name))),t.executionLog&&y.push(...t.executionLog)}else a||r.debug(`[Background] toolpre-filterclosed,after clarification, notre-filter`)}catch(e){r.warn(`[Background] clarification after toolre-filter failed, continue withcurrenttoolset:`,e.message)}}let a;a=typeof A==`string`?A:A&&typeof A==`object`&&`content`in A?A.content??JSON.stringify(A):JSON.stringify(A);let l=A&&A.success!==!1,T=S(a),ee=!1,te=a;if(T>ae){let e=re(a,ae);r.debug(`[Background] tool ${x} result truncated: ${T} → ${S(e)} tokens`),ee=!0,te=e,a=e}Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:O,toolName:x,success:l,content:l?te:A?.error||te,truncated:ee,duration:Date.now()-w}}).catch(()=>{});let ie=y.filter(e=>e.nodeType===`tool_exec`&&e.iteration===v).sort((e,t)=>y.indexOf(e)-y.indexOf(t)),M=0;for(let e=ie.length-1;e>=0&&ie[e].status===`failed`;e--)M++;if(y.filter(e=>e.nodeType===`reflection`&&e.reflectionType===`tool`).length<(f?.toolReflection?.maxPerIteration||2)&&Dt(a,M,f)&&d.push({toolName:x,toolResultStr:a,toolCallParams:E,toolCallId:O,priority:Et(x,a,M)}),x===`plan_task`&&A&&A.success&&A.data){N=A.data,r.debug(`[Background] received taskplanresult:`,JSON.stringify(N));let e=JSON.stringify({success:!0,message:`Task planning complete. Decomposed into ${N.subtasks.length} subtasks.`,data:N});b.push({role:`tool`,content:e,tool_call_id:O}),await se();let a=y.findIndex(e=>e.id===ne);a!==-1&&(y[a]={...y[a],duration:Date.now()-w,status:`success`,nodeName:t(`reactLoop.taskPlanDone`),action:{name:x,params:E},observation:t(`reactLoop.subtaskCount`,{count:N.subtasks.length}),subtaskCount:N.subtasks.length,strategy:N.strategy}),H(t(`reactLoop.taskPlanDone`),`success`);let l=q.tool_calls.findIndex(e=>e.id===O);if(l!==-1&&l<q.tool_calls.length-1){for(let e=l+1;e<q.tool_calls.length;e++){let n=q.tool_calls[e],i=n.function?.name||n.name||`unknown`,a=n.id||`tc_fallback_${crypto.randomUUID()}`;r.debug(`[Background] resend skiptool STREAM_TOOL_RESULT:`,i,`id:`,a),b.push({role:`tool`,content:JSON.stringify({success:!1,message:`Skipped: plan_task has decomposed subtasks; other tool calls in this round will not be executed.`}),tool_call_id:a}),Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:a,toolName:i,success:!1,content:t(`reactLoop.skippedAfterPlanTask`),truncated:!1,duration:0}}).catch(()=>{})}await se()}let u=await Wt(N,n,i,o,c,_,y,p,L.reflection,I,V,h);if(R(o)||_&&R(_))throw Lt(t(`bg.reactCancelled`),y);let d=3e3,f=u.map((e,t)=>{let n=typeof e.result==`string`?e.result:JSON.stringify(e.result),r=S(n)>d?C(n,d):n;return`Subtask ${t+1}: ${e.subtaskName}\nResult: ${r}`}).join(`
96
+ }`;try{let e=`${o.apiBase}/chat/completions`,i=s.model||a||o.modelName,c=await pr(e,{method:`POST`,headers:{Authorization:`Bearer ${o.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify({model:i,messages:[{role:`system`,content:`You are a strict quality evaluator. Output the evaluation result in JSON format; do not include markdown code block markers.`},{role:`user`,content:_}],stream:!1,temperature:s.temperature||.3,max_tokens:s.maxTokens||1024})},3e4,1,1e3);if(!c.ok)throw Error(`Subtask reflection API error: ${c.status}`);let u=await c.json(),m=u.choices?.[0]?.message?.content||``,h=kt(m),g=Date.now()-f;return p.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`success`,nodeType:`reflection`,nodeName:t(`reflection.subtaskNodeName`,{name:l}),reflectionType:`subtask`,overallScore:h.overallScore,dimensions:h.dimensions,issues:h.issues,suggestions:h.suggestions,prompt:_,rawContent:m,apiRequest:{model:i,messageCount:2,temperature:s.temperature||.3,maxTokens:s.maxTokens||1024},apiResponse:{tokenUsage:u.usage||null},duration:g}),r.debug(`[Background] subtask reflectioncomplete: ${l}, score: ${h.overallScore}/10, elapsed: ${g}ms`),u.usage&&yt({sessionId:d,model:i,usage:u.usage,callType:`subtask_reflection`}).catch(()=>{}),{score:h.overallScore,refinedContent:h.refinedAnswer&&h.refinedAnswer!==n?h.refinedAnswer:null,reflectionLog:p}}catch(e){r.warn(`[Background] subtask reflection failed:`,e.message);let n=Date.now()-f;return p.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`failed`,nodeType:`reflection`,nodeName:t(`reflection.subtaskNodeName`,{name:l}),reflectionType:`subtask`,error:e.message,duration:n}),{score:null,refinedContent:null,reflectionLog:p}}}e(`zh`,{reactLoop:{apiCallNode:`API调用 (第{count}次{subtask})`,apiCallSubtask:`, 子任务第{iteration}次`,preparing:`准备开始执行...`,toolExec:`工具执行:{name}`,toolExecStart:`执行工具: {name}`,taskPlanDone:`任务规划完成`,executionDone:`执行完成`,userDenied:`用户拒绝了此操作`,subtaskRolledBack:`子任务 {name} (已回滚)`,subtaskRollbackFailed:`子任务 {name} (回滚失败)`,subtaskCount:`已拆解为 {count} 个子任务`,toolReflection:`工具反思: {name}`,subtaskNode:`子任务 {index}: {name}`,subtaskCompleted:`子任务 {index}: {name} (完成)`,subtaskFailed:`子任务 {index}: {name} (失败)`,userCancelled:`用户取消`,skippedAfterPlanTask:`已跳过(plan_task 已拆分子任务,本轮其他工具调用不再执行)`,toolError:`错误: {message}`,loopTimeout:`ReAct 循环总超时 ({timeout}ms,不含澄清等待时间)`,apiInvalidJson:`API 响应不是有效的 JSON (HTTP {status}): {error}。响应前100字符: {preview}`,infiniteLoopDetected:`连续{count}次执行完全相同的工具调用(入参和返参均相同),疑似陷入死循环,已自动终止。请更换策略或缩小任务范围后重试。`,maxIterationsExceeded:`ReAct 循环超过最大迭代次数 ({maxIterations})`,toolTimeout:`工具执行超时 ({timeout}ms): {tool}`,toolAborted:`工具执行已被用户终止: {tool}`,jsonParseFailed:`JSON 解析失败 (HTTP {status}): {error}。响应前100字符: {preview}`}}),e(`en`,{reactLoop:{apiCallNode:`API Call (#{count}{subtask})`,apiCallSubtask:`, Subtask #{iteration}`,preparing:`Preparing to execute...`,toolExec:`Tool Exec:{name}`,toolExecStart:`Executing: {name}`,taskPlanDone:`Task planning completed`,executionDone:`Execution completed`,userDenied:`User denied this operation`,subtaskRolledBack:`Subtask {name} (rolled back)`,subtaskRollbackFailed:`Subtask {name} (rollback failed)`,subtaskCount:`Broken down into {count} subtasks`,toolReflection:`Tool Reflection: {name}`,subtaskNode:`Subtask {index}: {name}`,subtaskCompleted:`Subtask {index}: {name} (completed)`,subtaskFailed:`Subtask {index}: {name} (failed)`,skippedAfterPlanTask:`Skipped (plan_task has decomposed subtasks, other tool calls in this round are no longer executed)`,toolError:`Error: {message}`,loopTimeout:`ReAct loop total timeout ({timeout}ms, excluding clarification wait time)`,apiInvalidJson:`API response is not valid JSON (HTTP {status}): {error}. First 100 chars: {preview}`,infiniteLoopDetected:`Executed the exact same tool call {count} times in a row (both inputs and outputs identical), likely stuck in an infinite loop. Automatically terminated. Please change strategy or narrow the task scope and retry.`,maxIterationsExceeded:`ReAct loop exceeded maximum iterations ({maxIterations})`,toolTimeout:`Tool execution timed out ({timeout}ms): {tool}`,toolAborted:`Tool execution was aborted by user: {tool}`,jsonParseFailed:`JSON parse failed (HTTP {status}): {error}. First 100 chars: {preview}`}});var Nt=new Set,Pt=new Set,Ft={manage_cookies:`sensitiveTool.manage_cookies`,clear_data:`sensitiveTool.clear_data`,download_file:`sensitiveTool.download_file`,manage_tab:`sensitiveTool.manage_tab`,agent_file:`sensitiveTool.agent_file`};async function It(e,n,i,a){let o=Ft[e],s=o?t(o):e,c=3e5;r.debug(`[Background] requesting user confirmation for tool operation: ${e}`,n);let l=``;if(e===`manage_tab`&&n.action===`close`&&n.tabId!==void 0)try{let e=await chrome.tabs.get(parseInt(n.tabId,10));l=t(`sensitiveTool.tabInfo`,{title:e.title||t(`sensitiveTool.untitled`),url:e.url||t(`sensitiveTool.unknownUrl`)})}catch(e){l=t(`sensitiveTool.tabInfoError`,{error:e.message})}return new Promise(i=>{let o=t=>{t.type===`TOOL_CONFIRMATION_RESPONSE`&&t.toolCallId===e&&(chrome.runtime.onMessage.removeListener(o),clearTimeout(u),r.debug(`[Background] userconfirmresult: ${e} = ${t.confirmed}, scope: ${t.scope}`),t.confirmed&&t.scope===`loop`&&(Pt.add(a),r.debug(`[Background] session ${a} set as current taskallow`)),i(t.confirmed))};chrome.runtime.onMessage.addListener(o);let u=setTimeout(()=>{chrome.runtime.onMessage.removeListener(o),r.debug(`[Background] confirmtimeout,defaultdeny: ${e}`),i(!1)},c);chrome.runtime.sendMessage({type:`SHOW_CONFIRM_DIALOG`,data:{toolName:e,toolLabel:s,args:n,toolCallId:e,sessionId:a,timeout:c,message:l?t(`dialog.confirmAction`,{name:s})+l:void 0}}).catch(e=>{r.debug(`[Background] sendconfirm dialogmessage failed:`,e.message),chrome.runtime.onMessage.removeListener(o),clearTimeout(u),i(!0)})})}function Lt(e,t){let n=Error(e);return n.executionLog=t,n}var Rt=1e3;function zt(e,t,n=Rt){if(!e||e.length<=n)return 0;let i=e.length-n,a=0;for(let n=0;n<e.length&&a<i;n++)e[n].status!==`processing`&&(t&&t.delete(e[n].id),e.splice(n,1),a++,n--);return a>0&&r.debug(`[Background] executionLog memory trimmed: removed ${a} terminal old entries, remaining ${e.length}`),a}async function Bt(e,t){if(e)try{if(await D({sessionId:e,...t})){r.debug(`[Background] checkpoint saved (sessionId=${e}, iteration=${t.iteration}, reason=${t.interruptedReason})`);try{let t=await P(e);t?r.debug(`[Background] checkpoint write verifypassed,message=${t.currentMessages?.length||0}`):r.error(`[Background] ⚠️ checkpoint write returned successfulbut read-back empty!sessionId=${e}, possibly is DB store does not exist or transaction not committed`)}catch(e){r.error(`[Background] checkpoint read-backverify failed:`,e.message)}}else r.error(`[Background] checkpoint save returned false (sessionId=${e}, iteration=${t.iteration}), possibly is reactCheckpoints store not found,DB upgrade blocked`)}catch(e){r.error(`[Background] save checkpoint failed:`,e.message,e.stack)}}async function Vt(e){if(e)try{await ie(e),r.debug(`[Background] checkpoint cleaned (sessionId=${e})`)}catch(e){r.warn(`[Background] cleanup checkpoint failed:`,e.message)}}function Ht(e){if(!e||e.length===0)return e;let t=[],n=0;for(;n<e.length;){let i=e[n];if(i.role===`tool`){let t=n>0?e[n-1]:null;if(!t||t.role!==`assistant`||!t.tool_calls){r.warn(`[Background] cleanupIncompleteMessagePairs: skip orphaned tool message (index=`+n+`)`),n++;continue}}if(i.role===`assistant`&&i.tool_calls&&i.tool_calls.length>0){let a=n+1<e.length?e[n+1]:null;if(!a||a.role!==`tool`){r.warn(`[Background] cleanupIncompleteMessagePairs: orphaned assistant(tool_calls),clear tool_calls (index=`+n+`)`),t.push({...i,tool_calls:void 0}),n++;continue}}t.push(i),n++}return t.length!==e.length&&r.debug(`[Background] cleanupIncompleteMessagePairs: cleanup complete,message:`,e.length,`→`,t.length),t}async function Ut(e,t=``,n=null){if(!e)return null;let i=await P(e);if(!i){r.warn(`[Background] not found sessionId=${e} checkpoint, no way to restore`);try{let e=await le();e.length===0?r.warn(`[Background] IndexedDB contains no checkpoint record (may never have been saved successful)`):(r.warn(`[Background] current IndexedDB checkpoint column table:`,e.map(e=>({sessionId:e.sessionId,iteration:e.iteration,updatedAt:new Date(e.updatedAt).toISOString(),reason:e.interruptedReason}))),`${e.length}${e.map(e=>e.sessionId).join(`, `)}`)}catch(e){r.error(`[Background] read checkpoint column table failed:`,e),`${e.message}`}return null}r.debug(`[Background] from checkpoint restore ReAct loop: sessionId=${e}, iteration=${i.iteration}, messages=${i.currentMessages?.length}, userGuidance=${t?` has `:` no `}, resumeCallId=${n}`);let a=JSON.parse(JSON.stringify(i.currentMessages||[]));if(a=Ht(a),t&&t.trim()){let e={role:`user`,content:`[Task Resume Notice] The task was previously interrupted during execution and is now resuming from the checkpoint.\n\nAdditional user instructions: ${t.trim()}\n\nPlease continue completing the task based on the previous tool call results, taking the above instructions into account. Do not repeat already completed steps.`};a.push(e),r.debug(`[Background] injected user additionaldescription,messagetotal:`,a.length)}else a.push({role:`user`,content:`[Task Resume Notice] The task was previously interrupted during execution and is now resuming from the checkpoint. Please continue completing the task based on the previous tool call results. Do not repeat already completed steps.`}),r.debug(`[Background] injected defaultrestoreprompt,messagetotal:`,a.length);let o=await Wt(a,i.model,await zn(),i.tabId,i.apiParams||{},e,null,null,i.globalIteration||{value:i.iteration||0},i.executionLog||[],n||i.callId||null);return await Vt(e),o}async function Wt(e,n,i,o,c={},u=null,d=null,f=null,p={value:0},m=[],h=null){u&&Nt.add(u);let g=0,v=0,T=[...e],D=new Map,ee=null,k=0,A=null,j=null,ie=e=>{if(j===null){let t=S(typeof T[0]?.content==`string`?T[0].content:JSON.stringify(T[0]?.content||``)),n=S(JSON.stringify(i.map(e=>{let{id:t,...n}=e;return n}))),a=x(e,0,fe.customModelMap);j=a-t-n-4096-2e3,j<1e3&&(r.warn(`[Background] ReAct Token budget too low: ${j},using minimumbudget 1000`),j=1e3),r.debug(`[Background] ReAct Token budget: ${j} tokens (model: ${e}, actualsystem promptword: ${t}, actual tooldefinition: ${n}, context window: ${a})`)}return j},ae=6e3,oe=5e4,se=async()=>{let e=ie(n||`default`),t=_(y(T));if(t<=e)return;let i=T.length,a=t,o=T[0]?.role===`system`?[T[0]]:[],s=o.length?[...T.slice(1)]:[...T],c=e=>{let t=e.map(e=>({...e,content:w(e.content)}));return _(y(t))};for(let i=0;i<3&&(t=c([...o,...s]),!(t<=e));i++){let e=-1,t=-1;for(let n=0;n<s.length;n++)if(s[n].role===`assistant`&&Array.isArray(s[n].tool_calls)&&s[n].tool_calls.length>0){for(e=n,t=n+1;t<s.length&&s[t].role===`tool`;)t++;break}if(e===-1)break;let l=s.slice(e,t);r.debug(`[Background] attemptsummarystep ${i+1} round (message ${e}-${t-1})`);let u=await wt(l,I,n,{signal:de,timeout:15e3});if(!u){r.debug(`[Background] summary failed,downgraded to weight-based trimming`);break}let d=(A?.match(/Round \d+:/g)?.length||0)+1;A=(A||``)+`Round ${d}: ${u}\n`;let f=s.findIndex(e=>e.role===`user`),p={role:`user`,content:`[History Summary] The following is a summary of previous steps:\n${A.trim()}`,_isSummary:!0},m=s.findIndex(e=>e._isSummary);if(m>=0){s.splice(m,1);let e=s.findIndex(e=>e.role===`user`);s.splice(e+1,0,p)}else s.splice(f+1,0,p);let h=s.findIndex(e=>e===l[0]);h>=0&&s.splice(h,l.length);let g=c([...o,...s]);r.debug(`[Background] summary complete: ${a} → ${g} tokens (${l.length} → 1summary)`)}if(t=c([...o,...s]),t>e){r.debug(`[Background] still exceeding after summary (${t} > ${e}),enablefallbacktrimming`);let n=e=>e._reflection?3:e.role===`tool`?2:1;for(;s.length>0&&!(c([...o,...s])<=e);){let e=-1,t=0;for(let r=0;r<s.length;r++){let i=n(s[r]);if(i>t&&(t=i,e=r),t>=3)break}(e<0||t===0)&&(e=0);let r=s.splice(e,1)[0];if(r?.role===`assistant`&&r.tool_calls)for(;s.length>0&&s[e]?.role===`tool`;)s.splice(e,1);else if(r?.role===`tool`)for(let t=e-1;t>=0&&s[t]?.role===`assistant`&&s[t]?.tool_calls;t--){let e=s[t+1];(!e||e.role!==`tool`)&&delete s[t].tool_calls}}}T=[...o,...s];let l=c(T);r.debug(`[Background] ReAct Token trimming: ${a} → ${l} tokens (${i} → ${T.length} )`)},M=[...m],N=null,le=0,P=1500;async function F(e=``,t=!1){if(d){r.debug(`[Background] saveCheckpointNow skip (subtask): reason=${e}`);return}if(!u){r.warn(`[Background] saveCheckpointNow skip (sessionId empty)`);return}let i=Date.now();if(!t&&i-le<P){r.debug(`[Background] saveCheckpointNow throttlestreamskip: reason=${e}, since last save ${i-le}ms < ${P}ms`);return}le=i,zt(M,V),r.debug(`[Background] saveCheckpointNow start saving: sessionId=${u}, reason=${e}, force=${t}, iteration=${g}, messages=${T.length}, callId=${h}`),await Bt(u,{currentMessages:T.map(e=>{let t={...e};return typeof t.content==`function`&&(t.content=String(t.content)),t}),executionLog:[...M],iteration:g,globalIteration:{value:p?.value||g},subtaskPlan:N,currentSubtaskIndex:null,totalReflectionRounds:v,model:n||I?.modelName,apiParams:c,taskContext:null,tabId:o,callId:h,interruptedReason:e||`in_progress`})}ge(u||o),ye(o);let ue=u?_e(u,!d):null,de=ue?.signal,I=await z(),fe=await Ee();c&&c.imageApiBase&&(I.apiBase=c.imageApiBase),c&&c.imageApiKey&&(I.apiKey=c.imageApiKey);let L=I.reactConfig,he=L.maxIterations,ve=L.apiTimeout,be=L.loopTimeout,xe=L.toolTimeout,Se=L.clarifyTimeout,Ce=d&&(d.subtaskId||d.type===`subagent`),we=Ce?{...I.streamConfig,streamEnabled:!1}:I.streamConfig;r.debug(`[Background] reactLoop configuration:`,L),r.debug(`[Background] reactLoop received tool column table:`,i.map(e=>e.function.name),`count:`,i.length),r.debug(`[Background] reactLoop tasktext:`,d?`subtask ${d.subtaskId||` no `} (${d.subtaskName||`maintask`})`:` no `);let Te=0,B=``,V=new Map;function H(e,t){try{zt(M,V);let n=Date.now();if(typeof f==`function`&&f([...M]),e===B&&n-Te<200)return;Te=n,B=e;let i=[];for(let e of M){let t=V.get(e.id);(!t||t.status!==e.status||t.nodeName!==e.nodeName)&&(i.push(e),V.set(e.id,{status:e.status,nodeName:e.nodeName}))}let a={type:`EXECUTION_STATUS_UPDATE`,nodeName:e,status:t,callId:h,executionLog:i};u&&(a.sessionId=u),chrome.runtime.sendMessage(a).catch(e=>{r.debug(`[Background] sendexecution statusupdate failed:`,e.message)})}catch(e){r.debug(`[Background] sendexecution statusupdate exception:`,e.message)}}let De=Date.now(),Oe=0,U=null,W=!1;H(t(`reactLoop.preparing`),`processing`),await F(`initial`,!0);function ke(){W||(U=Date.now(),W=!0,r.debug(`[Background] overall looptimeoutpaused`))}function Ae(){let e=Date.now()-De;return be+Oe-e}function G(){if(W&&U!==null){let e=Date.now()-U;Oe+=e,U=null,W=!1,r.debug(`[Background] overall looptimeoutrestored,pause duration:`,Math.round(e/1e3),`s,remaining time:`,Math.round(Ae()/1e3),`s`)}}ge(u||o);try{for(;g<he;){if(R(o)||u&&R(u))throw Lt(t(`bg.reactCancelled`),M);let e=Date.now()-De,f=be+Oe;if(e>f)throw Lt(t(`reactLoop.loopTimeout`,{timeout:be}),M);g++,pe(u);let m=f-e;r.debug(`[Background] ReAct loopstep ${g} times,remaining time: ${Math.round(m/1e3)}s (paused: ${Math.round(Oe/1e3)}s)`);let A,le=Date.now(),P=O(T);for(let e=0;e<P.length-1;e++)P[e]={...P[e],content:w(P[e].content)};let he=crypto.randomUUID(),ge=me(u),_e=i.some(e=>e.function?.name===`plan_task`),ye=i;_e&&r.debug(`[Background] current iterationcontains plan_task,using Agent limittool into task decomposition,tool count :`,ye.length);let Te=y(P),Ee=_(Te),B=x(n||I.modelName,0,fe.customModelMap),U=S(JSON.stringify(ye.map(e=>{let{id:t,...n}=e;return n}))),W=_(U),Ae=Ee+W+4096,K=Te+U,je=E(Ae,B);if(je.level!==`safe`&&(r.warn(`[Background] context pressure: ${je.level} (${Math.round(je.ratio*100)}% used, message: ${Ee}, tool: ${W}, estimated total: ${Ae}/${B} tokens)`),je.level===`critical`||Ae>B*.85)){let e=ie(n||`default`),t=Math.floor(e*.75);r.warn(`[Background] context pressure too high,maindynamictrimmingmessage: current ${Ee} tokens → target budget ${t}`);let i=ce(T,Math.max(t,2e3));if(i.trimmedCount>0){T=i.messages,P=O(T);for(let e=0;e<P.length-1;e++)P[e]={...P[e],content:w(P[e].content)};r.warn(`[Background] maindynamictrimmingcomplete: ${i.trimmedCount} messageremove,remaining ${T.length} , ${y(P)} tokens`)}}M.push({id:he,iteration:g,globalIteration:ge,timestamp:new Date().toISOString(),status:`processing`,nodeType:`api_call`,nodeName:t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),apiRequest:{messageCount:P.length,toolCount:ye.length}}),H(t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),`processing`);let Me;try{let e=`${I.apiBase}/chat/completions`;r.debug(`[Background] API requesttool count count :`,ye.length);let i={model:n||I.modelName,messages:b(P),tools:ye.map(e=>{let{id:t,...n}=e;return n}),stream:we.streamEnabled!==!1};i.stream&&(i.stream_options={include_usage:!0}),r.debug(`[Background] API requestbody stream mode:`,i.stream,`tool count count :`,i.tools.length,`messagecount:`,i.messages.length,`model:`,i.model),c.temperature!==void 0&&(i.temperature=c.temperature),c.top_p!==void 0&&(i.top_p=c.top_p);let a=Math.max(m-3e4,ve);Me=setTimeout(()=>{r.warn(`[Background] ⚠️ API call outertimeoutprotection triggered (${Math.round(a/1e3)}s),force abort`),ue?.abort()},a),we.streamEnabled!==!1&&(chrome.runtime.sendMessage({type:`STREAM_START`,sessionId:u,callId:h}).catch(()=>{}),r.debug(`[Background] STREAM_START sent (API call with before )`));let o=await pr(e,{method:`POST`,headers:{Authorization:`Bearer ${I.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(i),signal:de},ve,L.apiRetryCount,L.apiRetryBaseDelay,(e,t)=>{r.warn(`[Background] API retry ${e} times after :`,t.message)});if(clearTimeout(Me),!o.ok){let e=await o.text();throw r.error(`[Background] API response error:`,o.status,e),Error(`HTTP error! status: ${o.status}, message: ${e.substring(0,500)}`)}if(we.streamEnabled!==!1&&o.body){r.debug(`[Background] enteringstreamingmode,streamEnabled:`,we.streamEnabled);let e=new ct(u,we,{callId:h,preStarted:!0}),t=await lt(o.body.getReader(),e,de);r.debug(`[Background] streaming API responsecomplete,content length:`,t.content.length,`tool_calls:`,t.toolCalls?.length,`usage:`,t.usage);let n=t.toolCalls?t.toolCalls.map(e=>({...e,id:e.id||`tc_fb_${crypto.randomUUID().slice(0,8)}`})):null;A={choices:[{message:{role:`assistant`,content:t.content||``,reasoning_content:t.reasoningContent,...n?{tool_calls:n}:{}},finish_reason:t.status===`tool_calls`?`tool_calls`:t.truncated?`length`:`stop`}],usage:t.usage}}else{let e=await o.text();r.debug(`[Background] API responsestate:`,o.status,`originaltext length:`,e.length,`preview:`,e.substring(0,200));try{A=JSON.parse(e)}catch(n){throw r.error(`[Background] JSON parse failed:`,n),r.error(`[Background] originalresponse:`,e),Error(t(`reactLoop.apiInvalidJson`,{status:o.status,error:n.message,preview:e.substring(0,100)}))}let n=A.choices?.[0]?.message?.tool_calls;if(n&&n.length>0){let e=n.map(e=>({...e,id:e.id||`tc_fb_${crypto.randomUUID().slice(0,8)}`}));A.choices[0].message.tool_calls=e}}}catch(e){clearTimeout(Me);let i=e.name===`AbortError`;i?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e);let a=M.findIndex(e=>e.id===he);throw a!==-1&&(M[a]={...M[a],duration:Date.now()-le,status:i?`cancelled`:`failed`,apiRequest:{...M[a].apiRequest,model:n||I.modelName,temperature:c.temperature,top_p:c.top_p,messageCount:P.length,toolCount:ye.length},error:i?t(`reactLoop.userCancelled`):e.message}),Lt(i?t(`bg.requestCancelled`):e.message,M)}let Ne=Date.now()-le,q=A.choices?.[0]?.message;A.choices?.[0]?.finish_reason===`length`&&r.warn(`[Background] API response reason token limit truncated (finish_reason: length),contentmay be incomplete`);let Pe=M.findIndex(e=>e.id===he);if(Pe!==-1&&(M[Pe]={...M[Pe],duration:Ne,status:`success`,thought:q?.content||``,action:q?.tool_calls?.length>0?{name:q.tool_calls[0].function?.name||q.tool_calls[0].name,params:(()=>{try{return JSON.parse(q.tool_calls[0].function?.arguments||`{}`)}catch{return{}}})()}:null,apiRequest:{...M[Pe].apiRequest,model:n||I.modelName,temperature:c.temperature,top_p:c.top_p,messageCount:P.length,toolCount:ye.length},apiResponse:{finishReason:A.choices?.[0]?.finish_reason,tokenUsage:A.usage}}),A.usage&&(yt({sessionId:u,model:n||I.modelName,usage:A.usage,callType:`react_loop`}).catch(()=>{}),K>0&&A.usage.prompt_tokens>0)){ne(K,A.usage.prompt_tokens);let e=te();e.active&&r.debug(`[Background] Tokencalibration activated: factor=${e.factor.toFixed(3)}, samples=${e.samples}`)}if(H(t(`reactLoop.apiCallNode`,{count:ge,subtask:d?t(`reactLoop.apiCallSubtask`,{iteration:g}):``}),`success`),q?.tool_calls&&q.tool_calls.length>0){r.debug(`[Background] recei to tool call:`,q.tool_calls);let e=JSON.stringify(q.tool_calls.map(e=>({name:e.function?.name||e.name,args:typeof e.function?.arguments==`string`?(()=>{try{return JSON.parse(e.function.arguments)}catch{return e.function.arguments}})():e.function?.arguments||{}})));r.debug(`[Background] this roundtool callinput fingerprint:`,e.substring(0,200)),T.push(q),await se();let d=[],f=L.reflection;async function m(e,o,u,m,g,_,v,y,b){if(R(o)||_&&R(_))throw Lt(t(`bg.reactCancelled`),y);let x=e.function?.name||e.name,w=Date.now(),T=e.function?.arguments;r.debug(`[Background] executeSingleToolCall recei to tool call:`,JSON.stringify({name:x,argsType:typeof T,argsRaw:typeof T==`string`?T.substring(0,200):JSON.stringify(T).substring(0,200),id:e.id}));let E=(()=>{if(!T)return{};if(typeof T==`object`)return T;try{return JSON.parse(T||`{}`)}catch{return{}}})(),O=e.id||`tc_fallback_${crypto.randomUUID()}`,ee=a.has(x),te=l[x]?.includes(E.action);if((ee||te)&&L.toolConfirmationEnabled){if(_&&Pt.has(_))r.debug(`[Background] session ${_} got currenttaskallow,skip confirm: ${x}`);else{ke(),chrome.runtime.sendMessage({type:`TOOL_CONFIRM_START`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send TOOL_CONFIRM_START message failed:`,e.message)});let n;try{n=await It(x,E,o,_)}finally{G(),chrome.runtime.sendMessage({type:`TOOL_CONFIRM_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send TOOL_CONFIRM_END message failed:`,e.message)})}if(!n){let n=crypto.randomUUID();return y.push({id:n,iteration:v,timestamp:new Date().toISOString(),status:`cancelled`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:t(`reactLoop.userDenied`)}),H(t(`reactLoop.toolExec`,{name:x}),`cancelled`),b.push({role:`tool`,content:`The user declined this operation.`,tool_call_id:O}),await se(),{toolCall:e,result:{success:!1,content:`The user declined this operation.`,error:`user_denied`},toolResultStr:`The user declined this operation.`,toolLogEntry:{id:n,iteration:v,timestamp:new Date().toISOString(),status:`cancelled`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:t(`reactLoop.userDenied`)}}}}}let k=`${x}:${JSON.stringify(E)}`;if(D.has(k)){let e=D.get(k);if(Date.now()-e.timestamp<6e4){if(s.has(x))return{...e,fromCache:!0};D.clear()}else D.delete(k)}s.has(x)||D.clear(),await new Promise(e=>setTimeout(e,0));let ne=crypto.randomUUID();y.push({id:ne,iteration:v,timestamp:new Date().toISOString(),status:`processing`,nodeType:`tool_exec`,nodeName:t(`reactLoop.toolExecStart`,{name:x})}),H(t(`reactLoop.toolExecStart`,{name:x}),`processing`),x===`clarify_question`&&(ke(),chrome.runtime.sendMessage({type:`CLARIFY_START`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_START message failed:`,e.message)}));let A;try{if(A=await Yt(e,o,u,m,g,_),x===`clarify_question`){G(),chrome.runtime.sendMessage({type:`CLARIFY_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_END message failed:`,e.message)}),r.debug(`[Background] clarification complete,re-filteringtool...`);try{let e=await zn(),t=await z(),a=t.reactConfig.enableToolPreselect,o=t.reactConfig.preselectMinToolCount||3;if(a&&e.length>o){let t=await vt(b,n,e,c);t.type===`tools`&&(i=t.tools,j=null,r.debug(`[Background] clarification after toolre-filtercomplete:`,i.map(e=>e.function.name))),t.executionLog&&y.push(...t.executionLog)}else a||r.debug(`[Background] toolpre-filterclosed,after clarification, notre-filter`)}catch(e){r.warn(`[Background] clarification after toolre-filter failed, continue withcurrenttoolset:`,e.message)}}let a;a=typeof A==`string`?A:A&&typeof A==`object`&&`content`in A?A.content??JSON.stringify(A):JSON.stringify(A);let l=A&&A.success!==!1,T=S(a),ee=!1,te=a;if(T>ae){let e=re(a,ae);r.debug(`[Background] tool ${x} result truncated: ${T} → ${S(e)} tokens`),ee=!0,te=e,a=e}Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:O,toolName:x,success:l,content:l?te:A?.error||te,truncated:ee,duration:Date.now()-w}}).catch(()=>{});let ie=y.filter(e=>e.nodeType===`tool_exec`&&e.iteration===v).sort((e,t)=>y.indexOf(e)-y.indexOf(t)),M=0;for(let e=ie.length-1;e>=0&&ie[e].status===`failed`;e--)M++;if(y.filter(e=>e.nodeType===`reflection`&&e.reflectionType===`tool`).length<(f?.toolReflection?.maxPerIteration||2)&&Dt(a,M,f)&&d.push({toolName:x,toolResultStr:a,toolCallParams:E,toolCallId:O,priority:Et(x,a,M)}),x===`plan_task`&&A&&A.success&&A.data){N=A.data,r.debug(`[Background] received taskplanresult:`,JSON.stringify(N));let e=JSON.stringify({success:!0,message:`Task planning complete. Decomposed into ${N.subtasks.length} subtasks.`,data:N});b.push({role:`tool`,content:e,tool_call_id:O}),await se();let a=y.findIndex(e=>e.id===ne);a!==-1&&(y[a]={...y[a],duration:Date.now()-w,status:`success`,nodeName:t(`reactLoop.taskPlanDone`),action:{name:x,params:E},observation:t(`reactLoop.subtaskCount`,{count:N.subtasks.length}),subtaskCount:N.subtasks.length,strategy:N.strategy}),H(t(`reactLoop.taskPlanDone`),`success`);let l=q.tool_calls.findIndex(e=>e.id===O);if(l!==-1&&l<q.tool_calls.length-1){for(let e=l+1;e<q.tool_calls.length;e++){let n=q.tool_calls[e],i=n.function?.name||n.name||`unknown`,a=n.id||`tc_fallback_${crypto.randomUUID()}`;r.debug(`[Background] resend skiptool STREAM_TOOL_RESULT:`,i,`id:`,a),b.push({role:`tool`,content:JSON.stringify({success:!1,message:`Skipped: plan_task has decomposed subtasks; other tool calls in this round will not be executed.`}),tool_call_id:a}),Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:a,toolName:i,success:!1,content:t(`reactLoop.skippedAfterPlanTask`),truncated:!1,duration:0}}).catch(()=>{})}await se()}let u=await Kt(N,n,i,o,c,_,y,p,L.reflection,I,V,h);if(R(o)||_&&R(_))throw Lt(t(`bg.reactCancelled`),y);let d=3e3,f=u.map((e,t)=>{let n=typeof e.result==`string`?e.result:JSON.stringify(e.result),r=S(n)>d?C(n,d):n;return`Subtask ${t+1}: ${e.subtaskName}\nResult: ${r}`}).join(`
97
97
 
98
- `);if(b.push({role:`system`,content:`The following are the execution results of the decomposed subtasks. Please summarize them:\n\n${f}`}),await se(),s.has(x)){if(D.size>=30){let e=D.keys().next().value;D.delete(e)}D.set(k,{planTaskHandled:!0,toolName:x,toolCallId:O,timestamp:Date.now()})}return{planTaskHandled:!0}}b.push({role:`tool`,content:a,tool_call_id:O,subtaskId:null,subtaskName:N?.subtasks[null]?.name||null}),await se(),r.debug(`[Background] toolexec result length:`,a.length,`content preview:`,a.substring(0,200));let ce=y.findIndex(e=>e.id===ne);if(ce!==-1){let e={...y[ce],duration:Date.now()-w,status:l?`success`:`failed`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},observation:l?a.length>oe?a.substring(0,oe)+`...`:a:void 0,prototypeId:A?.prototypeId||null};!l&&A?.error&&(e.error=A.error),y[ce]=e}if(s.has(x)){if(D.size>=30){let e=D.keys().next().value;D.delete(e)}D.set(k,{planTaskHandled:!1,toolResultStr:a,toolName:x,toolCallId:O,toolResult:A,timestamp:Date.now()})}return{planTaskHandled:!1,toolResultStr:a,toolName:x,toolCallId:O,toolResult:A}}catch(e){r.warn(`[Background] toolexecution failed (ReAct loop continue):`,e.message),x===`clarify_question`&&(G(),chrome.runtime.sendMessage({type:`CLARIFY_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_END message failed:`,e.message)}));let n=JSON.stringify({success:!1,error:e.message||`Tool execution error`});b.push({role:`tool`,content:n,tool_call_id:O,subtaskId:null,subtaskName:N?.subtasks[null]?.name||null}),await se();let i=y.findIndex(e=>e.id===ne);return i!==-1&&(y[i]={...y[i],duration:Date.now()-w,status:`failed`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:e.message}),r.warn(`[Background] tool ${x} execution failed,ReAct loop continue:`,e.message),H(t(`reactLoop.toolExec`,{name:x}),`failed`),Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:O,toolName:x,success:!1,content:t(`reactLoop.toolError`,{message:e.message}),truncated:!1,duration:Date.now()-w}}).catch(()=>{}),{error:e.message,toolName:x,toolCallId:O,toolResult:{success:!1,error:e.message},toolResultStr:JSON.stringify({success:!1,error:e.message})}}}async function _(){if(d.length===0)return;if(v>=10){r.warn(`[Background] reflectiontotal roundsreached limit,skip toolreflection`);return}d.sort((e,t)=>t.priority-e.priority);let e=f?.toolReflection?.maxPerIteration||2;for(let i of d.slice(0,e)){if(v>=10)break;v++;let e=await jt(i.toolName,i.toolResultStr,i.toolCallParams,I,n,f,M,g,u);if(e){let n={id:crypto.randomUUID(),iteration:g,timestamp:new Date().toISOString(),status:e.useful?`success`:`failed`,nodeType:`reflection`,nodeName:t(`reactLoop.toolReflection`,{name:i.toolName}),reflectionType:`tool`,useful:e.useful,reasoning:e.reasoning,suggestion:e.suggestion};if(M.push(n),r.debug(`[Background] toolreflection: ${i.toolName} - ${e.useful?` has with `:`invalid`} - ${e.reasoning}`),!e.useful&&e.suggestion){let t=`\n\n[Reflection Notice] The result returned by tool "${i.toolName}" was assessed as unhelpful (${e.reasoning}). Suggestion: ${e.suggestion}. Please consider adjusting your strategy in subsequent steps.`;for(let e=T.length-1;e>=0;e--)if(T[e].role===`tool`&&T[e].tool_call_id===i.toolCallId){T[e]={...T[e],content:T[e].content+t};break}}}}}if(q.tool_calls.every(e=>s.has(e.function?.name||e.name))&&q.tool_calls.length>1){r.debug(`[Background] parallel exectool call:`,q.tool_calls.map(e=>e.function?.name||e.name));let e=T.length,t=q.tool_calls.map(e=>m(e,o,xe,be,Se,u,g,M,T).catch(e=>({error:e.message}))),n=await Promise.all(t),i=T.splice(e),a=new Map(q.tool_calls.map((e,t)=>[e.id,t])),s=i.filter(e=>e.role===`tool`),c=i.filter(e=>e.role!==`tool`);s.sort((e,t)=>(a.get(e.tool_call_id)??999)-(a.get(t.tool_call_id)??999)),T.push(...c,...s);let l=!1;for(let e=0;e<q.tool_calls.length;e++){let t=n[e];t.error&&r.warn(`[Background] parallel toolsexecution failed: ${q.tool_calls[e].function?.name||q.tool_calls[e].name} - ${t.error}`),t.planTaskHandled&&(l=!0)}if(await _(),l){await F(`plan_task_completed`);continue}}else{let e=!1;for(let t=0;t<q.tool_calls.length;t++){let n=q.tool_calls[t];if((await m(n,o,xe,be,Se,u,g,M,T)).planTaskHandled){e=!0,await _();break}}if(await _(),e){await F(`plan_task_completed`);continue}}let y=[];for(let e=T.length-1;e>=0;e--){let t=T[e];if(t.role===`tool`)y.unshift(t.content);else if(t.role===`assistant`&&t.tool_calls)break}let b=JSON.stringify(q.tool_calls.map((e,t)=>({name:e.function?.name||e.name,args:typeof e.function?.arguments==`string`?(()=>{try{return JSON.parse(e.function.arguments)}catch{return e.function.arguments}})():e.function?.arguments||{},result:y[t]||``})));if(b===ee){k++;let e=q.tool_calls.map(e=>e.function?.name||e.name).join(`, `);if(r.warn(`[Background] detected infiniteloop:input and outputidentical (${k} consecutive repeats): ${e}`),k>=8)throw Lt(t(`reactLoop.infiniteLoopDetected`,{count:k}),M);if(k>=5){let e={role:`user`,content:`[System Notice] You have called the exact same tool with the same parameters ${k} times in a row and received identical results, which indicates the current strategy is making no progress. Please switch to a different strategy or tool immediately and do not repeat this operation. If the current tool cannot obtain the required data, try alternative approaches, or directly provide a conclusion based on the information already available.`};T.push(e),r.debug(`[Background] inject infinite loopwarningmessage`)}}else ee=b,k=1;await F(`tools_completed`);continue}let Fe=q?.content||``,Ie=q?.reasoning_content||null;r.debug(`[Background] ReAct loop complete,finalcontent length:`,Fe.length),await F(`final_answer`),await zt(u);let Le=L.reflection;if(Le?.enabled&&Le?.postReflection?.enabled&&Tt(M,d)){r.debug(`[Background] triggered post-reflection...`);let e=await At(T,Fe,M,n,I,Le,o,H,p,d,u,v);return e.reflectionLog&&e.reflectionLog.length>0&&M.push(...e.reflectionLog),H(t(`reactLoop.executionDone`),`success`),{content:e.content,executionLog:M,reflectionScore:e.overallScore,wasRevised:e.wasRevised,reasoningContent:Ie}}return H(t(`reactLoop.executionDone`),`success`),{content:Fe,executionLog:M,reasoningContent:Ie}}let e=Error(t(`reactLoop.maxIterationsExceeded`,{maxIterations:he}));throw e.executionLog=M,e}catch(e){throw await F(e.name===`AbortError`||e.message===`请求已被用户取消`||e.message===`ReAct 循环已被用户取消`?`user_cancelled`:`error`,!0),e}finally{u&&(Nt.delete(u),Pt.delete(u))}}var Ut={DEFAULT_FAILURE_STRATEGY:`continue`,DEFAULT_MAX_RETRIES:1,DEFAULT_MAX_PARALLEL:3};async function Wt(e,n,i,a,o,s,c,l={value:0},u=null,d=null,f=new Map,p=null){let{subtasks:m=[],strategy:h=`sequential`,taskDescription:g,failureStrategy:_=Ut.DEFAULT_FAILURE_STRATEGY,maxRetries:v=Ut.DEFAULT_MAX_RETRIES,maxParallel:y=Ut.DEFAULT_MAX_PARALLEL}=e,b=[],x=[];function S(e,t,n,r={}){let i=[];for(let e of n){let t=f.get(e.id);(!t||t.status!==e.status||t.nodeName!==e.nodeName)&&(i.push(e),f.set(e.id,{status:e.status,nodeName:e.nodeName}))}if(i.length===0)return;let a={type:`EXECUTION_STATUS_UPDATE`,nodeName:e,status:t,executionLog:i,...s?{sessionId:s}:{},...p?{callId:p}:{},...r};r.subtaskTotal!=null&&(a.subtaskTotal=r.subtaskTotal,a.subtaskIndex=r.subtaskIndex,a.subtaskName=r.subtaskName),chrome.runtime.sendMessage(a).catch(e=>{})}r.debug(`[Background] start executing subtask,strategy:`,h,`failedstrategy:`,_,`maxretry:`,v,`count:`,m.length);let C=h===`dependency`?Gt(m):m,w=await Kt(C,i);async function T(){r.debug(`[Background] start rollback completed subtask`);for(let e=x.length-1;e>=0;e--){let{subtask:n,result:i}=x[e];if(typeof n.rollback==`function`)try{r.debug(`[Background] rollback subtask: ${n.name}`),await n.rollback(i),c.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`rolledback`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskRolledBack`,{name:n.name}),subtaskId:n.id,subtaskName:n.name}),S(t(`reactLoop.subtaskRolledBack`,{name:n.name}),`rolledback`,c)}catch(e){r.error(`[Background] rollback failed:`,e.message),c.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`rollback_failed`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskRollbackFailed`,{name:n.name}),subtaskId:n.id,subtaskName:n.name,error:e.message})}}}async function E(e,i,f){let p=crypto.randomUUID(),m=`subtask_group_${f}`,h=s?`${s}_subtask_${f}`:null;c.push({id:p,iteration:0,timestamp:new Date().toISOString(),status:`processing`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0}),S(t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),`processing`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name});for(let _=0;_<=v;_++){if(R(a)||s&&R(s))throw r.debug(`[Background] subtaskretryby usercancel`),Lt(t(`bg.reactCancelled`),c);try{r.debug(`[Background] execute subtask ${f+1}/${C.length}: ${e.name} (attempt ${_+1}/${v+1})`);let y=[{role:`system`,content:`You are executing a subtask. Focus on completing this task and do not ask the user any questions.\n\nTask context: ${g}\n\nCurrent subtask: ${e.description}\n\nYou may use all available tools to complete the task. Choose the appropriate tools based on the actual situation.`},{role:`user`,content:e.description}],b=await Ht(y,n,i,a,o,h,{subtaskId:e.id,subtaskName:e.name},n=>{let r=[...c];n.forEach(t=>{r.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})}),S(t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),`processing`,r,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name})},l);b.executionLog&&b.executionLog.length>0&&b.executionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})});let w=c.findIndex(e=>e.id===p);w!==-1&&(c[w]={...c[w],status:`success`,duration:Date.now()-new Date(c[w].timestamp).getTime(),result:b.content.substring(0,200)+(b.content.length>200?`...`:``)}),S(t(`reactLoop.subtaskCompleted`,{index:f+1,name:e.name}),`success`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name}),x.push({subtask:e,result:b});let T=b.content,E=null;if(u?.enabled&&u?.subtaskReflection?.enabled){let t=u.subtaskReflection,i=e.complexity===`complex`||b.content.length>500||b.executionLog&&b.executionLog.length>3;if((!t.onlyForComplexSubtasks||i)&&t.maxRounds>0){r.debug(`[Background] subtask ${e.name} trigger reflection,complexity: ${i?`repmisc`:`normal`}`);let o=await Mt(y,b.content,b.executionLog||[],n,d,t,a,e.name,c,s);o.refinedContent&&(T=o.refinedContent,r.debug(`[Background] subtask ${e.name} after reflectionrevise`)),E=o.score,o.reflectionLog&&o.reflectionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})})}}return{success:!0,subtaskId:e.id,subtaskName:e.name,result:T,executionLog:b.executionLog||[],retryCount:_,reflectionScore:E}}catch(n){if(r.warn(`[Background] subtask ${e.name} attempt ${_+1} failed:`,n.message),_>=v){n.executionLog&&n.executionLog.length>0&&n.executionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})});let r=c.findIndex(e=>e.id===p);return r!==-1&&(c[r]={...c[r],status:`failed`,duration:Date.now()-new Date(c[r].timestamp).getTime(),error:n.message,retryCount:_+1}),S(t(`reactLoop.subtaskFailed`,{index:f+1,name:e.name}),`failed`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name}),{success:!1,subtaskId:e.id,subtaskName:e.name,result:n.message,executionLog:n.executionLog||[],retryCount:_+1,error:n}}await new Promise(e=>setTimeout(e,1e3*2**_))}}}if(h===`sequential`||h===`dependency`)for(let e=0;e<C.length;e++){if(R(a)||s&&R(s))return r.debug(`[Background] subtaskexec by usercancel`),b;let t=C[e],n=await E(t,w[t.id]||[],e);if(b.push(n),!n.success&&(r.debug(`[Background] subtask ${t.name} failed,failedstrategy: ${_}`),_===`stop`))return r.debug(`[Background] execute rollback`),await T(),b;if(R(a)||s&&R(s))return r.debug(`[Background] subtaskexec by usercancel`),b}else if(h===`parallel`){r.debug(`[Background] parallel executing subtask,max concurrency:`,y);let e=[],t=new Map;for(let n=0;n<C.length;n++){if(R(a)||s&&R(s))return r.debug(`[Background] subtaskparallel execby usercancel`),b;if(e.length>=y){let t=await Promise.race(e),n=e.indexOf(t);n>-1&&e.splice(n,1)}let i=C[n],o=E(i,w[i.id]||[],n).then(e=>(t.set(i.id,e),e));e.push(o)}await Promise.all(e);let n=!1;C.forEach(e=>{let r=t.get(e.id);r&&(b.push(r),r.success||(n=!0))}),n&&_===`stop`&&(r.debug(`[Background] parallel execoccurred failed,execute rollback`),await T())}else return r.warn(`[Background] not knownexec strategy: ${h},downgraded to sequentialexec `),Wt({...e,strategy:`sequential`},n,i,a,o,s,c,l,u,d,f,p);return b}function Gt(e){let t=[],n=new Set,r=new Set;function i(a){if(r.has(a.id))throw Error(`检测到子任务依赖循环`);n.has(a.id)||(r.add(a.id),(a.dependencies||[]).forEach(t=>{let n=e.find(e=>e.id===t);n&&i(n)}),r.delete(a.id),n.add(a.id),t.push(a))}return e.forEach(e=>{n.has(e.id)||i(e)}),t}async function Kt(e,t=null){let n=t||await Ln(),i=await z().then(e=>e.reactConfig||{}),a=i.enableToolPreselect===!0,o=i.preselectMinToolCount||10,s={},c=[`plan_task`],l=n.filter(e=>!c.includes(e.id));if(l.length<=o)return r.debug(`[Background] subtasktoolfilter:tool count ${l.length} <= ${o},full count inherit (excluded plan_task)`),e.forEach(e=>{s[e.id]=[...l]}),s;let u=[`clarify_question`];return e.forEach(e=>{if(a&&Array.isArray(e.requiredTools)&&e.requiredTools.length>0){let t=l.filter(t=>e.requiredTools.includes(t.id)),n=l.filter(e=>u.includes(e.id));s[e.id]=[...t,...n],r.debug(`[Background] subtask ${e.name} filter tools: ${t.length}/${l.length} (pre-filter mode)`)}else s[e.id]=[...l],r.debug(`[Background] subtask ${e.name} inherit parent task ${l.length} tool (excluded plan_task)`)}),s}async function qt(e,n,i,a,o,s=null){let l=e.function?.name||e.name;if(l===`clarify_question`)return r.debug(`[Background] clarificationtooldirectly execute, no outertimeout (overall looptimeoutpaused)`),ir(e,n,s);let u=c[l],d=u?Math.min(u,i):i;r.debug(`[Background] tool ${l} usingtimeout: ${d}ms${u?` (custom: ${u}ms, globallimit: ${i}ms)`:``}`);let f=Ce(s);return new Promise((r,i)=>{let a=setTimeout(()=>{i(Error(t(`reactLoop.toolTimeout`,{timeout:d,tool:l})))},d),o=()=>{clearTimeout(a),i(Error(t(`reactLoop.toolAborted`,{tool:l})))};f&&!f.signal.aborted&&f.signal.addEventListener(`abort`,o,{once:!0}),ir(e,n,s).then(e=>{clearTimeout(a),f&&(f.signal.removeEventListener(`abort`,o),Te(s)),r(e)}).catch(e=>{clearTimeout(a),f&&(f.signal.removeEventListener(`abort`,o),Te(s)),i(e)})})}function Jt(e,n,i={},a=null,o={},s=null){return z().then(c=>{i.imageApiBase&&(c.apiBase=i.imageApiBase),i.imageApiKey&&(c.apiKey=i.imageApiKey);let l=(a?_e(a):null)?.signal,u=`${c.apiBase}/chat/completions`,d=O(e),f=c.streamConfig?.streamEnabled!==!1;r.debug(`[Background] send API request to :`,u,`streaming:`,f);let p={model:n||c.modelName,messages:b(d),stream:f};return f&&(p.stream_options={include_usage:!0}),i.temperature!==void 0&&(p.temperature=i.temperature),i.top_p!==void 0&&(p.top_p=i.top_p),f&&a&&(chrome.runtime.sendMessage({type:`STREAM_START`,sessionId:a,callId:s}).catch(()=>{}),r.debug(`[Background] STREAM_START sent (API call with before )`)),dr(u,{method:`POST`,headers:{Authorization:`Bearer ${c.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(p),signal:l},c.reactConfig.apiTimeout,c.reactConfig.apiRetryCount,c.reactConfig.apiRetryBaseDelay).then(async e=>{if(!e.ok){let t=await e.text();throw r.error(`[Background] API response error:`,e.status,t),Error(`HTTP error! status: ${e.status}, message: ${t.substring(0,500)}`)}if(f&&e.body){let t=new ct(a,c.streamConfig,{...o,callId:s,preStarted:!0}),n=await lt(e.body.getReader(),t,l);return r.debug(`[Background] streaming API responsecomplete,content length:`,n.content.length,`usage:`,n.usage),{content:n.content,usage:n.usage,reasoningContent:n.reasoningContent}}let n=await e.text();r.debug(`[Background] non-streaming API responsestate:`,e.status,`text length:`,n.length,`preview:`,n.substring(0,200));try{let e=JSON.parse(n);return r.debug(`[Background] API response:`,JSON.stringify(e).substring(0,200)),{content:e.choices?.[0]?.message?.content||``,usage:e.usage||null}}catch(i){throw r.error(`[Background] JSON parse failed,originalresponse:`,n.substring(0,500)),Error(t(`reactLoop.jsonParseFailed`,{status:e.status,error:i.message,preview:n.substring(0,100)}))}}).catch(e=>{throw e.name===`AbortError`?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e),e})})}async function Yt(e){return M.find(t=>t.id===e)||((await chrome.storage.local.get([`customAgents`])).customAgents||[]).find(t=>t.id===e)||null}async function Xt(e,t){let n=e.systemPrompt||``;n.trim()||(n=`You are an AI assistant. Please complete the following task.`);try{let t=``;e.skillIds!=null&&Array.isArray(e.skillIds)&&e.skillIds.length>0?t=(await $e(e.skillIds)).prompts||``:e.skillIds??(t=(await Qe()).prompts||``),t&&(n+=`
98
+ `);if(b.push({role:`system`,content:`The following are the execution results of the decomposed subtasks. Please summarize them:\n\n${f}`}),await se(),s.has(x)){if(D.size>=30){let e=D.keys().next().value;D.delete(e)}D.set(k,{planTaskHandled:!0,toolName:x,toolCallId:O,timestamp:Date.now()})}return{planTaskHandled:!0}}b.push({role:`tool`,content:a,tool_call_id:O,subtaskId:null,subtaskName:N?.subtasks[null]?.name||null}),await se(),r.debug(`[Background] toolexec result length:`,a.length,`content preview:`,a.substring(0,200));let ce=y.findIndex(e=>e.id===ne);if(ce!==-1){let e={...y[ce],duration:Date.now()-w,status:l?`success`:`failed`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},observation:l?a.length>oe?a.substring(0,oe)+`...`:a:void 0,prototypeId:A?.prototypeId||null};!l&&A?.error&&(e.error=A.error),y[ce]=e}if(s.has(x)){if(D.size>=30){let e=D.keys().next().value;D.delete(e)}D.set(k,{planTaskHandled:!1,toolResultStr:a,toolName:x,toolCallId:O,toolResult:A,timestamp:Date.now()})}return{planTaskHandled:!1,toolResultStr:a,toolName:x,toolCallId:O,toolResult:A}}catch(e){r.warn(`[Background] toolexecution failed (ReAct loop continue):`,e.message),x===`clarify_question`&&(G(),chrome.runtime.sendMessage({type:`CLARIFY_END`,..._?{sessionId:_}:{}}).catch(e=>{r.debug(`[Background] send CLARIFY_END message failed:`,e.message)}));let n=JSON.stringify({success:!1,error:e.message||`Tool execution error`});b.push({role:`tool`,content:n,tool_call_id:O,subtaskId:null,subtaskName:N?.subtasks[null]?.name||null}),await se();let i=y.findIndex(e=>e.id===ne);return i!==-1&&(y[i]={...y[i],duration:Date.now()-w,status:`failed`,nodeName:t(`reactLoop.toolExec`,{name:x}),action:{name:x,params:E},error:e.message}),r.warn(`[Background] tool ${x} execution failed,ReAct loop continue:`,e.message),H(t(`reactLoop.toolExec`,{name:x}),`failed`),Ce||chrome.runtime.sendMessage({type:`STREAM_TOOL_RESULT`,sessionId:_,result:{toolCallId:O,toolName:x,success:!1,content:t(`reactLoop.toolError`,{message:e.message}),truncated:!1,duration:Date.now()-w}}).catch(()=>{}),{error:e.message,toolName:x,toolCallId:O,toolResult:{success:!1,error:e.message},toolResultStr:JSON.stringify({success:!1,error:e.message})}}}async function _(){if(d.length===0)return;if(v>=10){r.warn(`[Background] reflectiontotal roundsreached limit,skip toolreflection`);return}d.sort((e,t)=>t.priority-e.priority);let e=f?.toolReflection?.maxPerIteration||2;for(let i of d.slice(0,e)){if(v>=10)break;v++;let e=await jt(i.toolName,i.toolResultStr,i.toolCallParams,I,n,f,M,g,u);if(e){let n={id:crypto.randomUUID(),iteration:g,timestamp:new Date().toISOString(),status:e.useful?`success`:`failed`,nodeType:`reflection`,nodeName:t(`reactLoop.toolReflection`,{name:i.toolName}),reflectionType:`tool`,useful:e.useful,reasoning:e.reasoning,suggestion:e.suggestion};if(M.push(n),r.debug(`[Background] toolreflection: ${i.toolName} - ${e.useful?` has with `:`invalid`} - ${e.reasoning}`),!e.useful&&e.suggestion){let t=`\n\n[Reflection Notice] The result returned by tool "${i.toolName}" was assessed as unhelpful (${e.reasoning}). Suggestion: ${e.suggestion}. Please consider adjusting your strategy in subsequent steps.`;for(let e=T.length-1;e>=0;e--)if(T[e].role===`tool`&&T[e].tool_call_id===i.toolCallId){T[e]={...T[e],content:T[e].content+t};break}}}}}if(q.tool_calls.every(e=>s.has(e.function?.name||e.name))&&q.tool_calls.length>1){r.debug(`[Background] parallel exectool call:`,q.tool_calls.map(e=>e.function?.name||e.name));let e=T.length,t=q.tool_calls.map(e=>m(e,o,xe,be,Se,u,g,M,T).catch(e=>({error:e.message}))),n=await Promise.all(t),i=T.splice(e),a=new Map(q.tool_calls.map((e,t)=>[e.id,t])),s=i.filter(e=>e.role===`tool`),c=i.filter(e=>e.role!==`tool`);s.sort((e,t)=>(a.get(e.tool_call_id)??999)-(a.get(t.tool_call_id)??999)),T.push(...c,...s);let l=!1;for(let e=0;e<q.tool_calls.length;e++){let t=n[e];t.error&&r.warn(`[Background] parallel toolsexecution failed: ${q.tool_calls[e].function?.name||q.tool_calls[e].name} - ${t.error}`),t.planTaskHandled&&(l=!0)}if(await _(),l){await F(`plan_task_completed`);continue}}else{let e=!1;for(let t=0;t<q.tool_calls.length;t++){let n=q.tool_calls[t];if((await m(n,o,xe,be,Se,u,g,M,T)).planTaskHandled){e=!0,await _();break}}if(await _(),e){await F(`plan_task_completed`);continue}}let y=[];for(let e=T.length-1;e>=0;e--){let t=T[e];if(t.role===`tool`)y.unshift(t.content);else if(t.role===`assistant`&&t.tool_calls)break}let b=JSON.stringify(q.tool_calls.map((e,t)=>({name:e.function?.name||e.name,args:typeof e.function?.arguments==`string`?(()=>{try{return JSON.parse(e.function.arguments)}catch{return e.function.arguments}})():e.function?.arguments||{},result:y[t]||``})));if(b===ee){k++;let e=q.tool_calls.map(e=>e.function?.name||e.name).join(`, `);if(r.warn(`[Background] detected infiniteloop:input and outputidentical (${k} consecutive repeats): ${e}`),k>=8)throw Lt(t(`reactLoop.infiniteLoopDetected`,{count:k}),M);if(k>=5){let e={role:`user`,content:`[System Notice] You have called the exact same tool with the same parameters ${k} times in a row and received identical results, which indicates the current strategy is making no progress. Please switch to a different strategy or tool immediately and do not repeat this operation. If the current tool cannot obtain the required data, try alternative approaches, or directly provide a conclusion based on the information already available.`};T.push(e),r.debug(`[Background] inject infinite loopwarningmessage`)}}else ee=b,k=1;await F(`tools_completed`);continue}let Fe=q?.content||``,Ie=q?.reasoning_content||null;r.debug(`[Background] ReAct loop complete,finalcontent length:`,Fe.length),await F(`final_answer`),await Vt(u);let Le=L.reflection;if(Le?.enabled&&Le?.postReflection?.enabled&&Tt(M,d)){r.debug(`[Background] triggered post-reflection...`);let e=await At(T,Fe,M,n,I,Le,o,H,p,d,u,v);return e.reflectionLog&&e.reflectionLog.length>0&&M.push(...e.reflectionLog),H(t(`reactLoop.executionDone`),`success`),{content:e.content,executionLog:M,reflectionScore:e.overallScore,wasRevised:e.wasRevised,reasoningContent:Ie}}return H(t(`reactLoop.executionDone`),`success`),{content:Fe,executionLog:M,reasoningContent:Ie}}let e=Error(t(`reactLoop.maxIterationsExceeded`,{maxIterations:he}));throw e.executionLog=M,e}catch(e){throw await F(e.name===`AbortError`||e.message===`请求已被用户取消`||e.message===`ReAct 循环已被用户取消`?`user_cancelled`:`error`,!0),e}finally{u&&(Nt.delete(u),Pt.delete(u))}}var Gt={DEFAULT_FAILURE_STRATEGY:`continue`,DEFAULT_MAX_RETRIES:1,DEFAULT_MAX_PARALLEL:3};async function Kt(e,n,i,a,o,s,c,l={value:0},u=null,d=null,f=new Map,p=null){let{subtasks:m=[],strategy:h=`sequential`,taskDescription:g,failureStrategy:_=Gt.DEFAULT_FAILURE_STRATEGY,maxRetries:v=Gt.DEFAULT_MAX_RETRIES,maxParallel:y=Gt.DEFAULT_MAX_PARALLEL}=e,b=[],x=[];function S(e,t,n,r={}){zt(c,f);let i=[];for(let e of n){let t=f.get(e.id);(!t||t.status!==e.status||t.nodeName!==e.nodeName)&&(i.push(e),f.set(e.id,{status:e.status,nodeName:e.nodeName}))}if(i.length===0)return;let a={type:`EXECUTION_STATUS_UPDATE`,nodeName:e,status:t,executionLog:i,...s?{sessionId:s}:{},...p?{callId:p}:{},...r};r.subtaskTotal!=null&&(a.subtaskTotal=r.subtaskTotal,a.subtaskIndex=r.subtaskIndex,a.subtaskName=r.subtaskName),chrome.runtime.sendMessage(a).catch(e=>{})}r.debug(`[Background] start executing subtask,strategy:`,h,`failedstrategy:`,_,`maxretry:`,v,`count:`,m.length);let C=h===`dependency`?qt(m):m,w=await Jt(C,i);async function T(){r.debug(`[Background] start rollback completed subtask`);for(let e=x.length-1;e>=0;e--){let{subtask:n,result:i}=x[e];if(typeof n.rollback==`function`)try{r.debug(`[Background] rollback subtask: ${n.name}`),await n.rollback(i),c.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`rolledback`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskRolledBack`,{name:n.name}),subtaskId:n.id,subtaskName:n.name}),S(t(`reactLoop.subtaskRolledBack`,{name:n.name}),`rolledback`,c)}catch(e){r.error(`[Background] rollback failed:`,e.message),c.push({id:crypto.randomUUID(),iteration:0,timestamp:new Date().toISOString(),status:`rollback_failed`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskRollbackFailed`,{name:n.name}),subtaskId:n.id,subtaskName:n.name,error:e.message})}}}async function E(e,i,f){let p=crypto.randomUUID(),m=`subtask_group_${f}`,h=s?`${s}_subtask_${f}`:null;c.push({id:p,iteration:0,timestamp:new Date().toISOString(),status:`processing`,nodeType:`subtask`,nodeName:t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0}),S(t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),`processing`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name});for(let _=0;_<=v;_++){if(R(a)||s&&R(s))throw r.debug(`[Background] subtaskretryby usercancel`),Lt(t(`bg.reactCancelled`),c);try{r.debug(`[Background] execute subtask ${f+1}/${C.length}: ${e.name} (attempt ${_+1}/${v+1})`);let y=[{role:`system`,content:`You are executing a subtask. Focus on completing this task and do not ask the user any questions.\n\nTask context: ${g}\n\nCurrent subtask: ${e.description}\n\nYou may use all available tools to complete the task. Choose the appropriate tools based on the actual situation.`},{role:`user`,content:e.description}],b=await Wt(y,n,i,a,o,h,{subtaskId:e.id,subtaskName:e.name},n=>{let r=[...c];n.forEach(t=>{r.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})}),S(t(`reactLoop.subtaskNode`,{index:f+1,name:e.name}),`processing`,r,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name})},l);b.executionLog&&b.executionLog.length>0&&b.executionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})});let w=c.findIndex(e=>e.id===p);w!==-1&&(c[w]={...c[w],status:`success`,duration:Date.now()-new Date(c[w].timestamp).getTime(),result:b.content.substring(0,200)+(b.content.length>200?`...`:``)}),S(t(`reactLoop.subtaskCompleted`,{index:f+1,name:e.name}),`success`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name}),x.push({subtask:e,result:b});let T=b.content,E=null;if(u?.enabled&&u?.subtaskReflection?.enabled){let t=u.subtaskReflection,i=e.complexity===`complex`||b.content.length>500||b.executionLog&&b.executionLog.length>3;if((!t.onlyForComplexSubtasks||i)&&t.maxRounds>0){r.debug(`[Background] subtask ${e.name} trigger reflection,complexity: ${i?`repmisc`:`normal`}`);let o=await Mt(y,b.content,b.executionLog||[],n,d,t,a,e.name,c,s);o.refinedContent&&(T=o.refinedContent,r.debug(`[Background] subtask ${e.name} after reflectionrevise`)),E=o.score,o.reflectionLog&&o.reflectionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})})}}return{success:!0,subtaskId:e.id,subtaskName:e.name,result:T,executionLog:b.executionLog||[],retryCount:_,reflectionScore:E}}catch(n){if(r.warn(`[Background] subtask ${e.name} attempt ${_+1} failed:`,n.message),_>=v){n.executionLog&&n.executionLog.length>0&&n.executionLog.forEach(t=>{c.push({...t,subtaskId:e.id,subtaskName:e.name,subtaskIndex:f,taskGroup:m,taskGroupIndex:f+1,taskGroupName:e.name,isSubtask:!0})});let r=c.findIndex(e=>e.id===p);return r!==-1&&(c[r]={...c[r],status:`failed`,duration:Date.now()-new Date(c[r].timestamp).getTime(),error:n.message,retryCount:_+1}),S(t(`reactLoop.subtaskFailed`,{index:f+1,name:e.name}),`failed`,c,{taskGroup:m,subtaskIndex:f,subtaskTotal:C.length,subtaskName:e.name}),{success:!1,subtaskId:e.id,subtaskName:e.name,result:n.message,executionLog:n.executionLog||[],retryCount:_+1,error:n}}await new Promise(e=>setTimeout(e,1e3*2**_))}}}if(h===`sequential`||h===`dependency`)for(let e=0;e<C.length;e++){if(R(a)||s&&R(s))return r.debug(`[Background] subtaskexec by usercancel`),b;let t=C[e],n=await E(t,w[t.id]||[],e);if(b.push(n),!n.success&&(r.debug(`[Background] subtask ${t.name} failed,failedstrategy: ${_}`),_===`stop`))return r.debug(`[Background] execute rollback`),await T(),b;if(R(a)||s&&R(s))return r.debug(`[Background] subtaskexec by usercancel`),b}else if(h===`parallel`){r.debug(`[Background] parallel executing subtask,max concurrency:`,y);let e=[],t=new Map;for(let n=0;n<C.length;n++){if(R(a)||s&&R(s))return r.debug(`[Background] subtaskparallel execby usercancel`),b;if(e.length>=y){let t=await Promise.race(e),n=e.indexOf(t);n>-1&&e.splice(n,1)}let i=C[n],o=E(i,w[i.id]||[],n).then(e=>(t.set(i.id,e),e));e.push(o)}await Promise.all(e);let n=!1;C.forEach(e=>{let r=t.get(e.id);r&&(b.push(r),r.success||(n=!0))}),n&&_===`stop`&&(r.debug(`[Background] parallel execoccurred failed,execute rollback`),await T())}else return r.warn(`[Background] not knownexec strategy: ${h},downgraded to sequentialexec `),Kt({...e,strategy:`sequential`},n,i,a,o,s,c,l,u,d,f,p);return b}function qt(e){let t=[],n=new Set,r=new Set;function i(a){if(r.has(a.id))throw Error(`检测到子任务依赖循环`);n.has(a.id)||(r.add(a.id),(a.dependencies||[]).forEach(t=>{let n=e.find(e=>e.id===t);n&&i(n)}),r.delete(a.id),n.add(a.id),t.push(a))}return e.forEach(e=>{n.has(e.id)||i(e)}),t}async function Jt(e,t=null){let n=t||await zn(),i=await z().then(e=>e.reactConfig||{}),a=i.enableToolPreselect===!0,o=i.preselectMinToolCount||10,s={},c=[`plan_task`],l=n.filter(e=>!c.includes(e.id));if(l.length<=o)return r.debug(`[Background] subtasktoolfilter:tool count ${l.length} <= ${o},full count inherit (excluded plan_task)`),e.forEach(e=>{s[e.id]=[...l]}),s;let u=[`clarify_question`];return e.forEach(e=>{if(a&&Array.isArray(e.requiredTools)&&e.requiredTools.length>0){let t=l.filter(t=>e.requiredTools.includes(t.id)),n=l.filter(e=>u.includes(e.id));s[e.id]=[...t,...n],r.debug(`[Background] subtask ${e.name} filter tools: ${t.length}/${l.length} (pre-filter mode)`)}else s[e.id]=[...l],r.debug(`[Background] subtask ${e.name} inherit parent task ${l.length} tool (excluded plan_task)`)}),s}async function Yt(e,n,i,a,o,s=null){let l=e.function?.name||e.name;if(l===`clarify_question`)return r.debug(`[Background] clarificationtooldirectly execute, no outertimeout (overall looptimeoutpaused)`),or(e,n,s);let u=c[l],d=u?Math.min(u,i):i;r.debug(`[Background] tool ${l} usingtimeout: ${d}ms${u?` (custom: ${u}ms, globallimit: ${i}ms)`:``}`);let f=Ce(s);return new Promise((r,i)=>{let a=setTimeout(()=>{i(Error(t(`reactLoop.toolTimeout`,{timeout:d,tool:l})))},d),o=()=>{clearTimeout(a),i(Error(t(`reactLoop.toolAborted`,{tool:l})))};f&&!f.signal.aborted&&f.signal.addEventListener(`abort`,o,{once:!0}),or(e,n,s).then(e=>{clearTimeout(a),f&&(f.signal.removeEventListener(`abort`,o),Te(s)),r(e)}).catch(e=>{clearTimeout(a),f&&(f.signal.removeEventListener(`abort`,o),Te(s)),i(e)})})}function Xt(e,n,i={},a=null,o={},s=null){return z().then(c=>{i.imageApiBase&&(c.apiBase=i.imageApiBase),i.imageApiKey&&(c.apiKey=i.imageApiKey);let l=(a?_e(a):null)?.signal,u=`${c.apiBase}/chat/completions`,d=O(e),f=c.streamConfig?.streamEnabled!==!1;r.debug(`[Background] send API request to :`,u,`streaming:`,f);let p={model:n||c.modelName,messages:b(d),stream:f};return f&&(p.stream_options={include_usage:!0}),i.temperature!==void 0&&(p.temperature=i.temperature),i.top_p!==void 0&&(p.top_p=i.top_p),f&&a&&(chrome.runtime.sendMessage({type:`STREAM_START`,sessionId:a,callId:s}).catch(()=>{}),r.debug(`[Background] STREAM_START sent (API call with before )`)),pr(u,{method:`POST`,headers:{Authorization:`Bearer ${c.apiKey}`,"Content-Type":`application/json`},body:JSON.stringify(p),signal:l},c.reactConfig.apiTimeout,c.reactConfig.apiRetryCount,c.reactConfig.apiRetryBaseDelay).then(async e=>{if(!e.ok){let t=await e.text();throw r.error(`[Background] API response error:`,e.status,t),Error(`HTTP error! status: ${e.status}, message: ${t.substring(0,500)}`)}if(f&&e.body){let t=new ct(a,c.streamConfig,{...o,callId:s,preStarted:!0}),n=await lt(e.body.getReader(),t,l);return r.debug(`[Background] streaming API responsecomplete,content length:`,n.content.length,`usage:`,n.usage),{content:n.content,usage:n.usage,reasoningContent:n.reasoningContent}}let n=await e.text();r.debug(`[Background] non-streaming API responsestate:`,e.status,`text length:`,n.length,`preview:`,n.substring(0,200));try{let e=JSON.parse(n);return r.debug(`[Background] API response:`,JSON.stringify(e).substring(0,200)),{content:e.choices?.[0]?.message?.content||``,usage:e.usage||null}}catch(i){throw r.error(`[Background] JSON parse failed,originalresponse:`,n.substring(0,500)),Error(t(`reactLoop.jsonParseFailed`,{status:e.status,error:i.message,preview:n.substring(0,100)}))}}).catch(e=>{throw e.name===`AbortError`?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e),e})})}async function Zt(e){return M.find(t=>t.id===e)||((await chrome.storage.local.get([`customAgents`])).customAgents||[]).find(t=>t.id===e)||null}async function Qt(e,t){let n=e.systemPrompt||``;n.trim()||(n=`You are an AI assistant. Please complete the following task.`);try{let t=``;e.skillIds!=null&&Array.isArray(e.skillIds)&&e.skillIds.length>0?t=(await $e(e.skillIds)).prompts||``:e.skillIds??(t=(await Qe()).prompts||``),t&&(n+=`
99
99
 
100
100
  `+t)}catch{}return`${n}
101
101
 
@@ -106,13 +106,13 @@ ${t}
106
106
  - You are a sub-agent; only complete the task assigned to you
107
107
  - Use your available tools to complete the task efficiently
108
108
  - Return the result directly after completion; no extra confirmation is needed
109
- - Current time: ${new Date().toLocaleString(`zh-CN`)}`}async function Zt(e,t,n){let i=e.subAgentId||e.agent_id||e.sub_agent_id,a=e.task;if(!i||!a)return{success:!1,error:`Missing parameters: subAgentId/sub_agent_id and task are both required`,tool_call_id:t};r.debug(`[AgentDispatcher] dispatchsub Agent:`,i,`task:`,a.substring(0,100));let o=await Yt(i);if(!o)return{success:!1,error:`Sub-agent not found: ${i}`,tool_call_id:t};r.debug(`[AgentDispatcher] sub Agent:`,o.name);let s=await Ln(o.toolIds,o.id,o.skillIds);r.debug(`[AgentDispatcher] sub Agent tool count :`,s.length);let c=[{role:`system`,content:await Xt(o,a)}],l=await z(),u=n?`${n}_sub_${i}`:`sub_${i}`,d={temperature:o.temperature!==null&&o.temperature!==void 0?o.temperature:l.temperature===void 0?.2:l.temperature,top_p:o.topP!==null&&o.topP!==void 0?o.topP:l.topP===void 0?1:l.topP},f=o.model||l.modelName||`deepseek-v4-pro`;try{let e;if(s.length>0){r.debug(`[AgentDispatcher] sub Agent using ReAct mode,tool count :`,s.length,`subSessionId:`,u);let t=await Ht(c,f,s,null,d,u,{type:`subagent`,agentId:i},null,{value:0});e=t.content===void 0?t:t.content}else{r.debug(`[AgentDispatcher] sub Agent using non-streamingmode ( no tool), subSessionId:`,u);let t=await Jt(c,f,d,u);e=t.content===void 0?t:t.content}let n=4e3,a=typeof e==`string`&&e.length>n?e.substring(0,n)+`
109
+ - Current time: ${new Date().toLocaleString(`zh-CN`)}`}async function $t(e,t,n){let i=e.subAgentId||e.agent_id||e.sub_agent_id,a=e.task;if(!i||!a)return{success:!1,error:`Missing parameters: subAgentId/sub_agent_id and task are both required`,tool_call_id:t};r.debug(`[AgentDispatcher] dispatchsub Agent:`,i,`task:`,a.substring(0,100));let o=await Zt(i);if(!o)return{success:!1,error:`Sub-agent not found: ${i}`,tool_call_id:t};r.debug(`[AgentDispatcher] sub Agent:`,o.name);let s=await zn(o.toolIds,o.id,o.skillIds);r.debug(`[AgentDispatcher] sub Agent tool count :`,s.length);let c=[{role:`system`,content:await Qt(o,a)}],l=await z(),u=n?`${n}_sub_${i}`:`sub_${i}`,d={temperature:o.temperature!==null&&o.temperature!==void 0?o.temperature:l.temperature===void 0?.2:l.temperature,top_p:o.topP!==null&&o.topP!==void 0?o.topP:l.topP===void 0?1:l.topP},f=o.model||l.modelName||`deepseek-v4-pro`;try{let e;if(s.length>0){r.debug(`[AgentDispatcher] sub Agent using ReAct mode,tool count :`,s.length,`subSessionId:`,u);let t=await Wt(c,f,s,null,d,u,{type:`subagent`,agentId:i},null,{value:0});e=t.content===void 0?t:t.content}else{r.debug(`[AgentDispatcher] sub Agent using non-streamingmode ( no tool), subSessionId:`,u);let t=await Xt(c,f,d,u);e=t.content===void 0?t:t.content}let n=4e3,a=typeof e==`string`&&e.length>n?e.substring(0,n)+`
110
110
 
111
- ... (result truncated)`:e;return r.debug(`[AgentDispatcher] sub Agent execution complete:`,o.name,`result length:`,typeof a==`string`?a.length:`N/A`),{success:!0,content:`## Sub-agent [${o.name}] Execution Result\n\n${a}`,tool_call_id:t}}catch(e){return r.error(`[AgentDispatcher] sub Agent execution failed:`,e),{success:!1,error:`Sub-agent [${o.name}] execution failed: ${e.message||e}`,tool_call_id:t}}}function Qt(e,t){let n=`screenshot_${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.${t===`png`?`png`:`jpg`}`;chrome.downloads.download({url:e,filename:`Downloads/`+n,saveAs:!1},e=>{chrome.runtime.lastError?r.error(`[Background] download failed:`,chrome.runtime.lastError.message):r.debug(`[Background] screenshottriggerdownload,ID:`,e,`filename:`,n)})}e(`zh`,{toolHelpers:{operationFailed:`操作失败: {error}`,unknownResultFormat:`未知结果格式`,cannotAccessTab:`无法访问该标签页: {message}`,cannotUseOnSystemPage:`无法在系统页面使用工具: {url}`,contentScriptNotFound:`无法找到 content script 文件`,injectContentScriptFailed:`注入 Content Script 失败: {message}`}}),e(`en`,{toolHelpers:{operationFailed:`Operation failed: {error}`,unknownResultFormat:`Unknown result format`,cannotAccessTab:`Cannot access this tab: {message}`,cannotUseOnSystemPage:`Cannot use tools on system pages: {url}`,contentScriptNotFound:`Cannot find content script file`,injectContentScriptFailed:`Failed to inject Content Script: {message}`}});function $t(e){if(!e||typeof e!=`string`)return e;let t=!1,n=!1,r=[];for(let i=0;i<e.length;i++){let a=e[i];if(n){n=!1;continue}if(a===`\\`&&t){n=!0;continue}if(a===`"`&&!n){t=!t;continue}if(!t){if(a===`{`||a===`[`||a===`(`)r.push(a);else if(a===`}`||a===`]`||a===`)`){let e=a===`}`?`{`:a===`]`?`[`:`(`;r.length>0&&r[r.length-1]===e&&r.pop()}}}let i=e;t&&(i+=`"`),i=i.replace(/,\s*$/,``);let a={"{":`}`,"[":`]`,"(":`)`};for(;r.length>0;){let e=r.pop();i+=a[e]}return i}function en(e){if(!e||typeof e!=`string`)return e;let t=[],n=!1,r=!1,i=[],a=0;for(;a<e.length;){let o=e[a];if(r){t.push(o),r=!1,a++;continue}if(o===`\\`&&n){t.push(o),r=!0,a++;continue}if(o===`"`&&i.length>0&&i[i.length-1]===`[`){let t=e.substring(a).match(/^"[^"]+"\s*:\s*(true|false|null|-?\d+(?:\.\d+)?|"[^"]*")/);if(t){for(a+=t[0].length;a<e.length&&`
111
+ ... (result truncated)`:e;return r.debug(`[AgentDispatcher] sub Agent execution complete:`,o.name,`result length:`,typeof a==`string`?a.length:`N/A`),{success:!0,content:`## Sub-agent [${o.name}] Execution Result\n\n${a}`,tool_call_id:t}}catch(e){return r.error(`[AgentDispatcher] sub Agent execution failed:`,e),{success:!1,error:`Sub-agent [${o.name}] execution failed: ${e.message||e}`,tool_call_id:t}}}function en(e,t){let n=`screenshot_${new Date().toISOString().replace(/[:.]/g,`-`).slice(0,19)}.${t===`png`?`png`:`jpg`}`;chrome.downloads.download({url:e,filename:`Downloads/`+n,saveAs:!1},e=>{chrome.runtime.lastError?r.error(`[Background] download failed:`,chrome.runtime.lastError.message):r.debug(`[Background] screenshottriggerdownload,ID:`,e,`filename:`,n)})}e(`zh`,{toolHelpers:{operationFailed:`操作失败: {error}`,unknownResultFormat:`未知结果格式`,cannotAccessTab:`无法访问该标签页: {message}`,cannotUseOnSystemPage:`无法在系统页面使用工具: {url}`,contentScriptNotFound:`无法找到 content script 文件`,injectContentScriptFailed:`注入 Content Script 失败: {message}`}}),e(`en`,{toolHelpers:{operationFailed:`Operation failed: {error}`,unknownResultFormat:`Unknown result format`,cannotAccessTab:`Cannot access this tab: {message}`,cannotUseOnSystemPage:`Cannot use tools on system pages: {url}`,contentScriptNotFound:`Cannot find content script file`,injectContentScriptFailed:`Failed to inject Content Script: {message}`}});function tn(e){if(!e||typeof e!=`string`)return e;let t=!1,n=!1,r=[];for(let i=0;i<e.length;i++){let a=e[i];if(n){n=!1;continue}if(a===`\\`&&t){n=!0;continue}if(a===`"`&&!n){t=!t;continue}if(!t){if(a===`{`||a===`[`||a===`(`)r.push(a);else if(a===`}`||a===`]`||a===`)`){let e=a===`}`?`{`:a===`]`?`[`:`(`;r.length>0&&r[r.length-1]===e&&r.pop()}}}let i=e;t&&(i+=`"`),i=i.replace(/,\s*$/,``);let a={"{":`}`,"[":`]`,"(":`)`};for(;r.length>0;){let e=r.pop();i+=a[e]}return i}function nn(e){if(!e||typeof e!=`string`)return e;let t=[],n=!1,r=!1,i=[],a=0;for(;a<e.length;){let o=e[a];if(r){t.push(o),r=!1,a++;continue}if(o===`\\`&&n){t.push(o),r=!0,a++;continue}if(o===`"`&&i.length>0&&i[i.length-1]===`[`){let t=e.substring(a).match(/^"[^"]+"\s*:\s*(true|false|null|-?\d+(?:\.\d+)?|"[^"]*")/);if(t){for(a+=t[0].length;a<e.length&&`
112
112
  \r`.includes(e[a]);)a++;for(a<e.length&&e[a]===`,`&&a++;a<e.length&&`
113
113
  \r`.includes(e[a]);)a++;continue}}if(o===`"`){n=!n,t.push(o),a++;continue}if(n){t.push(o),a++;continue}if(o===`{`||o===`[`){i.push(o),t.push(o),a++;continue}if(o===`}`||o===`]`){i.length>0&&i.pop(),t.push(o),a++;continue}t.push(o),a++}let o=t.join(``);return o=o.replace(/,\s*,/g,`,`),o=o.replace(/,\s*([}\]])/g,`$1`),o=o.replace(/\[\s*,/g,`[`),o=o.replace(/,\s*\]/g,`]`),o}function Y(e,t,n={}){return{success:e,content:t,...n}}e(`zh`,{toolMemory:{missingAction:`缺少 action 参数`,missingType:`缺少 type 参数`,missingContent:`缺少 content 参数`,readFailed:`读取记忆文件失败: {error}`,writeFailed:`写入记忆文件失败: {error}`,parseFailed:`记忆文件解析失败: {error}`,updatedDuplicate:`已更新已有记忆: {id}(内容相同,已合并)`,added:`已添加记忆: {id} ({type}){warning}`,nearLimitWarning:`
114
114
  ⚠️ 记忆数量接近上限(事实: {facts}/{maxFacts}, 摘要: {summaries}/{maxSummaries}),建议调用 agent_memory action=manage 进行审查整理。`,updateNeedsId:`update 操作需要 memoryId 参数`,deleteNeedsId:`delete 操作需要 memoryId 参数`,typeMismatch:`记忆 {id} 类型不匹配(实际类型: {type})`,notFound:`未找到记忆: {id}`,updated:`已更新记忆: {id}`,deleted:`已删除记忆: {id}`,unsupportedAction:`不支持的操作: {action}`,storeMissingSubAction:`store 操作缺少 subAction (add/update/delete)`,manageMissingSubAction:`manage 操作缺少 subAction (review/compact)`,unsupportedMemoryAction:`不支持的 action: {action}`,memoryEmpty:`记忆文件为空,暂无存储的记忆。`,noMatch:`未找到匹配的记忆。`,foundResults:`找到 {count} 条相关记忆:{note}`,recallNoteAllOld:`(注:以上记忆在本对话中已检索过,此处为重复返回)`,recallNoteMixed:`(注:{oldCount} 条记忆在本对话中已检索过,仅返回新的 {newCount} 条)`,compactDone:`记忆压缩完成。移除了 {facts} 条事实记忆和 {summaries} 条摘要记忆(价值低于 {threshold})。当前: 事实 {totalFacts}, 摘要 {totalSummaries}`,reviewTitle:`## 记忆审查报告`,reviewOverview:`**概况**: 事实 {facts}/{maxFacts}, 摘要 {summaries}/{maxSummaries}`,reviewLastReview:`**上次审查**: {date}`,reviewNeverReviewed:`从未审查`,reviewCandidates:`**低价值记忆候选** (价值 < {threshold}):`,reviewNoCandidates:`无候选淘汰项,所有记忆价值良好。`,reviewSuggestion:`**建议操作**:`,reviewSuggestionDelete:`- 对于确实过时/不再适用的记忆,使用 agent_memory action=store subAction=delete 删除`,reviewSuggestionMerge:`- 对于内容相似的记忆,使用 agent_memory action=store subAction=update 合并`,reviewSuggestionKeep:`- 对于仍有用但价值低的记忆,可保留不做处理`,factLabel:`事实`,summaryLabel:`摘要`,neverAccessed:`从未`,memoryItemHeader:`**{index}. [{type}] {id}**`,memoryItemContent:` 内容: {content}`,memoryItemTitle:` 标题: {title}`,memoryItemTags:` 标签: {tags}`,memoryItemStats:` 重要性: {importance}/10 | 访问: {accessCount}次 | 创建: {createdAt}`,reviewItemCreated:` 创建: {createdAt} | 最后访问: {lastAccess} | 访问: {accessCount}次`}}),e(`en`,{toolMemory:{missingAction:`Missing action parameter`,missingType:`Missing type parameter`,missingContent:`Missing content parameter`,readFailed:`Failed to read memory file: {error}`,writeFailed:`Failed to write memory file: {error}`,parseFailed:`Memory file parse failed: {error}`,updatedDuplicate:`Updated existing memory: {id} (content identical, merged)`,added:`Added memory: {id} ({type}){warning}`,nearLimitWarning:`
115
- ⚠️ Memory count approaching limit (facts: {facts}/{maxFacts}, summaries: {summaries}/{maxSummaries}). Consider calling agent_memory action=manage to review and clean up.`,updateNeedsId:`update action requires memoryId parameter`,deleteNeedsId:`delete action requires memoryId parameter`,typeMismatch:`Memory {id} type mismatch (actual type: {type})`,notFound:`Memory not found: {id}`,updated:`Updated memory: {id}`,deleted:`Deleted memory: {id}`,unsupportedAction:`Unsupported action: {action}`,storeMissingSubAction:`store action missing subAction (add/update/delete)`,manageMissingSubAction:`manage action missing subAction (review/compact)`,unsupportedMemoryAction:`Unsupported action: {action}`,memoryEmpty:`Memory file is empty, no stored memories.`,noMatch:`No matching memories found.`,foundResults:`Found {count} relevant memories:{note}`,recallNoteAllOld:`(Note: The above memories have already been retrieved in this conversation, returned again)`,recallNoteMixed:`(Note: {oldCount} memories already retrieved in this conversation, only returning {newCount} new ones)`,compactDone:`Memory compaction complete. Removed {facts} fact memories and {summaries} summary memories (value below {threshold}). Current: facts {totalFacts}, summaries {totalSummaries}`,reviewTitle:`## Memory Review Report`,reviewOverview:`**Overview**: Facts {facts}/{maxFacts}, Summaries {summaries}/{maxSummaries}`,reviewLastReview:`**Last review**: {date}`,reviewNeverReviewed:`Never reviewed`,reviewCandidates:`**Low-value memory candidates** (value < {threshold}):`,reviewNoCandidates:`No candidates for removal, all memories have good value.`,reviewSuggestion:`**Suggested actions**:`,reviewSuggestionDelete:`- For outdated/no longer applicable memories, use agent_memory action=store subAction=delete to remove`,reviewSuggestionMerge:`- For similar memories, use agent_memory action=store subAction=update to merge`,reviewSuggestionKeep:`- For still useful but low-value memories, keep them as-is`,factLabel:`Fact`,summaryLabel:`Summary`,neverAccessed:`Never`,memoryItemHeader:`**{index}. [{type}] {id}**`,memoryItemContent:` Content: {content}`,memoryItemTitle:` Title: {title}`,memoryItemTags:` Tags: {tags}`,memoryItemStats:` Importance: {importance}/10 | Access: {accessCount} times | Created: {createdAt}`,reviewItemCreated:` Created: {createdAt} | Last access: {lastAccess} | Access: {accessCount} times`}});var tn=null;async function nn(){for(;tn;)await tn;let e;return tn=new Promise(t=>{e=t}),()=>{e&&=(e(),tn=null,null)}}var rn=`~/.ai-helper-agent/memory/global-memory.json`,an={version:1,updatedAt:new Date().toISOString(),stats:{totalFacts:0,totalSummaries:0,lastReviewAt:null},facts:[],summaries:[],meta:{maxFacts:50,maxSummaries:20,reviewThreshold:.8}};async function on(){let e=await je(rn);if(!e.success)return e.error&&(e.error.includes(`ENOENT`)||e.error.includes(`File does not exist`)||e.error.includes(`文件不存在`))?{success:!0,data:{...an,updatedAt:new Date().toISOString()}}:{success:!1,error:e.error};try{let t=JSON.parse(e.content);return{success:!0,data:{...an,...t,meta:{...an.meta,...t.meta||{}}}}}catch(e){return{success:!1,error:t(`toolMemory.parseFailed`,{error:e.message})}}}async function sn(e){return e.updatedAt=new Date().toISOString(),e.stats.totalFacts=(e.facts||[]).length,e.stats.totalSummaries=(e.summaries||[]).length,e.version=e.version||1,Ne(rn,JSON.stringify(e,null,2))}function cn(e){return`${e===`fact`?`fact`:`sum`}_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,6)}`}function ln(e,t){let n=e.importance||5,r=e.accessCount||0,i=(t-new Date(e.createdAt).getTime())/864e5,a;return a=i<=7?1:i<=30?.8:i<=90?.5:.2,n*(1+Math.log(r+1))*a}async function un(e){let t=await nn();try{return await e()}finally{t()}}async function dn(e,n){let{action:r,type:i,category:a,content:o,title:s,tags:c,importance:l,memoryId:u,sourceSessionId:d}=e;return r?!i&&r!==`delete`?Y(!1,t(`toolMemory.missingType`),n):!o&&r!==`delete`?Y(!1,t(`toolMemory.missingContent`),n):un(async()=>{let e=await on();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let f=e.data,p=new Date().toISOString(),m=i===`fact`?f.facts:f.summaries;if(r===`add`){let e={id:cn(i),type:i,category:a||`custom`,content:o,tags:c||[],importance:l||5,accessCount:0,lastAccessAt:null,createdAt:p,updatedAt:p,sourceSessionId:d||null};i===`summary`&&s&&(e.title=s);let r=m.find(e=>e.content===o&&e.type===i);if(r){r.updatedAt=p,r.tags=c||r.tags,r.importance=l||r.importance,r.sourceSessionId=d||r.sourceSessionId;let e=await sn(f);return e.success?{...Y(!0,t(`toolMemory.updatedDuplicate`,{id:r.id}),n),memory:r,action:`updated`,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:e.error}),n)}m.push(e);let u=await sn(f);if(!u.success)return Y(!1,t(`toolMemory.writeFailed`,{error:u.error}),n);let h=f.meta.maxFacts,g=f.meta.maxSummaries,_=f.facts.length/h,v=f.summaries.length/g,y=``;return(_>=.8||v>=.8)&&(y=t(`toolMemory.nearLimitWarning`,{facts:f.facts.length,maxFacts:h,summaries:f.summaries.length,maxSummaries:g})),{...Y(!0,t(`toolMemory.added`,{id:e.id,type:i,warning:y}),n),memory:e,action:`added`,stats:f.stats}}if(r===`update`){if(!u)return Y(!1,t(`toolMemory.updateNeedsId`),n);let e=m.findIndex(e=>e.id===u);if(e===-1){let e=i===`fact`?f.summaries:f.facts,r=e.findIndex(e=>e.id===u);return r===-1?Y(!1,t(`toolMemory.notFound`,{id:u}),n):Y(!1,t(`toolMemory.typeMismatch`,{id:u,type:e[r].type}),n)}let r=m[e];o!==void 0&&(r.content=o),c!==void 0&&(r.tags=c),l!==void 0&&(r.importance=l),a!==void 0&&(r.category=a),i===`summary`&&s!==void 0&&(r.title=s),r.updatedAt=p;let d=await sn(f);return d.success?{...Y(!0,t(`toolMemory.updated`,{id:u}),n),memory:r,action:`updated`,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:d.error}),n)}if(r===`delete`){if(!u)return Y(!1,t(`toolMemory.deleteNeedsId`),n);let e=[f.facts,f.summaries];for(let r of e){let e=r.findIndex(e=>e.id===u);if(e!==-1){let i=r.splice(e,1)[0];pn(u);let a=await sn(f);return a.success?{...Y(!0,t(`toolMemory.deleted`,{id:u}),n),removed:i,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:a.error}),n)}}return Y(!1,t(`toolMemory.notFound`,{id:u}),n)}return Y(!1,t(`toolMemory.unsupportedAction`,{action:r}),n)}):Y(!1,t(`toolMemory.missingAction`),n)}var fn=new Map;function pn(e){for(let[t,n]of fn.entries())n.has(e)&&(n.delete(e),n.size===0&&fn.delete(t))}async function mn(e,n,i){let{query:a,tags:o,memoryType:s=`all`,limit:c=10}=e;return un(async()=>{let e=await on();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let l=e.data,u=[];if((s===`all`||s===`fact`)&&u.push(...l.facts.map(e=>({...e,_source:`facts`}))),(s===`all`||s===`summary`)&&u.push(...l.summaries.map(e=>({...e,_source:`summaries`}))),u.length===0)return{...Y(!0,t(`toolMemory.memoryEmpty`),n),results:[],total:0};if(o&&o.length>0&&(u=u.filter(e=>{let t=(e.tags||[]).map(e=>e.toLowerCase());return o.some(e=>t.includes(e.toLowerCase()))})),a&&a.trim()){let e=new Set(`的.是.了.在.我.你.他.她.它.们.这.那.不.也.就.都.会.要.能.可.把.被.让.给.对.从.到.和.与.或.但.而.还.又.只.很.更.最.有.没.吗.呢.吧.啊.什么.怎么.为什么.哪里.哪个.多少.the.a.an.is.are.was.were.be.been.being.have.has.had.do.does.did.will.would.could.should.may.might.can.shall.must.need.dare.this.that.these.those.it.its.they.them.their.in.on.at.to.for.of.with.by.from.as.into.and.or.not.but.if.then.else.when.where.why.how.so.no.up.out.just.now.here.there.all.each.every`.split(`.`));function t(t){let n=t.toLowerCase().trim(),r=n.length>200?n.slice(0,200):n,i=r.split(/([\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+|[a-z]+|\d+|[^a-z\d\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+)/i),a=[];r.length>=2&&a.push(r);for(let e of i)if(!(!e||e.trim().length===0)){if(/^[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+$/.test(e)){if(e.length<=4)a.push(e);else for(let t=0;t<=e.length-2;t++)a.push(e.substring(t,t+2))}else/^[a-z\d]+$/.test(e)&&e.length>=2&&a.push(e)}return[...new Set(a)].filter(t=>t.length>=1&&!e.has(t)).slice(0,30)}let n=t(a),r=a.toLowerCase().trim();if(n.length>0&&(u=u.map(e=>{let t=0,i=(e.content||``).toLowerCase(),a=(e.title||``).toLowerCase(),o=(e.tags||[]).map(e=>e.toLowerCase());for(let e of n)i.includes(e)&&(t+=3),a.includes(e)&&(t+=2),o.some(t=>t.includes(e))&&(t+=2);return r.length>=2&&(i.includes(r)&&(t+=5),a.includes(r)&&(t+=3)),{memory:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score).map(e=>e.memory),u.length===0&&r.length>=2)){let e=u.filter(e=>{let t=(e.content||``).toLowerCase(),n=(e.title||``).toLowerCase();return t.includes(r)||n.includes(r)}).map(e=>({memory:e,score:5})).sort((e,t)=>t.score-e.score).map(e=>e.memory);e.length>0&&(u=e)}}let d=new Set,f=u.filter(e=>!d.has(e.id)&&(d.add(e.id),!0)).slice(0,c),p=``;if(i){let e=fn.get(i);if(e&&e.size>0){let n=[],r=[];for(let t of f)e.has(t.id)?r.push(t):n.push(t);n.length===0&&r.length>0?(p=t(`toolMemory.recallNoteAllOld`),f=r):n.length>0&&(r.length>0&&(p=t(`toolMemory.recallNoteMixed`,{oldCount:r.length,newCount:n.length})),f=n)}}if(i&&f.length>0){fn.has(i)||fn.set(i,new Set);let e=fn.get(i);for(let t of f)e.add(t.id)}for(let e of f){let t=(e._source===`facts`?l.facts:l.summaries).find(t=>t.id===e.id);t&&(t.accessCount=(t.accessCount||0)+1,t.lastAccessAt=new Date().toISOString(),delete e._source)}try{await sn(l)}catch(e){r.warn(`[Memory] update visitcount failed:`,e.message)}return{success:!0,message:f.length===0?t(`toolMemory.noMatch`):t(`toolMemory.foundResults`,{count:f.length,note:p})+`
115
+ ⚠️ Memory count approaching limit (facts: {facts}/{maxFacts}, summaries: {summaries}/{maxSummaries}). Consider calling agent_memory action=manage to review and clean up.`,updateNeedsId:`update action requires memoryId parameter`,deleteNeedsId:`delete action requires memoryId parameter`,typeMismatch:`Memory {id} type mismatch (actual type: {type})`,notFound:`Memory not found: {id}`,updated:`Updated memory: {id}`,deleted:`Deleted memory: {id}`,unsupportedAction:`Unsupported action: {action}`,storeMissingSubAction:`store action missing subAction (add/update/delete)`,manageMissingSubAction:`manage action missing subAction (review/compact)`,unsupportedMemoryAction:`Unsupported action: {action}`,memoryEmpty:`Memory file is empty, no stored memories.`,noMatch:`No matching memories found.`,foundResults:`Found {count} relevant memories:{note}`,recallNoteAllOld:`(Note: The above memories have already been retrieved in this conversation, returned again)`,recallNoteMixed:`(Note: {oldCount} memories already retrieved in this conversation, only returning {newCount} new ones)`,compactDone:`Memory compaction complete. Removed {facts} fact memories and {summaries} summary memories (value below {threshold}). Current: facts {totalFacts}, summaries {totalSummaries}`,reviewTitle:`## Memory Review Report`,reviewOverview:`**Overview**: Facts {facts}/{maxFacts}, Summaries {summaries}/{maxSummaries}`,reviewLastReview:`**Last review**: {date}`,reviewNeverReviewed:`Never reviewed`,reviewCandidates:`**Low-value memory candidates** (value < {threshold}):`,reviewNoCandidates:`No candidates for removal, all memories have good value.`,reviewSuggestion:`**Suggested actions**:`,reviewSuggestionDelete:`- For outdated/no longer applicable memories, use agent_memory action=store subAction=delete to remove`,reviewSuggestionMerge:`- For similar memories, use agent_memory action=store subAction=update to merge`,reviewSuggestionKeep:`- For still useful but low-value memories, keep them as-is`,factLabel:`Fact`,summaryLabel:`Summary`,neverAccessed:`Never`,memoryItemHeader:`**{index}. [{type}] {id}**`,memoryItemContent:` Content: {content}`,memoryItemTitle:` Title: {title}`,memoryItemTags:` Tags: {tags}`,memoryItemStats:` Importance: {importance}/10 | Access: {accessCount} times | Created: {createdAt}`,reviewItemCreated:` Created: {createdAt} | Last access: {lastAccess} | Access: {accessCount} times`}});var rn=null;async function an(){for(;rn;)await rn;let e;return rn=new Promise(t=>{e=t}),()=>{e&&=(e(),rn=null,null)}}var on=`~/.ai-helper-agent/memory/global-memory.json`,sn={version:1,updatedAt:new Date().toISOString(),stats:{totalFacts:0,totalSummaries:0,lastReviewAt:null},facts:[],summaries:[],meta:{maxFacts:50,maxSummaries:20,reviewThreshold:.8}};async function cn(){let e=await je(on);if(!e.success)return e.error&&(e.error.includes(`ENOENT`)||e.error.includes(`File does not exist`)||e.error.includes(`文件不存在`))?{success:!0,data:{...sn,updatedAt:new Date().toISOString()}}:{success:!1,error:e.error};try{let t=JSON.parse(e.content);return{success:!0,data:{...sn,...t,meta:{...sn.meta,...t.meta||{}}}}}catch(e){return{success:!1,error:t(`toolMemory.parseFailed`,{error:e.message})}}}async function ln(e){return e.updatedAt=new Date().toISOString(),e.stats.totalFacts=(e.facts||[]).length,e.stats.totalSummaries=(e.summaries||[]).length,e.version=e.version||1,Ne(on,JSON.stringify(e,null,2))}function un(e){return`${e===`fact`?`fact`:`sum`}_${Date.now().toString(36)}_${Math.random().toString(36).substring(2,6)}`}function dn(e,t){let n=e.importance||5,r=e.accessCount||0,i=(t-new Date(e.createdAt).getTime())/864e5,a;return a=i<=7?1:i<=30?.8:i<=90?.5:.2,n*(1+Math.log(r+1))*a}async function fn(e){let t=await an();try{return await e()}finally{t()}}async function pn(e,n){let{action:r,type:i,category:a,content:o,title:s,tags:c,importance:l,memoryId:u,sourceSessionId:d}=e;return r?!i&&r!==`delete`?Y(!1,t(`toolMemory.missingType`),n):!o&&r!==`delete`?Y(!1,t(`toolMemory.missingContent`),n):fn(async()=>{let e=await cn();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let f=e.data,p=new Date().toISOString(),m=i===`fact`?f.facts:f.summaries;if(r===`add`){let e={id:un(i),type:i,category:a||`custom`,content:o,tags:c||[],importance:l||5,accessCount:0,lastAccessAt:null,createdAt:p,updatedAt:p,sourceSessionId:d||null};i===`summary`&&s&&(e.title=s);let r=m.find(e=>e.content===o&&e.type===i);if(r){r.updatedAt=p,r.tags=c||r.tags,r.importance=l||r.importance,r.sourceSessionId=d||r.sourceSessionId;let e=await ln(f);return e.success?{...Y(!0,t(`toolMemory.updatedDuplicate`,{id:r.id}),n),memory:r,action:`updated`,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:e.error}),n)}m.push(e);let u=await ln(f);if(!u.success)return Y(!1,t(`toolMemory.writeFailed`,{error:u.error}),n);let h=f.meta.maxFacts,g=f.meta.maxSummaries,_=f.facts.length/h,v=f.summaries.length/g,y=``;return(_>=.8||v>=.8)&&(y=t(`toolMemory.nearLimitWarning`,{facts:f.facts.length,maxFacts:h,summaries:f.summaries.length,maxSummaries:g})),{...Y(!0,t(`toolMemory.added`,{id:e.id,type:i,warning:y}),n),memory:e,action:`added`,stats:f.stats}}if(r===`update`){if(!u)return Y(!1,t(`toolMemory.updateNeedsId`),n);let e=m.findIndex(e=>e.id===u);if(e===-1){let e=i===`fact`?f.summaries:f.facts,r=e.findIndex(e=>e.id===u);return r===-1?Y(!1,t(`toolMemory.notFound`,{id:u}),n):Y(!1,t(`toolMemory.typeMismatch`,{id:u,type:e[r].type}),n)}let r=m[e];o!==void 0&&(r.content=o),c!==void 0&&(r.tags=c),l!==void 0&&(r.importance=l),a!==void 0&&(r.category=a),i===`summary`&&s!==void 0&&(r.title=s),r.updatedAt=p;let d=await ln(f);return d.success?{...Y(!0,t(`toolMemory.updated`,{id:u}),n),memory:r,action:`updated`,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:d.error}),n)}if(r===`delete`){if(!u)return Y(!1,t(`toolMemory.deleteNeedsId`),n);let e=[f.facts,f.summaries];for(let r of e){let e=r.findIndex(e=>e.id===u);if(e!==-1){let i=r.splice(e,1)[0];hn(u);let a=await ln(f);return a.success?{...Y(!0,t(`toolMemory.deleted`,{id:u}),n),removed:i,stats:f.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:a.error}),n)}}return Y(!1,t(`toolMemory.notFound`,{id:u}),n)}return Y(!1,t(`toolMemory.unsupportedAction`,{action:r}),n)}):Y(!1,t(`toolMemory.missingAction`),n)}var mn=new Map;function hn(e){for(let[t,n]of mn.entries())n.has(e)&&(n.delete(e),n.size===0&&mn.delete(t))}async function gn(e,n,i){let{query:a,tags:o,memoryType:s=`all`,limit:c=10}=e;return fn(async()=>{let e=await cn();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let l=e.data,u=[];if((s===`all`||s===`fact`)&&u.push(...l.facts.map(e=>({...e,_source:`facts`}))),(s===`all`||s===`summary`)&&u.push(...l.summaries.map(e=>({...e,_source:`summaries`}))),u.length===0)return{...Y(!0,t(`toolMemory.memoryEmpty`),n),results:[],total:0};if(o&&o.length>0&&(u=u.filter(e=>{let t=(e.tags||[]).map(e=>e.toLowerCase());return o.some(e=>t.includes(e.toLowerCase()))})),a&&a.trim()){let e=new Set(`的.是.了.在.我.你.他.她.它.们.这.那.不.也.就.都.会.要.能.可.把.被.让.给.对.从.到.和.与.或.但.而.还.又.只.很.更.最.有.没.吗.呢.吧.啊.什么.怎么.为什么.哪里.哪个.多少.the.a.an.is.are.was.were.be.been.being.have.has.had.do.does.did.will.would.could.should.may.might.can.shall.must.need.dare.this.that.these.those.it.its.they.them.their.in.on.at.to.for.of.with.by.from.as.into.and.or.not.but.if.then.else.when.where.why.how.so.no.up.out.just.now.here.there.all.each.every`.split(`.`));function t(t){let n=t.toLowerCase().trim(),r=n.length>200?n.slice(0,200):n,i=r.split(/([\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+|[a-z]+|\d+|[^a-z\d\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+)/i),a=[];r.length>=2&&a.push(r);for(let e of i)if(!(!e||e.trim().length===0)){if(/^[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]+$/.test(e)){if(e.length<=4)a.push(e);else for(let t=0;t<=e.length-2;t++)a.push(e.substring(t,t+2))}else/^[a-z\d]+$/.test(e)&&e.length>=2&&a.push(e)}return[...new Set(a)].filter(t=>t.length>=1&&!e.has(t)).slice(0,30)}let n=t(a),r=a.toLowerCase().trim();if(n.length>0&&(u=u.map(e=>{let t=0,i=(e.content||``).toLowerCase(),a=(e.title||``).toLowerCase(),o=(e.tags||[]).map(e=>e.toLowerCase());for(let e of n)i.includes(e)&&(t+=3),a.includes(e)&&(t+=2),o.some(t=>t.includes(e))&&(t+=2);return r.length>=2&&(i.includes(r)&&(t+=5),a.includes(r)&&(t+=3)),{memory:e,score:t}}).filter(e=>e.score>0).sort((e,t)=>t.score-e.score).map(e=>e.memory),u.length===0&&r.length>=2)){let e=u.filter(e=>{let t=(e.content||``).toLowerCase(),n=(e.title||``).toLowerCase();return t.includes(r)||n.includes(r)}).map(e=>({memory:e,score:5})).sort((e,t)=>t.score-e.score).map(e=>e.memory);e.length>0&&(u=e)}}let d=new Set,f=u.filter(e=>!d.has(e.id)&&(d.add(e.id),!0)).slice(0,c),p=``;if(i){let e=mn.get(i);if(e&&e.size>0){let n=[],r=[];for(let t of f)e.has(t.id)?r.push(t):n.push(t);n.length===0&&r.length>0?(p=t(`toolMemory.recallNoteAllOld`),f=r):n.length>0&&(r.length>0&&(p=t(`toolMemory.recallNoteMixed`,{oldCount:r.length,newCount:n.length})),f=n)}}if(i&&f.length>0){mn.has(i)||mn.set(i,new Set);let e=mn.get(i);for(let t of f)e.add(t.id)}for(let e of f){let t=(e._source===`facts`?l.facts:l.summaries).find(t=>t.id===e.id);t&&(t.accessCount=(t.accessCount||0)+1,t.lastAccessAt=new Date().toISOString(),delete e._source)}try{await ln(l)}catch(e){r.warn(`[Memory] update visitcount failed:`,e.message)}return{success:!0,message:f.length===0?t(`toolMemory.noMatch`):t(`toolMemory.foundResults`,{count:f.length,note:p})+`
116
116
 
117
117
  `+f.map((e,n)=>{let r=t(`toolMemory.memoryItemHeader`,{index:n+1,type:e.type===`fact`?t(`toolMemory.factLabel`):t(`toolMemory.summaryLabel`),id:e.id})+`
118
118
  `;return r+=t(`toolMemory.memoryItemContent`,{content:e.content})+`
@@ -120,7 +120,7 @@ ${t}
120
120
  `),e.tags&&e.tags.length>0&&(r+=t(`toolMemory.memoryItemTags`,{tags:e.tags.join(`, `)})+`
121
121
  `),r+=t(`toolMemory.memoryItemStats`,{importance:e.importance,accessCount:e.accessCount,createdAt:e.createdAt}),r}).join(`
122
122
 
123
- `),results:f.map(e=>{let{_source:t,...n}=e;return n}),total:f.length,query:a,tool_call_id:n}})}async function hn(e,n){let{action:r}=e;return r?un(async()=>{let e=await on();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let i=e.data,a=Date.now();if(r===`review`){let e=[...i.facts.map(e=>({...e,_source:`facts`})),...i.summaries.map(e=>({...e,_source:`summaries`}))].map(e=>({id:e.id,type:e.type,category:e.category,content:e.content,title:e.title,tags:e.tags,importance:e.importance,accessCount:e.accessCount||0,lastAccessAt:e.lastAccessAt,createdAt:e.createdAt,value:ln(e,a).toFixed(2),_source:e._source})).sort((e,t)=>parseFloat(e.value)-parseFloat(t.value)),r=i.facts.length,o=i.summaries.length,s=i.meta.maxFacts,c=i.meta.maxSummaries,l=e.filter(e=>parseFloat(e.value)<10);return{...Y(!0,t(`toolMemory.reviewTitle`)+`
123
+ `),results:f.map(e=>{let{_source:t,...n}=e;return n}),total:f.length,query:a,tool_call_id:n}})}async function _n(e,n){let{action:r}=e;return r?fn(async()=>{let e=await cn();if(!e.success)return Y(!1,t(`toolMemory.readFailed`,{error:e.error}),n);let i=e.data,a=Date.now();if(r===`review`){let e=[...i.facts.map(e=>({...e,_source:`facts`})),...i.summaries.map(e=>({...e,_source:`summaries`}))].map(e=>({id:e.id,type:e.type,category:e.category,content:e.content,title:e.title,tags:e.tags,importance:e.importance,accessCount:e.accessCount||0,lastAccessAt:e.lastAccessAt,createdAt:e.createdAt,value:dn(e,a).toFixed(2),_source:e._source})).sort((e,t)=>parseFloat(e.value)-parseFloat(t.value)),r=i.facts.length,o=i.summaries.length,s=i.meta.maxFacts,c=i.meta.maxSummaries,l=e.filter(e=>parseFloat(e.value)<10);return{...Y(!0,t(`toolMemory.reviewTitle`)+`
124
124
 
125
125
  `+t(`toolMemory.reviewOverview`,{facts:r,maxFacts:s,summaries:o,maxSummaries:c})+`
126
126
  `+t(`toolMemory.reviewLastReview`,{date:i.stats.lastReviewAt||t(`toolMemory.reviewNeverReviewed`)})+`
@@ -135,7 +135,7 @@ ${t}
135
135
  `+t(`toolMemory.reviewSuggestion`)+`
136
136
  `+t(`toolMemory.reviewSuggestionDelete`)+`
137
137
  `+t(`toolMemory.reviewSuggestionMerge`)+`
138
- `+t(`toolMemory.reviewSuggestionKeep`),n),scored:e.map(e=>{let{_source:t,...n}=e;return n}),candidates:l.map(e=>{let{_source:t,...n}=e;return n}),stats:i.stats}}if(r===`compact`){let e=0,r=0;i.facts=i.facts.filter(t=>ln(t,a)<10?(e++,!1):!0),i.summaries=i.summaries.filter(e=>ln(e,a)<10?(r++,!1):!0),i.stats.lastReviewAt=new Date().toISOString();let o=await sn(i);return o.success?{...Y(!0,t(`toolMemory.compactDone`,{facts:e,summaries:r,threshold:10,totalFacts:i.stats.totalFacts,totalSummaries:i.stats.totalSummaries}),n),removedFacts:e,removedSummaries:r,stats:i.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:o.error}),n)}return Y(!1,t(`toolMemory.unsupportedAction`,{action:r}),n)}):Y(!1,t(`toolMemory.missingAction`),n)}async function gn(e,n,r){let{action:i,subAction:a}=e;return i?i===`recall`?mn(e,n,r):i===`store`?a?dn({...e,action:a},n):Y(!1,t(`toolMemory.storeMissingSubAction`),n):i===`manage`?a?hn({...e,action:a},n):Y(!1,t(`toolMemory.manageMissingSubAction`),n):Y(!1,t(`toolMemory.unsupportedMemoryAction`,{action:i}),n):Y(!1,t(`toolMemory.missingAction`),n)}e(`zh`,{toolExec:{unknown:`未知`,unknownResultFormat:`未知结果格式`,tabAccessDenied:`无法访问该标签页: {error}`,tabErrorPage:`该标签页显示错误页面,页面未能成功加载。请检查 URL 是否正确、网络是否可达`,systemPageNotAllowed:`无法在系统页面使用工具: {url}`,contentScriptNotFound:`无法找到 content script 文件`,contentScriptInjectFailed:`注入 Content Script 失败: {error}`,unknownError:`未知错误`,argParseFailed:`工具参数解析失败`,unknownTool:`未知工具: {name}`,noTabAvailable:`没有可用的标签页`,noTitle:`(无标题)`,clarifyDialogFailed:`无法显示澄清对话框: {error}`,clarifyTimeout:`用户未在规定时间内完成澄清 ({seconds}秒)`,clarifyPanelClosed:`Side Panel 已关闭,澄清操作中止`,missingUrlParam:`缺少 URL 参数`,invalidUrlFormat:`无效的 URL 格式: {url}`,readResponseFailed:`读取响应内容失败: {error}`,tabNotFound:`未找到当前标签页`,getRequiresName:`get操作需要提供name参数`,setRequiresNameValue:`set操作需要提供name和value参数`,removeRequiresName:`remove操作需要提供name参数`,unknownAction:`未知操作: {action}`,missingTaskDesc:`缺少任务描述参数`,emptySubtasks:`子任务列表不能为空`,invalidSubtaskStructure:`子任务结构不完整,缺少id/name/description`,cannotGetCurrentTab:`无法获取当前标签页`,cannotParseTabUrl:`无法解析当前标签页 URL`,missingPrototypeId:`缺少 prototypeId 参数`,prototypeNotFound:`未找到原型: {id}`,fetchFailed:`获取失败: {error}`,missingHtmlParam:`缺少 HTML 参数`,missingTitleParam:`缺少 title 参数`,savePrototypeFailed:`保存原型失败`,executionFailed:`执行失败: {error}`,missingNameParam:`缺少 name 参数`,skillExecFailed:`Skill 执行失败`,skillExecException:`Skill 执行异常: {error}`,skillLoadFailed:`Skill 加载失败`,skillLoadException:`Skill 加载异常: {error}`,missingPathParam:`缺少 path 参数`,tabNotExistOrAccessible:`标签页 {tabId} 不存在或无法访问`,screenshotDownloaded:`截图已下载到本地({size} KB)`,screenshotSuccess:`截图成功!
138
+ `+t(`toolMemory.reviewSuggestionKeep`),n),scored:e.map(e=>{let{_source:t,...n}=e;return n}),candidates:l.map(e=>{let{_source:t,...n}=e;return n}),stats:i.stats}}if(r===`compact`){let e=0,r=0;i.facts=i.facts.filter(t=>dn(t,a)<10?(e++,!1):!0),i.summaries=i.summaries.filter(e=>dn(e,a)<10?(r++,!1):!0),i.stats.lastReviewAt=new Date().toISOString();let o=await ln(i);return o.success?{...Y(!0,t(`toolMemory.compactDone`,{facts:e,summaries:r,threshold:10,totalFacts:i.stats.totalFacts,totalSummaries:i.stats.totalSummaries}),n),removedFacts:e,removedSummaries:r,stats:i.stats}:Y(!1,t(`toolMemory.writeFailed`,{error:o.error}),n)}return Y(!1,t(`toolMemory.unsupportedAction`,{action:r}),n)}):Y(!1,t(`toolMemory.missingAction`),n)}async function vn(e,n,r){let{action:i,subAction:a}=e;return i?i===`recall`?gn(e,n,r):i===`store`?a?pn({...e,action:a},n):Y(!1,t(`toolMemory.storeMissingSubAction`),n):i===`manage`?a?_n({...e,action:a},n):Y(!1,t(`toolMemory.manageMissingSubAction`),n):Y(!1,t(`toolMemory.unsupportedMemoryAction`,{action:i}),n):Y(!1,t(`toolMemory.missingAction`),n)}e(`zh`,{toolExec:{unknown:`未知`,unknownResultFormat:`未知结果格式`,tabAccessDenied:`无法访问该标签页: {error}`,tabErrorPage:`该标签页显示错误页面,页面未能成功加载。请检查 URL 是否正确、网络是否可达`,systemPageNotAllowed:`无法在系统页面使用工具: {url}`,contentScriptNotFound:`无法找到 content script 文件`,contentScriptInjectFailed:`注入 Content Script 失败: {error}`,unknownError:`未知错误`,argParseFailed:`工具参数解析失败`,unknownTool:`未知工具: {name}`,noTabAvailable:`没有可用的标签页`,noTitle:`(无标题)`,clarifyDialogFailed:`无法显示澄清对话框: {error}`,clarifyTimeout:`用户未在规定时间内完成澄清 ({seconds}秒)`,clarifyPanelClosed:`Side Panel 已关闭,澄清操作中止`,missingUrlParam:`缺少 URL 参数`,invalidUrlFormat:`无效的 URL 格式: {url}`,readResponseFailed:`读取响应内容失败: {error}`,tabNotFound:`未找到当前标签页`,getRequiresName:`get操作需要提供name参数`,setRequiresNameValue:`set操作需要提供name和value参数`,removeRequiresName:`remove操作需要提供name参数`,unknownAction:`未知操作: {action}`,missingTaskDesc:`缺少任务描述参数`,emptySubtasks:`子任务列表不能为空`,invalidSubtaskStructure:`子任务结构不完整,缺少id/name/description`,cannotGetCurrentTab:`无法获取当前标签页`,cannotParseTabUrl:`无法解析当前标签页 URL`,missingPrototypeId:`缺少 prototypeId 参数`,prototypeNotFound:`未找到原型: {id}`,fetchFailed:`获取失败: {error}`,missingHtmlParam:`缺少 HTML 参数`,missingTitleParam:`缺少 title 参数`,savePrototypeFailed:`保存原型失败`,executionFailed:`执行失败: {error}`,missingNameParam:`缺少 name 参数`,skillExecFailed:`Skill 执行失败`,skillExecException:`Skill 执行异常: {error}`,skillLoadFailed:`Skill 加载失败`,skillLoadException:`Skill 加载异常: {error}`,missingPathParam:`缺少 path 参数`,tabNotExistOrAccessible:`标签页 {tabId} 不存在或无法访问`,screenshotDownloaded:`截图已下载到本地({size} KB)`,screenshotSuccess:`截图成功!
139
139
  图片大小约 {size} MB
140
140
  格式: {format}
141
141
  质量: {quality}
@@ -275,15 +275,15 @@ Image recognition analysis timed out (60 seconds), please check if the image rec
275
275
  - Page title: {title}
276
276
  - Page URL: {url}
277
277
 
278
- Image recognition analysis failed: {error}`,dialogAccept:`auto-accept`,dialogDismiss:`auto-dismiss`,dialogRestore:`restore native dialogs`,dialogSet:`Dialog handling set to: {mode}. Subsequent alert/confirm/prompt will be handled accordingly`}});var X=new Map,_n=new Set,vn=new Set,yn=null,bn=150,xn=3,Sn=20;function Cn(e,t=bn){return!e||typeof e!=`string`||e.length<=t?e:e.slice(0,t-3)+`...`}function wn(e,t=0){if(!e||typeof e!=`object`||t>=xn)return e;let n={};for(let[r,i]of Object.entries(e)){if(!i||typeof i!=`object`){n[r]=i;continue}let e={...i};delete e.$schema,delete e.$ref,delete e.definitions,delete e.additionalProperties,e.description&&=Cn(e.description),e.properties&&=wn(e.properties,t+1),e.items&&typeof e.items==`object`&&(e.items.properties&&(e.items.properties=wn(e.items.properties,t+1)),e.items.description&&(e.items.description=Cn(e.items.description))),n[r]=e}return n}function Tn(e){if(!e||typeof e!=`object`)return{type:`object`,properties:{}};let{$schema:n,$ref:r,definitions:i,additionalProperties:a,...o}=e;if(o.type||=`object`,o.description&&=Cn(o.description),o.properties){o.properties=wn(o.properties,0);let e=Object.keys(o.properties);if(e.length>Sn){let n=e.slice(0,Sn),r=e.slice(Sn),i={};n.forEach(e=>{i[e]=o.properties[e]}),i.additionalParams={type:`object`,description:t(`toolExec.additionalParamsDesc`,{count:r.length,names:r.join(`, `).slice(0,100)})},o.properties=i}}return o}Promise.resolve();async function En(){let e=yn,t;yn=new Promise(e=>{t=e}),await e;try{let{mcpEnabled:e}=await chrome.storage.local.get([`mcpEnabled`]);if(e!==!0)return r.debug(`[Background] MCP globaltoggleclosed,skip toolload`),0;Dn();let[t,n]=await Promise.all([Ue(),Ge()]);if(!t.success||!t.tools||t.tools.length===0)return r.debug(`[Background] no available MCP tool`),0;let i=new Set;if(n?.servers)for(let e of n.servers)e.enabled===!1&&i.add(e.id);let a=0;for(let e of t.tools){if(i.has(e.serverId)){r.debug(`[Background] skip disabled MCP server "${e.serverName}" tool: ${e.name}`);continue}let t=`mcp_${e.serverId}_${e.name}`;if(vn.has(t))continue;let n={id:t,category:`mcp`,execution:`background`,parallelizable:!0,requiresConfirmation:!1,type:`function`,function:{name:t,description:Cn(`[MCP:${e.serverName}] ${e.description||e.name}`,200),parameters:Tn(e.inputSchema)}};f.push(n),m.push({id:n.id,type:n.type,function:n.function}),d[t]=`background`,tr[t]=async(t,n)=>{let r=await We(e.serverId,e.name,t);return{success:r.success,content:r.content||r.error||``,tool_call_id:n}},vn.add(t),a++}kn();let o=t.tools.filter(e=>!i.has(e.serverId)).map(e=>({id:`mcp_${e.serverId}_${e.name}`,name:`mcp_${e.serverId}_${e.name}`,description:`[MCP:${e.serverName}] ${e.description||e.name}`,category:`mcp`,execution:`background`,parallelizable:!0,requiresConfirmation:!1,enabled:!0,serverId:e.serverId,serverName:e.serverName}));return await chrome.storage.local.set({mcpTools:o}),r.debug(`[Background] loaded ${a} MCP tool`),a}catch(e){return r.warn(`[Background] load MCP tool failed (Agent may not be supported MCP):`,e.message),0}finally{t()}}function Dn(){for(let e of vn){let t=f.findIndex(t=>t.id===e);t>=0&&f.splice(t,1),t=m.findIndex(t=>t.id===e),t>=0&&m.splice(t,1),delete d[e],delete tr[e]}vn.clear(),kn(),chrome.storage.local.remove(`mcpTools`)}async function On(){let e=yn,t;yn=new Promise(e=>{t=e}),await e;try{Dn()}finally{t()}}function kn(){for(let e of Object.keys(nr))delete nr[e];s.clear(),a.clear();for(let e of f)e.execution===`background`&&tr[e.id]&&(nr[e.id]=tr[e.id]),e.parallelizable&&s.add(e.id),e.requiresConfirmation&&a.add(e.id)}var An=`sensitiveAuditLog`,jn=100;async function Mn(e,t,n={}){try{let r=(await chrome.storage.local.get([An]))[An]||[];r.unshift({timestamp:new Date().toISOString(),category:e,action:t,details:n}),r.length>jn&&(r.length=jn),await chrome.storage.local.set({[An]:r})}catch(e){console.warn(`[Background] Audit log write failed:`,e)}}var Nn=new Map,Pn=3e4;function Fn(e){e?Nn.delete(e):Nn.clear()}async function In(){let e=await chrome.storage.local.get([`pairedAgents`,`activeAgentId`]),t=(e.pairedAgents||[]).find(t=>t.id===e.activeAgentId);if(!t)return Nn.clear(),V(`__global__`,!1),!1;let n=Date.now(),r=Nn.get(t.id);if(r&&r.connected!==null&&n-r.checkedAt<Pn)return r.connected;try{let e=new AbortController,r=setTimeout(()=>e.abort(),5e3),i=await fetch(`${t.url}/api/status`,{signal:e.signal,cache:`no-cache`});clearTimeout(r);let a=i.ok;return Nn.set(t.id,{connected:a,checkedAt:n}),V(t.id,a),console.log(`[Background] Agent connectivity check:`,a?`reachable`:`unreachable (status=`+i.status+`)`),a}catch(e){return Nn.set(t.id,{connected:!1,checkedAt:n}),V(t.id,!1),console.log(`[Background] Agent connectivity check: unreachable (`+(e.name===`AbortError`?`timeout`:e.message)+`)`),!1}}async function Ln(e=null,n=null,r=null){return new Promise(i=>{let a=`agentEnabledTools_${n||`default`}`;chrome.storage.local.get([a,`enabledTools`,`enableImageInput`,`pairedAgents`,`enableToolPreselect`],async n=>{let o=n[a]||n.enabledTools;(!o||!Array.isArray(o)||o.length===0)&&(o=m.map(e=>e.id),console.log(`[Background] not foundtool configuration,using default value (all enabled)`));let s={open_tab:`manage_tab`,switch_tab:`manage_tab`,close_tab:`manage_tab`,reload_tab:`manage_tab`,navigate_back_forward:`manage_tab`,search_bookmarks:`search_browser_data`,search_history:`search_browser_data`,agent_list_trash:`agent_trash`,agent_restore_trash:`agent_trash`,ai_agent_list:`manage_agent`,ai_agent_switch:`manage_agent`,manage_ai_agent:`manage_agent`,dispatch_sub_agent:`dispatch_task`,search_conversation_memory:`search_chats`,preview_ui_prototype:`preview_ui`,agent_read_file:`agent_file`,agent_write_file:`agent_file`,agent_list_dir:`agent_file`,agent_delete_file:`agent_file`,agent_download_file:`agent_file`,agent_search_files:`agent_search`,agent_search_content:`agent_search`,agent_skill_load:`agent_skill`,agent_workflow_run:`agent_skill`,click_element:`interact_element`,hover_element:`interact_element`,agent_exec_command:`agent_exec`,get_page_content:`page_content`,get_iframe_content:`iframe_content`,get_browser_info:`browser_info`,get_tabs:`list_tabs`,wait_for_element:`wait_element`,wait_for_navigation:`wait_navigation`,query_interactive_elements:`query_elements`,scroll_and_collect:`scroll_collect`,drag_and_drop:`drag_drop`,show_notification:`notify`,generate_qrcode:`qrcode`,clear_page_data:`clear_data`,search_chat_history:`search_chats`,ui_prototype:`preview_ui`},c=!1;o=o.map(e=>s[e]?(c=!0,s[e]):e),o=[...new Set(o)],c&&console.log(`[Background] detected old tool name,migrated to merged new tool name`);let l=e?o.filter(t=>e.includes(t)):o;e&&console.log(`[Background] tool filter: ${o.length} global → ${l.length} final`),r!=null&&Array.isArray(r)&&r.length>0&&(l.includes(`agent_skill`)||(l.push(`agent_skill`),console.log(`[Background] auto-adding skill tool: agent_skill`)));let u=n.enableImageInput===!0,d=n.enableToolPreselect===!0;console.log(`[Background] getTools - enableToolPreselect:`,d);let f=await In(),p=(n.pairedAgents||[]).length;console.log(`[Background] tool configuration: ${l.length} enable, Agent=${f}, image recognition=${u}`);let{mcpEnabled:h,skillsEnabled:g}=await chrome.storage.local.get([`mcpEnabled`,`skillsEnabled`]),_=m.filter(e=>l.includes(e.id)).filter(e=>!(e.id.startsWith(`agent_`)&&!f||e.id===`manage_agent`&&p<2||e.id===`agent_skill`&&g===!1||e.id.startsWith(`mcp_`)&&(h!==!0||!f||!vn.has(e.id)))).map(e=>{let r=JSON.parse(JSON.stringify(e));if(e.id===`capture_page`){let e=r.function.parameters.properties.action;u||(e.enum=[`download`],e.description=t(`toolExec.captureDownloadAction`),e.default=`download`,r.function.description=t(`toolExec.captureDownloadDesc`))}if(e.id===`plan_task`){let e=n.preselectMinToolCount||10,i=d&&l.length>e;if(console.log(`[Background] getTools - processing plan_task, enableToolPreselect:`,d,`toolCount:`,l.length,`threshold:`,e,`shouldAdd:`,i),i){r.function.description=`任务规划与拆解,将复杂任务分解为子任务。重要:必须为每个子任务的 requiredTools 字段指定所需工具ID列表,子任务仅继承此处指定的工具。`;let e=r.function.parameters.properties.subtasks.items.properties;e.requiredTools={type:`array`,items:{type:`string`},description:t(`toolExec.requiredToolsDesc`,{tools:l.join(`, `)})};let n=r.function.parameters.properties.subtasks.items.required;n.includes(`requiredTools`)||n.push(`requiredTools`),console.log(`[Background] getTools - added requiredTools to plan_task (required)`)}}return r});console.log(`[Background] finalavailable tools: ${_.length} `),i(_)})})}chrome.storage.onChanged.addListener(e=>{if(e.mcpEnabled){let t=e.mcpEnabled.newValue===!0;r.debug(`[Background] MCP globaltoggle changed:`,t),t?En().then(e=>{r.debug(`[Background] MCP tools re-load:`,e,``)}):On().then(()=>{r.debug(`[Background] MCP all toolsunload`)})}e.skillsEnabled&&console.log(`[Background] Skill global toggle changed:`,e.skillsEnabled.newValue!==!1)});async function Rn(e,n,r=null){let{action:i=`both`,tabId:a,format:o=`jpeg`,quality:s=60,visionMaxDim:c=1024,visionQuality:l=65}=e;try{let e,u,d=``,f=``;if(a)try{let t=await chrome.tabs.get(a);e=t.id,u=t.windowId,d=t.url||``,f=t.title||``,await chrome.tabs.update(e,{active:!0}),await new Promise(e=>setTimeout(e,300))}catch{return Z(!1,t(`toolExec.tabNotExistOrAccessible`,{tabId:a}),{tool_call_id:n})}else{let r=await chrome.tabs.query({active:!0,currentWindow:!0});if(!r.length)return Z(!1,t(`toolExec.cannotGetCurrentTab`),{tool_call_id:n});e=r[0].id,u=r[0].windowId,d=r[0].url||``,f=r[0].title||``}console.log(`[Background] taking screenshot: tabId=`,e,`url=`,d,`action=`,i,`format=`,o,`quality=`,s,`visionMaxDim=`,c,`visionQuality=`,l);let p=await new Promise((e,t)=>{chrome.tabs.captureVisibleTab(u,{format:o,quality:s},n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})}),m=(p.length/1024).toFixed(1);console.log(`[Background] screenshot complete,size:`,m,`KB`),chrome.storage.local.set({_lastVisionScreenshot:{dataUrl:p,sizeKB:m,url:d,title:f,timestamp:Date.now()}}).catch(()=>{});let h=i===`download`||i===`both`,g=i===`analyze`||i===`both`;if(h&&Qt(p,o),g){let e=await zn(p,c,l/100),i=(e.length/1024).toFixed(1);console.log(`[Background] screenshot compressed size:`,i,`KB (maxDim:`,c,`quality:`,l,`)`);let a=await Bn(e,d,f,r);return h?Z(!0,`${t(`toolExec.screenshotDownloaded`,{size:m})}。\n\n${a}`,{tool_call_id:n}):Z(!0,a,{tool_call_id:n})}let _=(p.length/1024/1024).toFixed(2);return Z(!0,t(`toolExec.screenshotSuccess`,{size:_,format:o===`png`?`png`:`jpg`,quality:s}),{tool_call_id:n})}catch(e){return Z(!1,t(`toolExec.screenshotFailed`,{error:e.message}),{tool_call_id:n})}}async function zn(e,t=1024,n=.65){try{let r=await(await fetch(e)).blob(),i=await createImageBitmap(r),{width:a,height:o}=i;(a>t||o>t)&&(a>o?(o=Math.round(t/a*o),a=t):(a=Math.round(t/o*a),o=t));let s=new OffscreenCanvas(a,o);s.getContext(`2d`).drawImage(i,0,0,a,o);let c=await s.convertToBlob({type:`image/jpeg`,quality:n});return new Promise((e,t)=>{let n=new FileReader;n.onloadend=()=>e(n.result),n.onerror=t,n.readAsDataURL(c)})}catch(t){return console.warn(`[Background] image compression failed, using original screenshot:`,t.message),e}}async function Bn(e,n,r,i=null){let a=await new Promise(e=>{chrome.storage.local.get([`imageApiBase`,`imageApiKey`,`imageModelName`,`apiBase`,`apiKey`,`modelName`,`streamEnabled`],e)}),o=a.imageApiBase||a.apiBase,s=a.imageApiKey||a.apiKey,c=a.imageModelName||a.modelName,l=a.streamEnabled!==!1;if(!o||!s)return console.log(`[Background] image recognition API not configured,returnscreenshotbasicinfo`),t(`toolExec.screenshotBasicInfo`,{title:r,url:n});console.log(`[Background] calling image recognition API to analyze screenshot,model:`,c,`endpoint:`,o,`streaming:`,l);let u=t(`toolExec.visionPrompt`,{title:r,url:n}),d=new AbortController,f=setTimeout(()=>d.abort(),6e4);try{let t={model:c,messages:[{role:`user`,content:[{type:`text`,text:u},{type:`image_url`,image_url:{url:e,detail:`auto`}}]}],max_tokens:2e3};l&&(t.stream=!0);let a=await fetch(`${o}/chat/completions`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${s}`},body:JSON.stringify(t),signal:d.signal});if(clearTimeout(f),!a.ok){let e=await a.text().catch(()=>``);return console.error(`[Background] image recognition API request failed:`,a.status,e),`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别分析失败(API 返回 ${a.status}),请检查图片识别 API 配置。`}let p;return p=l?await Vn(a,d,i):(await a.json()).choices?.[0]?.message?.content,p?(console.log(`[Background] image recognition analysis complete,result length:`,p.length),`页面截图分析结果:\n\n**页面**: ${r}\n**地址**: ${n}\n\n${p}`):(console.error(`[Background] image recognition API result is empty`),`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别返回结果为空,请重试。`)}catch(e){return clearTimeout(f),console.error(`[Background] image recognition API call exception:`,e.message),e.name===`AbortError`?`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别分析超时(60秒),请检查图片识别 API 是否可用或尝试重新截图。`:t(`toolExec.screenshotAnalysisError`,{title:r,url:n,error:e.message})}}async function Vn(e,t,n=null){let r=e.body.getReader(),i=new TextDecoder,a=``,o=``;try{for(;;){let e;e=t&&t.signal?await Promise.race([r.read(),new Promise((e,n)=>{if(t.signal.aborted){n(new DOMException(`Aborted`,`AbortError`));return}t.signal.addEventListener(`abort`,()=>n(new DOMException(`Aborted`,`AbortError`)),{once:!0})})]):await r.read();let{done:s,value:c}=e;if(s)break;a+=i.decode(c,{stream:!1});let l=a.split(`
279
- `);a=l.pop()||``;for(let e of l){let t=``;if(e.startsWith(`data:`)&&(t=e.substring(5).replace(/^\s+/,``)),!(!t||t===`[DONE]`))try{let e=JSON.parse(t),r=e.choices?.[0]?.delta?.content||e.choices?.[0]?.message?.content||e.choices?.[0]?.text||``;r&&(o+=r,n&&chrome.runtime.sendMessage({type:`VISION_ANALYSIS_CHUNK`,sessionId:n,delta:r}).catch(()=>{}))}catch(e){console.warn(`[Background] image recognition SSE parse failed,raw data:`,t.substring(0,200),`error:`,e.message)}}}}finally{r.releaseLock()}return o}function Hn(e){if(!e)return null;if(typeof e==`object`)return e;if(typeof e!=`string`)return null;let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{console.warn(`[Background] tool parameterdirectparse failed,attemptrepair...`)}let n=t;n=n.replace(/,\s*([}\]])/g,`$1`),n=n.replace(/"([^"]+)":\s*([^",\{\}\[\]]+?)(\s*[,}\]])/g,(e,t,n,r)=>{let i=n.trim();return/^(true|false|null|-?\d+(\.\d+)?)$/.test(i)?e:`"${t}": "${i.replace(/"/g,`\\"`)}"${r}`});let r;do r=n,n=n.replace(/"([^"]+)":\s*([^",\{\}\[\]]+?)(\s*[,}\]])/g,(e,t,n,r)=>{let i=n.trim();return/^(true|false|null|-?\d+(\.\d+)?)$/.test(i)?e:`"${t}": "${i.replace(/"/g,`\\"`)}"${r}`});while(n!==r);n=n.replace(/"([^"]+)":\s*"([^"]*)(")([^"]*)"/g,(e,t,n,r,i)=>`"${t}": "${n}\\"${i}"`),n=$t(n),n=en(n);try{let e=JSON.parse(n);return console.log(`[Background] tool parameterrepairparse successful:`,e),e}catch(e){return console.error(`[Background] tool parameterrepairparse also failed:`,e,`after repaircharsstring:`,n.substring(0,200)),null}}function Z(e,t,n={}){return{success:e,content:t,...n}}function Un(e){if(e===0)return`0 B`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=1024,r=Math.floor(Math.log(e)/Math.log(n));return`${(e/n**r).toFixed(r===0?0:1)} ${t[r]}`}function Wn(e,n){if(e&&typeof e==`object`&&`success`in e){if(!(`content`in e)){if(e.message)e.content=e.message;else if(!e.success&&e.error){let n=String(e.error).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`);e.content=t(`toolExec.operationFailed`,{error:n}),e.message=e.error}else{let{success:t,error:n,tool_call_id:r,...i}=e;e.content=JSON.stringify(i),e.metadata=i}console.warn(`[Background] toolreturnformatnon-standard (missing content field),auto-filled`)}return e.tool_call_id||=n,e}return typeof e==`string`?(console.warn(`[Background] toolreturnpurecharsstring but non-standardobject,use instead with makeResult()`),{success:!0,content:e,tool_call_id:n}):{success:!1,error:t(`toolExec.unknownResultFormat`),content:``,tool_call_id:n}}async function Gn(e,t,n){try{let r=`toolUsageStats`,i=(await chrome.storage.local.get([r]))[r]||{},a=i[e]||{callCount:0,successCount:0,totalDuration:0,lastUsed:0};a.callCount++,t.success&&a.successCount++,a.totalDuration+=n,a.lastUsed=Date.now(),i[e]=a,chrome.storage.local.set({[r]:i})}catch(e){console.warn(`[Background] recordtoolstats failed:`,e)}}function Kn(){return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},t=>{e(t&&t.length>0?t[0].id:null)})})}async function qn(e,n,r){return new Promise(i=>{chrome.tabs.sendMessage(e,n,a=>{if(chrome.runtime.lastError){let a=chrome.runtime.lastError.message;console.warn(`[Background] sendmessage to content script failed:`,a),chrome.tabs.get(e,o=>{if(chrome.runtime.lastError||!o){i({success:!1,error:t(`toolExec.tabAccessDenied`,{error:a}),tool_call_id:r});return}let s=o.url||``;if(s.startsWith(`chrome://`)||s.startsWith(`chrome-extension://`)||s.startsWith(`about:`)||s.startsWith(`chrome-error://`)){s.startsWith(`chrome-error://`)?i({success:!1,error:t(`toolExec.tabErrorPage`),tool_call_id:r}):i({success:!1,error:t(`toolExec.systemPageNotAllowed`,{url:s}),tool_call_id:r});return}console.log(`[Background] attempt autoinject content script to Tab:`,e);let c=chrome.runtime.getManifest().content_scripts?.[0]?.js||[],l=c.findIndex(e=>/content/i.test(e)&&e.endsWith(`.js`)),u=l===-1?c:[c[l]];if(l===-1&&u.length===0){i({success:!1,error:t(`toolExec.contentScriptNotFound`),tool_call_id:r});return}chrome.scripting.executeScript({target:{tabId:e},files:u}).then(()=>{console.log(`[Background] Content script inject successful, startretrysendmessage`),d(e,n,0)}).catch(e=>{console.warn(`[Background] inject content script failed:`,e.message),e.message&&e.message.includes(`error page`)?i({success:!1,error:t(`toolExec.tabErrorPage`),tool_call_id:r}):i({success:!1,error:t(`toolExec.contentScriptInjectFailed`,{error:e.message}),tool_call_id:r})});function d(e,t,n){let a=[300,600,1200],o=a.length;setTimeout(()=>{chrome.tabs.sendMessage(e,t,s=>{chrome.runtime.lastError?n<o-1?(console.warn(`[Background] retry ${n+2}/${o+1} failed, ${a[n+1]}ms after retry:`,chrome.runtime.lastError.message),d(e,t,n+1)):(console.warn(`[Background] all has retryaverage failed:`,chrome.runtime.lastError.message),i({success:!1,error:chrome.runtime.lastError.message,tool_call_id:r})):(console.log(`[Background] retry successful (`+(n+2)+` times)`),i({...s,tool_call_id:r}))})},a[n])}})}else i({...a,tool_call_id:r})})})}async function Jn(e,n,r){let{action:i}=e;switch(i){case`open`:return gr(e,n,r);case`switch`:return _r(e,n,r);case`close`:return vr(e,n);case`reload`:return wr(e,n);case`navigate`:return Cr(e,n);default:return Z(!1,t(`toolExec.unknownManageTabAction`,{action:i}),{tool_call_id:n})}}async function Yn(e,n){let{action:r}=e;switch(r){case`bookmark`:return ar(e,n);case`history`:return or(e,n);default:return Z(!1,t(`toolExec.unknownSearchBrowserDataAction`,{action:r}),{tool_call_id:n})}}async function Xn(e,n){let{action:r}=e;switch(r){case`list`:return Pr(e,n);case`restore`:return Fr(e,n);default:return Z(!1,t(`toolExec.unknownAgentTrashAction`,{action:r}),{tool_call_id:n})}}async function Zn(e,n){let{action:r}=e;switch(r){case`list`:return Xr(e,n);case`switch`:return Zr(e,n);default:return Z(!1,t(`toolExec.unknownManageAgentAction`,{action:r}),{tool_call_id:n})}}async function Qn(e,n){let{action:r}=e;switch(r){case`read`:return kr(e,n);case`write`:return jr(e,n);case`list`:return Mr(e,n);case`delete`:return Nr(e,n);case`download`:return Ir(e,n);default:return Z(!1,t(`toolExec.unknownAgentFileAction`,{action:r}),{tool_call_id:n})}}async function $n(e,n){let{searchType:r}=e;switch(r){case`file`:return Br(e,n);case`content`:return Vr(e,n);default:return Z(!1,t(`toolExec.unknownAgentSearchType`,{type:r}),{tool_call_id:n})}}async function er(e,n,r){let{scope:i=`last_n_rounds`,rounds:a=3,sessionId:o}=e,s=o||r||await ae();if(!s)return Z(!1,t(`toolExec.cannotGetSessionId`),{tool_call_id:n});let c=await ee(s);if(!c)return Z(!1,t(`toolExec.sessionNotFound`,{id:s}),{tool_call_id:n});let l=(c.messageHistory||[]).map((e,t)=>({msg:e,idx:t})).filter(({msg:e})=>e.role===`assistant`&&Array.isArray(e.executionLog)&&e.executionLog.length>0);if(l.length===0)return Z(!0,t(`toolExec.noExecutionLog`),{tool_call_id:n});let u;u=i===`full_session`?l:l.slice(-Math.min(a,l.length));let d=[],f=[],p=[],m=[];for(let{msg:e,idx:n}of u){let r=n+1,i=e.executionLog||[];for(let e of i){let n=e.nodeType;if(m.push({round:r,nodeType:n,nodeName:e.nodeName||e.action?.name||t(`toolExec.unknown`),status:e.status||`unknown`,timestamp:e.timestamp||null,toolName:e.action?.name||null}),n===`tool_exec`){let n=e.action?.name||e.nodeName||t(`toolExec.unknownTool`,{name:`unknown`}),i=e.action?.arguments||e.action?.args||{},a=e.status;a===`success`?d.push({round:r,tool:n,args:i,result:e.observation||e.result||`成功`,description:e.nodeName||``}):(a===`failed`||a===`cancelled`)&&f.push({round:r,tool:n,args:i,status:a,error:e.error||e.observation||e.result||t(`toolExec.unknownError`),description:e.nodeName||``})}n===`reflection`&&p.push({round:r,tool:e.action?.name||e.nodeName||t(`toolExec.unknown`),effective:e.effective===void 0?null:e.effective,reasoning:e.reasoning||e.analysis||``,suggestion:e.suggestion||e.advice||``,reflectionType:e.reflectionType||``})}}let h=u.length,g=m.length,_=m.filter(e=>e.status===`success`).length,v=m.filter(e=>e.status===`failed`||e.status===`cancelled`).length,y={sessionId:s,scope:i,roundsAnalyzed:h,stats:{totalSteps:g,successCount:_,failCount:v,successRate:g>0?(_/g*100).toFixed(1)+`%`:`0%`},successPaths:d,failures:f,reflections:p,timeline:m},b=[];if(b.push(`## 执行日志提炼报告`),b.push(``),b.push(`**会话**: ${c.title||s.slice(0,8)}`),b.push(`**分析范围**: ${i}(${h} 轮)`),b.push(`**统计**: 共 ${g} 步,成功 ${_},失败 ${v},成功率 ${y.stats.successRate}`),b.push(``),d.length>0){b.push(`### ✅ 成功路径`),b.push(``);for(let e of d)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\` → ${typeof e.result==`string`?e.result.substring(0,100):`执行成功`}`);b.push(``)}if(f.length>0){b.push(`### ❌ 失败教训`),b.push(``);for(let e of f)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\` ${e.status}: ${typeof e.error==`string`?e.error.substring(0,150):`未知错误`}`);b.push(``)}if(p.length>0){b.push(`### 🎯 反思建议`),b.push(``);for(let e of p)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\``),e.reasoning&&b.push(` - 推理: ${e.reasoning.substring(0,200)}`),e.suggestion&&b.push(` - 建议: ${e.suggestion.substring(0,200)}`);b.push(``)}return Z(!0,b.join(`
280
- `),{tool_call_id:n,extractedData:y})}var tr={capture_page:Rn,clarify_question:cr,notify:lr,fetch_url:fr,list_tabs:yr,browser_info:mr,download_file:hr,manage_cookies:br,plan_task:xr,clear_data:Sr,search_chats:sr,preview_ui:Tr,agent_file:Qn,agent_exec:Rr,agent_search:$n,agent_skill:Or,wait_navigation:Ar,handle_dialog:pr,dispatch_task:Zt,agent_memory:async(e,t,n)=>gn(e,t,n),page_content:Wr,extract_data:Gr,clipboard:Kr,manage_tab:Jn,search_browser_data:Yn,agent_trash:Xn,manage_agent:Zn,exec_log:er},nr={};for(let e of f)e.execution===`background`&&tr[e.id]&&(nr[e.id]=tr[e.id]);var rr={};for(let e of f)if(e.execution===`content_script`){let t=e.function.parameters?.properties;if(t){let n=Object.keys(t);rr[e.id]=e=>{let t={};for(let r of n)t[r]=e[r];return t}}else rr[e.id]=()=>({})}rr.search_in_page=e=>({query:e.query||e.pattern,mode:e.mode,caseSensitive:e.caseSensitive,contextLength:e.contextLength,maxResults:e.maxResults,highlight:e.highlight});async function ir(e,n,r=null){let i=Date.now(),{name:a,arguments:o,id:s,function:c,index:l}=e,u=a||c&&c.name,f=s,p={};if(console.log(`[Background] tool callraw data:`,JSON.stringify(e)),c&&c.arguments){console.log(`[Background] toolCall.function.arguments type:`,typeof c.arguments);try{p=Hn(c.arguments)||{}}catch(e){return console.error(`[Background] parsetool parameter failed:`,e,`originalvalue:`,JSON.stringify(c.arguments).substring(0,300)),{success:!1,error:t(`toolExec.argParseFailed`),tool_call_id:f}}let e=typeof c.arguments==`string`?c.arguments.trim():JSON.stringify(c.arguments);Object.keys(p).length===0&&e.length>0&&e!==`{}`&&console.error(`[Background] parameterparse after empty object!original arguments:`,JSON.stringify(c.arguments).substring(0,300))}else if(typeof o==`object`)p=o||{};else if(typeof o==`string`){console.log(`[Background] using backup argsStr parse:`,o.substring(0,300));try{p=Hn(o)||{}}catch(e){return console.error(`[Background] parsetool parameter failed:`,e,`originalvalue:`,o),{success:!1,error:t(`toolExec.argParseFailed`),tool_call_id:f}}}console.log(`[Background] exec tool:`,u,p,`id:`,f);let m=d[u],h;if(m===`background`){let e=nr[u];e?(console.log(`[Background] ${u} directly execute, not passed content script`),h=await e(p,f,r,n)):h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f}}else if(m===`content_script`){let e=rr[u];if(e){let n=u.toUpperCase(),i=e(p),a=r?Se(r):null,o=p.tabId||a||await Kn();h=o?await qn(o,{type:n,...i},f):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:f}}else h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f}}else h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f};h=Wn(h,f);let g=Date.now()-i;return Gn(u,h,g),h}function ar(e,n){let r=e.query||``,a=parseInt(e.maxResults,10)||10;return console.log(`[Background] exec bookmarksearch:`,`query=`,JSON.stringify(r),`maxResults=`,a),new Promise(e=>{if(!chrome.bookmarks){console.error(`[Background] chrome.bookmarks API non- with `),e(Z(!1,t(`toolExec.bookmarkApiUnavailable`)));return}if(!r||r.trim()===``){console.log(`[Background] emptyquery,getbookmark rootnode...`),chrome.bookmarks.getTree(n=>{if(console.log(`[Background] chrome.bookmarks.getTree callback, tree node count:`,n?n.length:`null`),chrome.runtime.lastError){console.error(`[Background] chrome.bookmarks.getTree error:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.bookmarkFetchFailed`,{error:chrome.runtime.lastError.message})));return}let r=[];function o(e){e&&e.forEach(e=>{e.url&&r.push(e),e.children&&e.children.length>0&&o(e.children)})}if(o(n),console.log(`[Background] receiset to total bookmarks:`,r.length),r.length===0){e(Z(!0,t(`toolExec.noBookmarks`)));return}let s=r.slice(0,a).map(e=>({title:e.title||t(`toolExec.noTitle`),url:e.url||``,dateAdded:e.dateAdded?new Date(e.dateAdded).toLocaleString(i()===`en`?`en-US`:`zh-CN`):null})),c=`${t(`toolExec.bookmarksCount`,{total:r.length,shown:s.length})}\n`+s.map((e,t)=>`${t+1}. ${e.title}\n URL: ${e.url}`).join(`
278
+ Image recognition analysis failed: {error}`,dialogAccept:`auto-accept`,dialogDismiss:`auto-dismiss`,dialogRestore:`restore native dialogs`,dialogSet:`Dialog handling set to: {mode}. Subsequent alert/confirm/prompt will be handled accordingly`}});var X=new Map,yn=new Set,bn=new Set,xn=null,Sn=150,Cn=3,wn=20;function Tn(e,t=Sn){return!e||typeof e!=`string`||e.length<=t?e:e.slice(0,t-3)+`...`}function En(e,t=0){if(!e||typeof e!=`object`||t>=Cn)return e;let n={};for(let[r,i]of Object.entries(e)){if(!i||typeof i!=`object`){n[r]=i;continue}let e={...i};delete e.$schema,delete e.$ref,delete e.definitions,delete e.additionalProperties,e.description&&=Tn(e.description),e.properties&&=En(e.properties,t+1),e.items&&typeof e.items==`object`&&(e.items.properties&&(e.items.properties=En(e.items.properties,t+1)),e.items.description&&(e.items.description=Tn(e.items.description))),n[r]=e}return n}function Dn(e){if(!e||typeof e!=`object`)return{type:`object`,properties:{}};let{$schema:n,$ref:r,definitions:i,additionalProperties:a,...o}=e;if(o.type||=`object`,o.description&&=Tn(o.description),o.properties){o.properties=En(o.properties,0);let e=Object.keys(o.properties);if(e.length>wn){let n=e.slice(0,wn),r=e.slice(wn),i={};n.forEach(e=>{i[e]=o.properties[e]}),i.additionalParams={type:`object`,description:t(`toolExec.additionalParamsDesc`,{count:r.length,names:r.join(`, `).slice(0,100)})},o.properties=i}}return o}Promise.resolve();async function On(){let e=xn,t;xn=new Promise(e=>{t=e}),await e;try{let{mcpEnabled:e}=await chrome.storage.local.get([`mcpEnabled`]);if(e!==!0)return r.debug(`[Background] MCP globaltoggleclosed,skip toolload`),0;kn();let[t,n]=await Promise.all([Ue(),Ge()]);if(!t.success||!t.tools||t.tools.length===0)return r.debug(`[Background] no available MCP tool`),0;let i=new Set;if(n?.servers)for(let e of n.servers)e.enabled===!1&&i.add(e.id);let a=0;for(let e of t.tools){if(i.has(e.serverId)){r.debug(`[Background] skip disabled MCP server "${e.serverName}" tool: ${e.name}`);continue}let t=`mcp_${e.serverId}_${e.name}`;if(bn.has(t))continue;let n={id:t,category:`mcp`,execution:`background`,parallelizable:!0,requiresConfirmation:!1,type:`function`,function:{name:t,description:Tn(`[MCP:${e.serverName}] ${e.description||e.name}`,200),parameters:Dn(e.inputSchema)}};f.push(n),m.push({id:n.id,type:n.type,function:n.function}),d[t]=`background`,rr[t]=async(t,n)=>{let r=await We(e.serverId,e.name,t);return{success:r.success,content:r.content||r.error||``,tool_call_id:n}},bn.add(t),a++}jn();let o=t.tools.filter(e=>!i.has(e.serverId)).map(e=>({id:`mcp_${e.serverId}_${e.name}`,name:`mcp_${e.serverId}_${e.name}`,description:`[MCP:${e.serverName}] ${e.description||e.name}`,category:`mcp`,execution:`background`,parallelizable:!0,requiresConfirmation:!1,enabled:!0,serverId:e.serverId,serverName:e.serverName}));return await chrome.storage.local.set({mcpTools:o}),r.debug(`[Background] loaded ${a} MCP tool`),a}catch(e){return r.warn(`[Background] load MCP tool failed (Agent may not be supported MCP):`,e.message),0}finally{t()}}function kn(){for(let e of bn){let t=f.findIndex(t=>t.id===e);t>=0&&f.splice(t,1),t=m.findIndex(t=>t.id===e),t>=0&&m.splice(t,1),delete d[e],delete rr[e]}bn.clear(),jn(),chrome.storage.local.remove(`mcpTools`)}async function An(){let e=xn,t;xn=new Promise(e=>{t=e}),await e;try{kn()}finally{t()}}function jn(){for(let e of Object.keys(ir))delete ir[e];s.clear(),a.clear();for(let e of f)e.execution===`background`&&rr[e.id]&&(ir[e.id]=rr[e.id]),e.parallelizable&&s.add(e.id),e.requiresConfirmation&&a.add(e.id)}var Mn=`sensitiveAuditLog`,Nn=100;async function Pn(e,t,n={}){try{let r=(await chrome.storage.local.get([Mn]))[Mn]||[];r.unshift({timestamp:new Date().toISOString(),category:e,action:t,details:n}),r.length>Nn&&(r.length=Nn),await chrome.storage.local.set({[Mn]:r})}catch(e){console.warn(`[Background] Audit log write failed:`,e)}}var Fn=new Map,In=3e4;function Ln(e){e?Fn.delete(e):Fn.clear()}async function Rn(){let e=await chrome.storage.local.get([`pairedAgents`,`activeAgentId`]),t=(e.pairedAgents||[]).find(t=>t.id===e.activeAgentId);if(!t)return Fn.clear(),V(`__global__`,!1),!1;let n=Date.now(),r=Fn.get(t.id);if(r&&r.connected!==null&&n-r.checkedAt<In)return r.connected;try{let e=new AbortController,r=setTimeout(()=>e.abort(),5e3),i=await fetch(`${t.url}/api/status`,{signal:e.signal,cache:`no-cache`});clearTimeout(r);let a=i.ok;return Fn.set(t.id,{connected:a,checkedAt:n}),V(t.id,a),console.log(`[Background] Agent connectivity check:`,a?`reachable`:`unreachable (status=`+i.status+`)`),a}catch(e){return Fn.set(t.id,{connected:!1,checkedAt:n}),V(t.id,!1),console.log(`[Background] Agent connectivity check: unreachable (`+(e.name===`AbortError`?`timeout`:e.message)+`)`),!1}}async function zn(e=null,n=null,r=null){return new Promise(i=>{let a=`agentEnabledTools_${n||`default`}`;chrome.storage.local.get([a,`enabledTools`,`enableImageInput`,`pairedAgents`,`enableToolPreselect`],async n=>{let o=n[a]||n.enabledTools;(!o||!Array.isArray(o)||o.length===0)&&(o=m.map(e=>e.id),console.log(`[Background] not foundtool configuration,using default value (all enabled)`));let s={open_tab:`manage_tab`,switch_tab:`manage_tab`,close_tab:`manage_tab`,reload_tab:`manage_tab`,navigate_back_forward:`manage_tab`,search_bookmarks:`search_browser_data`,search_history:`search_browser_data`,agent_list_trash:`agent_trash`,agent_restore_trash:`agent_trash`,ai_agent_list:`manage_agent`,ai_agent_switch:`manage_agent`,manage_ai_agent:`manage_agent`,dispatch_sub_agent:`dispatch_task`,search_conversation_memory:`search_chats`,preview_ui_prototype:`preview_ui`,agent_read_file:`agent_file`,agent_write_file:`agent_file`,agent_list_dir:`agent_file`,agent_delete_file:`agent_file`,agent_download_file:`agent_file`,agent_search_files:`agent_search`,agent_search_content:`agent_search`,agent_skill_load:`agent_skill`,agent_workflow_run:`agent_skill`,click_element:`interact_element`,hover_element:`interact_element`,agent_exec_command:`agent_exec`,get_page_content:`page_content`,get_iframe_content:`iframe_content`,get_browser_info:`browser_info`,get_tabs:`list_tabs`,wait_for_element:`wait_element`,wait_for_navigation:`wait_navigation`,query_interactive_elements:`query_elements`,scroll_and_collect:`scroll_collect`,drag_and_drop:`drag_drop`,show_notification:`notify`,generate_qrcode:`qrcode`,clear_page_data:`clear_data`,search_chat_history:`search_chats`,ui_prototype:`preview_ui`},c=!1;o=o.map(e=>s[e]?(c=!0,s[e]):e),o=[...new Set(o)],c&&console.log(`[Background] detected old tool name,migrated to merged new tool name`);let l=e?o.filter(t=>e.includes(t)):o;e&&console.log(`[Background] tool filter: ${o.length} global → ${l.length} final`),r!=null&&Array.isArray(r)&&r.length>0&&(l.includes(`agent_skill`)||(l.push(`agent_skill`),console.log(`[Background] auto-adding skill tool: agent_skill`)));let u=n.enableImageInput===!0,d=n.enableToolPreselect===!0;console.log(`[Background] getTools - enableToolPreselect:`,d);let f=await Rn(),p=(n.pairedAgents||[]).length;console.log(`[Background] tool configuration: ${l.length} enable, Agent=${f}, image recognition=${u}`);let{mcpEnabled:h,skillsEnabled:g}=await chrome.storage.local.get([`mcpEnabled`,`skillsEnabled`]),_=m.filter(e=>l.includes(e.id)).filter(e=>!(e.id.startsWith(`agent_`)&&!f||e.id===`manage_agent`&&p<2||e.id===`agent_skill`&&g===!1||e.id.startsWith(`mcp_`)&&(h!==!0||!f||!bn.has(e.id)))).map(e=>{let r=JSON.parse(JSON.stringify(e));if(e.id===`capture_page`){let e=r.function.parameters.properties.action;u||(e.enum=[`download`],e.description=t(`toolExec.captureDownloadAction`),e.default=`download`,r.function.description=t(`toolExec.captureDownloadDesc`))}if(e.id===`plan_task`){let e=n.preselectMinToolCount||10,i=d&&l.length>e;if(console.log(`[Background] getTools - processing plan_task, enableToolPreselect:`,d,`toolCount:`,l.length,`threshold:`,e,`shouldAdd:`,i),i){r.function.description=`任务规划与拆解,将复杂任务分解为子任务。重要:必须为每个子任务的 requiredTools 字段指定所需工具ID列表,子任务仅继承此处指定的工具。`;let e=r.function.parameters.properties.subtasks.items.properties;e.requiredTools={type:`array`,items:{type:`string`},description:t(`toolExec.requiredToolsDesc`,{tools:l.join(`, `)})};let n=r.function.parameters.properties.subtasks.items.required;n.includes(`requiredTools`)||n.push(`requiredTools`),console.log(`[Background] getTools - added requiredTools to plan_task (required)`)}}return r});console.log(`[Background] finalavailable tools: ${_.length} `),i(_)})})}chrome.storage.onChanged.addListener(e=>{if(e.mcpEnabled){let t=e.mcpEnabled.newValue===!0;r.debug(`[Background] MCP globaltoggle changed:`,t),t?On().then(e=>{r.debug(`[Background] MCP tools re-load:`,e,``)}):An().then(()=>{r.debug(`[Background] MCP all toolsunload`)})}e.skillsEnabled&&console.log(`[Background] Skill global toggle changed:`,e.skillsEnabled.newValue!==!1)});async function Bn(e,n,r=null){let{action:i=`both`,tabId:a,format:o=`jpeg`,quality:s=60,visionMaxDim:c=1024,visionQuality:l=65}=e;try{let e,u,d=``,f=``;if(a)try{let t=await chrome.tabs.get(a);e=t.id,u=t.windowId,d=t.url||``,f=t.title||``,await chrome.tabs.update(e,{active:!0}),await new Promise(e=>setTimeout(e,300))}catch{return Z(!1,t(`toolExec.tabNotExistOrAccessible`,{tabId:a}),{tool_call_id:n})}else{let r=await chrome.tabs.query({active:!0,currentWindow:!0});if(!r.length)return Z(!1,t(`toolExec.cannotGetCurrentTab`),{tool_call_id:n});e=r[0].id,u=r[0].windowId,d=r[0].url||``,f=r[0].title||``}console.log(`[Background] taking screenshot: tabId=`,e,`url=`,d,`action=`,i,`format=`,o,`quality=`,s,`visionMaxDim=`,c,`visionQuality=`,l);let p=await new Promise((e,t)=>{chrome.tabs.captureVisibleTab(u,{format:o,quality:s},n=>{chrome.runtime.lastError?t(Error(chrome.runtime.lastError.message)):e(n)})}),m=(p.length/1024).toFixed(1);console.log(`[Background] screenshot complete,size:`,m,`KB`),chrome.storage.local.set({_lastVisionScreenshot:{dataUrl:p,sizeKB:m,url:d,title:f,timestamp:Date.now()}}).catch(()=>{});let h=i===`download`||i===`both`,g=i===`analyze`||i===`both`;if(h&&en(p,o),g){let e=await Vn(p,c,l/100),i=(e.length/1024).toFixed(1);console.log(`[Background] screenshot compressed size:`,i,`KB (maxDim:`,c,`quality:`,l,`)`);let a=await Hn(e,d,f,r);return h?Z(!0,`${t(`toolExec.screenshotDownloaded`,{size:m})}。\n\n${a}`,{tool_call_id:n}):Z(!0,a,{tool_call_id:n})}let _=(p.length/1024/1024).toFixed(2);return Z(!0,t(`toolExec.screenshotSuccess`,{size:_,format:o===`png`?`png`:`jpg`,quality:s}),{tool_call_id:n})}catch(e){return Z(!1,t(`toolExec.screenshotFailed`,{error:e.message}),{tool_call_id:n})}}async function Vn(e,t=1024,n=.65){try{let r=await(await fetch(e)).blob(),i=await createImageBitmap(r),{width:a,height:o}=i;(a>t||o>t)&&(a>o?(o=Math.round(t/a*o),a=t):(a=Math.round(t/o*a),o=t));let s=new OffscreenCanvas(a,o);s.getContext(`2d`).drawImage(i,0,0,a,o);let c=await s.convertToBlob({type:`image/jpeg`,quality:n});return new Promise((e,t)=>{let n=new FileReader;n.onloadend=()=>e(n.result),n.onerror=t,n.readAsDataURL(c)})}catch(t){return console.warn(`[Background] image compression failed, using original screenshot:`,t.message),e}}async function Hn(e,n,r,i=null){let a=await new Promise(e=>{chrome.storage.local.get([`imageApiBase`,`imageApiKey`,`imageModelName`,`apiBase`,`apiKey`,`modelName`,`streamEnabled`],e)}),o=a.imageApiBase||a.apiBase,s=a.imageApiKey||a.apiKey,c=a.imageModelName||a.modelName,l=a.streamEnabled!==!1;if(!o||!s)return console.log(`[Background] image recognition API not configured,returnscreenshotbasicinfo`),t(`toolExec.screenshotBasicInfo`,{title:r,url:n});console.log(`[Background] calling image recognition API to analyze screenshot,model:`,c,`endpoint:`,o,`streaming:`,l);let u=t(`toolExec.visionPrompt`,{title:r,url:n}),d=new AbortController,f=setTimeout(()=>d.abort(),6e4);try{let t={model:c,messages:[{role:`user`,content:[{type:`text`,text:u},{type:`image_url`,image_url:{url:e,detail:`auto`}}]}],max_tokens:2e3};l&&(t.stream=!0);let a=await fetch(`${o}/chat/completions`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${s}`},body:JSON.stringify(t),signal:d.signal});if(clearTimeout(f),!a.ok){let e=await a.text().catch(()=>``);return console.error(`[Background] image recognition API request failed:`,a.status,e),`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别分析失败(API 返回 ${a.status}),请检查图片识别 API 配置。`}let p;return p=l?await Un(a,d,i):(await a.json()).choices?.[0]?.message?.content,p?(console.log(`[Background] image recognition analysis complete,result length:`,p.length),`页面截图分析结果:\n\n**页面**: ${r}\n**地址**: ${n}\n\n${p}`):(console.error(`[Background] image recognition API result is empty`),`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别返回结果为空,请重试。`)}catch(e){return clearTimeout(f),console.error(`[Background] image recognition API call exception:`,e.message),e.name===`AbortError`?`页面截图已获取。\n\n- 页面标题: ${r}\n- 页面地址: ${n}\n\n图片识别分析超时(60秒),请检查图片识别 API 是否可用或尝试重新截图。`:t(`toolExec.screenshotAnalysisError`,{title:r,url:n,error:e.message})}}async function Un(e,t,n=null){let r=e.body.getReader(),i=new TextDecoder,a=``,o=``;try{for(;;){let e;e=t&&t.signal?await Promise.race([r.read(),new Promise((e,n)=>{if(t.signal.aborted){n(new DOMException(`Aborted`,`AbortError`));return}t.signal.addEventListener(`abort`,()=>n(new DOMException(`Aborted`,`AbortError`)),{once:!0})})]):await r.read();let{done:s,value:c}=e;if(s)break;a+=i.decode(c,{stream:!1});let l=a.split(`
279
+ `);a=l.pop()||``;for(let e of l){let t=``;if(e.startsWith(`data:`)&&(t=e.substring(5).replace(/^\s+/,``)),!(!t||t===`[DONE]`))try{let e=JSON.parse(t),r=e.choices?.[0]?.delta?.content||e.choices?.[0]?.message?.content||e.choices?.[0]?.text||``;r&&(o+=r,n&&chrome.runtime.sendMessage({type:`VISION_ANALYSIS_CHUNK`,sessionId:n,delta:r}).catch(()=>{}))}catch(e){console.warn(`[Background] image recognition SSE parse failed,raw data:`,t.substring(0,200),`error:`,e.message)}}}}finally{r.releaseLock()}return o}function Wn(e){if(!e)return null;if(typeof e==`object`)return e;if(typeof e!=`string`)return null;let t=e.trim();if(!t)return null;try{return JSON.parse(t)}catch{console.warn(`[Background] tool parameterdirectparse failed,attemptrepair...`)}let n=t;n=n.replace(/,\s*([}\]])/g,`$1`),n=n.replace(/"([^"]+)":\s*([^",\{\}\[\]]+?)(\s*[,}\]])/g,(e,t,n,r)=>{let i=n.trim();return/^(true|false|null|-?\d+(\.\d+)?)$/.test(i)?e:`"${t}": "${i.replace(/"/g,`\\"`)}"${r}`});let r;do r=n,n=n.replace(/"([^"]+)":\s*([^",\{\}\[\]]+?)(\s*[,}\]])/g,(e,t,n,r)=>{let i=n.trim();return/^(true|false|null|-?\d+(\.\d+)?)$/.test(i)?e:`"${t}": "${i.replace(/"/g,`\\"`)}"${r}`});while(n!==r);n=n.replace(/"([^"]+)":\s*"([^"]*)(")([^"]*)"/g,(e,t,n,r,i)=>`"${t}": "${n}\\"${i}"`),n=tn(n),n=nn(n);try{let e=JSON.parse(n);return console.log(`[Background] tool parameterrepairparse successful:`,e),e}catch(e){return console.error(`[Background] tool parameterrepairparse also failed:`,e,`after repaircharsstring:`,n.substring(0,200)),null}}function Z(e,t,n={}){return{success:e,content:t,...n}}function Gn(e){if(e===0)return`0 B`;let t=[`B`,`KB`,`MB`,`GB`,`TB`],n=1024,r=Math.floor(Math.log(e)/Math.log(n));return`${(e/n**r).toFixed(r===0?0:1)} ${t[r]}`}function Kn(e,n){if(e&&typeof e==`object`&&`success`in e){if(!(`content`in e)){if(e.message)e.content=e.message;else if(!e.success&&e.error){let n=String(e.error).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`);e.content=t(`toolExec.operationFailed`,{error:n}),e.message=e.error}else{let{success:t,error:n,tool_call_id:r,...i}=e;e.content=JSON.stringify(i),e.metadata=i}console.warn(`[Background] toolreturnformatnon-standard (missing content field),auto-filled`)}return e.tool_call_id||=n,e}return typeof e==`string`?(console.warn(`[Background] toolreturnpurecharsstring but non-standardobject,use instead with makeResult()`),{success:!0,content:e,tool_call_id:n}):{success:!1,error:t(`toolExec.unknownResultFormat`),content:``,tool_call_id:n}}async function qn(e,t,n){try{let r=`toolUsageStats`,i=(await chrome.storage.local.get([r]))[r]||{},a=i[e]||{callCount:0,successCount:0,totalDuration:0,lastUsed:0};a.callCount++,t.success&&a.successCount++,a.totalDuration+=n,a.lastUsed=Date.now(),i[e]=a,chrome.storage.local.set({[r]:i})}catch(e){console.warn(`[Background] recordtoolstats failed:`,e)}}function Jn(){return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},t=>{e(t&&t.length>0?t[0].id:null)})})}async function Yn(e,n,r){return new Promise(i=>{chrome.tabs.sendMessage(e,n,a=>{if(chrome.runtime.lastError){let a=chrome.runtime.lastError.message;console.warn(`[Background] sendmessage to content script failed:`,a),chrome.tabs.get(e,o=>{if(chrome.runtime.lastError||!o){i({success:!1,error:t(`toolExec.tabAccessDenied`,{error:a}),tool_call_id:r});return}let s=o.url||``;if(s.startsWith(`chrome://`)||s.startsWith(`chrome-extension://`)||s.startsWith(`about:`)||s.startsWith(`chrome-error://`)){s.startsWith(`chrome-error://`)?i({success:!1,error:t(`toolExec.tabErrorPage`),tool_call_id:r}):i({success:!1,error:t(`toolExec.systemPageNotAllowed`,{url:s}),tool_call_id:r});return}console.log(`[Background] attempt autoinject content script to Tab:`,e);let c=chrome.runtime.getManifest().content_scripts?.[0]?.js||[],l=c.findIndex(e=>/content/i.test(e)&&e.endsWith(`.js`)),u=l===-1?c:[c[l]];if(l===-1&&u.length===0){i({success:!1,error:t(`toolExec.contentScriptNotFound`),tool_call_id:r});return}chrome.scripting.executeScript({target:{tabId:e},files:u}).then(()=>{console.log(`[Background] Content script inject successful, startretrysendmessage`),d(e,n,0)}).catch(e=>{console.warn(`[Background] inject content script failed:`,e.message),e.message&&e.message.includes(`error page`)?i({success:!1,error:t(`toolExec.tabErrorPage`),tool_call_id:r}):i({success:!1,error:t(`toolExec.contentScriptInjectFailed`,{error:e.message}),tool_call_id:r})});function d(e,t,n){let a=[300,600,1200],o=a.length;setTimeout(()=>{chrome.tabs.sendMessage(e,t,s=>{chrome.runtime.lastError?n<o-1?(console.warn(`[Background] retry ${n+2}/${o+1} failed, ${a[n+1]}ms after retry:`,chrome.runtime.lastError.message),d(e,t,n+1)):(console.warn(`[Background] all has retryaverage failed:`,chrome.runtime.lastError.message),i({success:!1,error:chrome.runtime.lastError.message,tool_call_id:r})):(console.log(`[Background] retry successful (`+(n+2)+` times)`),i({...s,tool_call_id:r}))})},a[n])}})}else i({...a,tool_call_id:r})})})}async function Xn(e,n,r){let{action:i}=e;switch(i){case`open`:return vr(e,n,r);case`switch`:return yr(e,n,r);case`close`:return br(e,n);case`reload`:return Er(e,n);case`navigate`:return Tr(e,n);default:return Z(!1,t(`toolExec.unknownManageTabAction`,{action:i}),{tool_call_id:n})}}async function Zn(e,n){let{action:r}=e;switch(r){case`bookmark`:return sr(e,n);case`history`:return cr(e,n);default:return Z(!1,t(`toolExec.unknownSearchBrowserDataAction`,{action:r}),{tool_call_id:n})}}async function Qn(e,n){let{action:r}=e;switch(r){case`list`:return Ir(e,n);case`restore`:return Lr(e,n);default:return Z(!1,t(`toolExec.unknownAgentTrashAction`,{action:r}),{tool_call_id:n})}}async function $n(e,n){let{action:r}=e;switch(r){case`list`:return Qr(e,n);case`switch`:return $r(e,n);default:return Z(!1,t(`toolExec.unknownManageAgentAction`,{action:r}),{tool_call_id:n})}}async function er(e,n){let{action:r}=e;switch(r){case`read`:return jr(e,n);case`write`:return Nr(e,n);case`list`:return Pr(e,n);case`delete`:return Fr(e,n);case`download`:return Rr(e,n);default:return Z(!1,t(`toolExec.unknownAgentFileAction`,{action:r}),{tool_call_id:n})}}async function tr(e,n){let{searchType:r}=e;switch(r){case`file`:return Hr(e,n);case`content`:return Ur(e,n);default:return Z(!1,t(`toolExec.unknownAgentSearchType`,{type:r}),{tool_call_id:n})}}async function nr(e,n,r){let{scope:i=`last_n_rounds`,rounds:a=3,sessionId:o}=e,s=o||r||await ae();if(!s)return Z(!1,t(`toolExec.cannotGetSessionId`),{tool_call_id:n});let c=await ee(s);if(!c)return Z(!1,t(`toolExec.sessionNotFound`,{id:s}),{tool_call_id:n});let l=(c.messageHistory||[]).map((e,t)=>({msg:e,idx:t})).filter(({msg:e})=>e.role===`assistant`&&Array.isArray(e.executionLog)&&e.executionLog.length>0);if(l.length===0)return Z(!0,t(`toolExec.noExecutionLog`),{tool_call_id:n});let u;u=i===`full_session`?l:l.slice(-Math.min(a,l.length));let d=[],f=[],p=[],m=[];for(let{msg:e,idx:n}of u){let r=n+1,i=e.executionLog||[];for(let e of i){let n=e.nodeType;if(m.push({round:r,nodeType:n,nodeName:e.nodeName||e.action?.name||t(`toolExec.unknown`),status:e.status||`unknown`,timestamp:e.timestamp||null,toolName:e.action?.name||null}),n===`tool_exec`){let n=e.action?.name||e.nodeName||t(`toolExec.unknownTool`,{name:`unknown`}),i=e.action?.arguments||e.action?.args||{},a=e.status;a===`success`?d.push({round:r,tool:n,args:i,result:e.observation||e.result||`成功`,description:e.nodeName||``}):(a===`failed`||a===`cancelled`)&&f.push({round:r,tool:n,args:i,status:a,error:e.error||e.observation||e.result||t(`toolExec.unknownError`),description:e.nodeName||``})}n===`reflection`&&p.push({round:r,tool:e.action?.name||e.nodeName||t(`toolExec.unknown`),effective:e.effective===void 0?null:e.effective,reasoning:e.reasoning||e.analysis||``,suggestion:e.suggestion||e.advice||``,reflectionType:e.reflectionType||``})}}let h=u.length,g=m.length,_=m.filter(e=>e.status===`success`).length,v=m.filter(e=>e.status===`failed`||e.status===`cancelled`).length,y={sessionId:s,scope:i,roundsAnalyzed:h,stats:{totalSteps:g,successCount:_,failCount:v,successRate:g>0?(_/g*100).toFixed(1)+`%`:`0%`},successPaths:d,failures:f,reflections:p,timeline:m},b=[];if(b.push(`## 执行日志提炼报告`),b.push(``),b.push(`**会话**: ${c.title||s.slice(0,8)}`),b.push(`**分析范围**: ${i}(${h} 轮)`),b.push(`**统计**: 共 ${g} 步,成功 ${_},失败 ${v},成功率 ${y.stats.successRate}`),b.push(``),d.length>0){b.push(`### ✅ 成功路径`),b.push(``);for(let e of d)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\` → ${typeof e.result==`string`?e.result.substring(0,100):`执行成功`}`);b.push(``)}if(f.length>0){b.push(`### ❌ 失败教训`),b.push(``);for(let e of f)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\` ${e.status}: ${typeof e.error==`string`?e.error.substring(0,150):`未知错误`}`);b.push(``)}if(p.length>0){b.push(`### 🎯 反思建议`),b.push(``);for(let e of p)b.push(`- **[轮次${e.round}]** 工具 \`${e.tool}\``),e.reasoning&&b.push(` - 推理: ${e.reasoning.substring(0,200)}`),e.suggestion&&b.push(` - 建议: ${e.suggestion.substring(0,200)}`);b.push(``)}return Z(!0,b.join(`
280
+ `),{tool_call_id:n,extractedData:y})}var rr={capture_page:Bn,clarify_question:ur,notify:dr,fetch_url:mr,list_tabs:xr,browser_info:gr,download_file:_r,manage_cookies:Sr,plan_task:Cr,clear_data:wr,search_chats:lr,preview_ui:Dr,agent_file:er,agent_exec:Br,agent_search:tr,agent_skill:Ar,wait_navigation:Mr,handle_dialog:hr,dispatch_task:$t,agent_memory:async(e,t,n)=>vn(e,t,n),page_content:Kr,extract_data:qr,clipboard:Jr,manage_tab:Xn,search_browser_data:Zn,agent_trash:Qn,manage_agent:$n,exec_log:nr},ir={};for(let e of f)e.execution===`background`&&rr[e.id]&&(ir[e.id]=rr[e.id]);var ar={};for(let e of f)if(e.execution===`content_script`){let t=e.function.parameters?.properties;if(t){let n=Object.keys(t);ar[e.id]=e=>{let t={};for(let r of n)t[r]=e[r];return t}}else ar[e.id]=()=>({})}ar.search_in_page=e=>({query:e.query||e.pattern,mode:e.mode,caseSensitive:e.caseSensitive,contextLength:e.contextLength,maxResults:e.maxResults,highlight:e.highlight});async function or(e,n,r=null){let i=Date.now(),{name:a,arguments:o,id:s,function:c,index:l}=e,u=a||c&&c.name,f=s,p={};if(console.log(`[Background] tool callraw data:`,JSON.stringify(e)),c&&c.arguments){console.log(`[Background] toolCall.function.arguments type:`,typeof c.arguments);try{p=Wn(c.arguments)||{}}catch(e){return console.error(`[Background] parsetool parameter failed:`,e,`originalvalue:`,JSON.stringify(c.arguments).substring(0,300)),{success:!1,error:t(`toolExec.argParseFailed`),tool_call_id:f}}let e=typeof c.arguments==`string`?c.arguments.trim():JSON.stringify(c.arguments);Object.keys(p).length===0&&e.length>0&&e!==`{}`&&console.error(`[Background] parameterparse after empty object!original arguments:`,JSON.stringify(c.arguments).substring(0,300))}else if(typeof o==`object`)p=o||{};else if(typeof o==`string`){console.log(`[Background] using backup argsStr parse:`,o.substring(0,300));try{p=Wn(o)||{}}catch(e){return console.error(`[Background] parsetool parameter failed:`,e,`originalvalue:`,o),{success:!1,error:t(`toolExec.argParseFailed`),tool_call_id:f}}}console.log(`[Background] exec tool:`,u,p,`id:`,f);let m=d[u],h;if(m===`background`){let e=ir[u];e?(console.log(`[Background] ${u} directly execute, not passed content script`),h=await e(p,f,r,n)):h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f}}else if(m===`content_script`){let e=ar[u];if(e){let n=u.toUpperCase(),i=e(p),a=r?Se(r):null,o=p.tabId||a||await Jn();h=o?await Yn(o,{type:n,...i},f):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:f}}else h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f}}else h={success:!1,error:t(`toolExec.unknownTool`,{name:u}),tool_call_id:f};h=Kn(h,f);let g=Date.now()-i;return qn(u,h,g),h}function sr(e,n){let r=e.query||``,a=parseInt(e.maxResults,10)||10;return console.log(`[Background] exec bookmarksearch:`,`query=`,JSON.stringify(r),`maxResults=`,a),new Promise(e=>{if(!chrome.bookmarks){console.error(`[Background] chrome.bookmarks API non- with `),e(Z(!1,t(`toolExec.bookmarkApiUnavailable`)));return}if(!r||r.trim()===``){console.log(`[Background] emptyquery,getbookmark rootnode...`),chrome.bookmarks.getTree(n=>{if(console.log(`[Background] chrome.bookmarks.getTree callback, tree node count:`,n?n.length:`null`),chrome.runtime.lastError){console.error(`[Background] chrome.bookmarks.getTree error:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.bookmarkFetchFailed`,{error:chrome.runtime.lastError.message})));return}let r=[];function o(e){e&&e.forEach(e=>{e.url&&r.push(e),e.children&&e.children.length>0&&o(e.children)})}if(o(n),console.log(`[Background] receiset to total bookmarks:`,r.length),r.length===0){e(Z(!0,t(`toolExec.noBookmarks`)));return}let s=r.slice(0,a).map(e=>({title:e.title||t(`toolExec.noTitle`),url:e.url||``,dateAdded:e.dateAdded?new Date(e.dateAdded).toLocaleString(i()===`en`?`en-US`:`zh-CN`):null})),c=`${t(`toolExec.bookmarksCount`,{total:r.length,shown:s.length})}\n`+s.map((e,t)=>`${t+1}. ${e.title}\n URL: ${e.url}`).join(`
281
281
 
282
282
  `);console.log(`[Background] bookmark search successful,return result:`,s.length),e(Z(!0,c))});return}console.log(`[Background] call with chrome.bookmarks.search...`),chrome.bookmarks.search(r,n=>{if(console.log(`[Background] chrome.bookmarks.search callback, result count:`,n?n.length:`null`),chrome.runtime.lastError){console.error(`[Background] chrome.bookmarks.search error:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.bookmarkSearchFailed`,{error:chrome.runtime.lastError.message})));return}if(!n||n.length===0){console.log(`[Background] not foundmatched bookmarks`),e(Z(!0,t(`toolExec.bookmarkNoMatch`)));return}let r=n.slice(0,a).map(e=>({title:e.title||`(无标题)`,url:e.url||``,dateAdded:e.dateAdded?new Date(e.dateAdded).toLocaleString(`zh-CN`):null})),i=`找到 ${n.length} 个匹配的书签,显示前 ${r.length} 个:\n`+r.map((e,t)=>`${t+1}. ${e.title}\n URL: ${e.url}`).join(`
283
283
 
284
- `);console.log(`[Background] bookmark search successful,return result:`,r.length),e(Z(!0,i))})})}function or(e,n){let r=e.query||``,a=parseInt(e.maxResults,10)||10,o=e.startTime||null,s=e.endTime||null;return console.log(`[Background] exec historyrecordsearch:`,`query=`,JSON.stringify(r),`maxResults=`,a,`time range:`,o,`-`,s),new Promise(e=>{if(!chrome.history){console.error(`[Background] chrome.history API non- with `),e(Z(!1,t(`toolExec.historyApiUnavailable`)));return}let n={text:r,maxResults:a};o&&(n.startTime=o),s&&(n.endTime=s),console.log(`[Background] call with chrome.history.search, options:`,JSON.stringify(n)),chrome.history.search(n,n=>{if(console.log(`[Background] chrome.history.search callback, result count:`,n?n.length:`null`),chrome.runtime.lastError){console.error(`[Background] chrome.history.search error:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.historySearchFailed`,{error:chrome.runtime.lastError.message})));return}if(!n||n.length===0){console.log(`[Background] not foundmatched visitsrecord`),e(Z(!0,t(`toolExec.historyNoMatch`)));return}let r=n.map(e=>({title:e.title||`(无标题)`,url:e.url,lastVisitTime:e.lastVisitTime?new Date(e.lastVisitTime).toLocaleString(i()===`en`?`en-US`:`zh-CN`):null,visitCount:e.visitCount||0})),a=`${t(`toolExec.historyResultsCount`,{count:n.length})}\n`+r.map((e,t)=>`${t+1}. ${e.title}\n URL: ${e.url}\n 最后访问: ${e.lastVisitTime}\n 访问次数: ${e.visitCount}`).join(`
284
+ `);console.log(`[Background] bookmark search successful,return result:`,r.length),e(Z(!0,i))})})}function cr(e,n){let r=e.query||``,a=parseInt(e.maxResults,10)||10,o=e.startTime||null,s=e.endTime||null;return console.log(`[Background] exec historyrecordsearch:`,`query=`,JSON.stringify(r),`maxResults=`,a,`time range:`,o,`-`,s),new Promise(e=>{if(!chrome.history){console.error(`[Background] chrome.history API non- with `),e(Z(!1,t(`toolExec.historyApiUnavailable`)));return}let n={text:r,maxResults:a};o&&(n.startTime=o),s&&(n.endTime=s),console.log(`[Background] call with chrome.history.search, options:`,JSON.stringify(n)),chrome.history.search(n,n=>{if(console.log(`[Background] chrome.history.search callback, result count:`,n?n.length:`null`),chrome.runtime.lastError){console.error(`[Background] chrome.history.search error:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.historySearchFailed`,{error:chrome.runtime.lastError.message})));return}if(!n||n.length===0){console.log(`[Background] not foundmatched visitsrecord`),e(Z(!0,t(`toolExec.historyNoMatch`)));return}let r=n.map(e=>({title:e.title||`(无标题)`,url:e.url,lastVisitTime:e.lastVisitTime?new Date(e.lastVisitTime).toLocaleString(i()===`en`?`en-US`:`zh-CN`):null,visitCount:e.visitCount||0})),a=`${t(`toolExec.historyResultsCount`,{count:n.length})}\n`+r.map((e,t)=>`${t+1}. ${e.title}\n URL: ${e.url}\n 最后访问: ${e.lastVisitTime}\n 访问次数: ${e.visitCount}`).join(`
285
285
 
286
- `);console.log(`[Background] historyrecordsearch successful,return result:`,r.length),e(Z(!0,a))})})}async function sr(e,n,r=null){let i=(e.query||``).toLowerCase(),a=parseInt(e.maxResults,10)||(i?5:100),o=e.searchScope||`current_session`;console.log(`[Background] exec conversation memorysearch:`,`query=`,JSON.stringify(i),`maxResults=`,a,`scope=`,o,`sessionId=`,r);try{await se();let n=[],s=null;if(o!==`all_sessions`&&(s=r||await ae()),n=(await g(s)).map(e=>({session:e.sessionLabel,index:e.index,role:e.role,content:e.content})),o===`all_sessions`&&(await A()).forEach(e=>{n.push({session:e.sessionLabel,index:e.index,role:e.role,content:e.content})}),n.length===0)return Z(!0,t(`toolExec.noChatRecords`));if(!i){let e=n.slice(0,a);return Z(!0,`${t(`toolExec.chatMessagesCount`,{total:n.length,shown:e.length})}\n\n`+e.map((e,n)=>{let r=typeof e.content==`string`?e.content:Array.isArray(e.content)?e.content.filter(e=>e.type===`text`).map(e=>e.text).join(``):``,i=r.length>500?r.substring(0,500)+`...`:r;return`### ${n+1}. [${e.session}] ${e.role===`user`?t(`toolExec.roleUser`):t(`toolExec.roleAssistant`)}${t(`toolExec.chatMessageLabel`)}\n${i}`}).join(`
286
+ `);console.log(`[Background] historyrecordsearch successful,return result:`,r.length),e(Z(!0,a))})})}async function lr(e,n,r=null){let i=(e.query||``).toLowerCase(),a=parseInt(e.maxResults,10)||(i?5:100),o=e.searchScope||`current_session`;console.log(`[Background] exec conversation memorysearch:`,`query=`,JSON.stringify(i),`maxResults=`,a,`scope=`,o,`sessionId=`,r);try{await se();let n=[],s=null;if(o!==`all_sessions`&&(s=r||await ae()),n=(await g(s)).map(e=>({session:e.sessionLabel,index:e.index,role:e.role,content:e.content})),o===`all_sessions`&&(await A()).forEach(e=>{n.push({session:e.sessionLabel,index:e.index,role:e.role,content:e.content})}),n.length===0)return Z(!0,t(`toolExec.noChatRecords`));if(!i){let e=n.slice(0,a);return Z(!0,`${t(`toolExec.chatMessagesCount`,{total:n.length,shown:e.length})}\n\n`+e.map((e,n)=>{let r=typeof e.content==`string`?e.content:Array.isArray(e.content)?e.content.filter(e=>e.type===`text`).map(e=>e.text).join(``):``,i=r.length>500?r.substring(0,500)+`...`:r;return`### ${n+1}. [${e.session}] ${e.role===`user`?t(`toolExec.roleUser`):t(`toolExec.roleAssistant`)}${t(`toolExec.chatMessageLabel`)}\n${i}`}).join(`
287
287
 
288
288
  ---
289
289
 
@@ -291,22 +291,22 @@ Image recognition analysis failed: {error}`,dialogAccept:`auto-accept`,dialogDis
291
291
 
292
292
  ---
293
293
 
294
- `);return console.log(`[Background] conversation memorysearch successful,return:`,l.length,`result`),Z(!0,u)}catch(e){return console.error(`[Background] conversation memorysearch failed:`,e),Z(!1,t(`toolExec.chatSearchError`,{error:e.message}))}}async function cr(e,n,r=null){let{question:i,recommendedOption:a,allowCustomInput:o=!0,allowAdditionalInfo:s=!0}=e,c=Array.isArray(e.options)?e.options:e.options?[String(e.options)]:[];console.log(`[Background] exec clarificationtool:`,e,`toolCallId:`,n,`sessionId:`,r);let l=(await z()).reactConfig.clarifyTimeout;return new Promise(e=>{let u={question:i,options:c,recommendedOption:a===void 0?0:a,allowCustomInput:o,allowAdditionalInfo:s,toolCallId:n,timeout:l,sessionId:r},d=null,f=null,p=null,m=()=>{d&&=(clearTimeout(d),null),p&&=(clearInterval(p),null),f&&=(chrome.runtime.onMessage.removeListener(f),null)},h=r=>{if(r.type===`CLARIFY_RESPONSE`&&r.toolCallId===n){m(),console.log(`[Background] received clarificationresponse:`,r);let{selectedOption:n,customInput:i,additionalInfo:a}=r,o=``;o=n>=0&&c[n]?t(`toolExec.selectedOption`,{option:c[n]}):i&&i.trim()?t(`toolExec.customInput`,{input:i.trim()}):t(`toolExec.noClarification`),a&&a.trim()&&(o+=`\n补充说明: ${a.trim()}`),e(Z(!0,o))}};chrome.runtime.sendMessage({type:`SHOW_CLARIFY_DIALOG`,sessionId:r,data:u},i=>{if(chrome.runtime.lastError){console.error(`[Background] send clarificationmessage failed:`,chrome.runtime.lastError.message),m(),e({success:!1,error:t(`toolExec.clarifyDialogFailed`,{error:chrome.runtime.lastError.message}),tool_call_id:n});return}console.log(`[Background] clarification dialogsent to Side Panel,timeout:`,l,`ms`),d=setTimeout(()=>{console.error(`[Background] clarification dialogtimeout`),m(),chrome.runtime.sendMessage({type:`CLARIFY_TIMEOUT`,toolCallId:n,sessionId:r}).catch(()=>{}),e({success:!1,error:t(`toolExec.clarifyTimeout`,{seconds:Math.round(l/1e3)}),tool_call_id:n})},l),p=setInterval(async()=>{try{let i=await chrome.runtime.getContexts({contextTypes:[`SIDE_PANEL`]});(!i||i.length===0)&&(console.warn(`[Background] Side Panel closed,early terminateclarificationwaiting`),m(),chrome.runtime.sendMessage({type:`CLARIFY_TIMEOUT`,toolCallId:n,sessionId:r}).catch(()=>{}),e({success:!1,error:t(`toolExec.clarifyPanelClosed`),tool_call_id:n}))}catch{}},5e3),f=(e,t,n)=>{h(e)},chrome.runtime.onMessage.addListener(f)})})}function lr(e,n){let{title:r,message:i,icon:a,silent:o=!1,requireInteraction:s=!1,playSound:c=!1,soundType:l=`default`}=e;return console.log(`[Background] exec browser notification:`,e,`toolCallId:`,n),new Promise(e=>{let n={type:`basic`,title:r,message:i,iconUrl:a||`icons/icon128.png`,silent:o===!0||o===`true`,requireInteraction:s===!0||s===`true`};chrome.notifications.create(n,n=>{if(chrome.runtime.lastError){console.error(`[Background] create notification failed:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.notificationFailed`,{error:chrome.runtime.lastError.message})));return}console.log(`[Background] notification created,ID:`,n),c&&chrome.runtime.sendMessage({type:`PLAY_NOTIFICATION_SOUND`,soundType:l}),e(Z(!0,t(`toolExec.notificationSent`)))})})}async function ur(e,t,n){let r=Math.max(1,Math.floor(Number(n)||6e4)),i=new AbortController,a=t?.signal,o,s;typeof AbortSignal.timeout==`function`?o=AbortSignal.timeout(r):(o=i.signal,s=setTimeout(()=>i.abort(),r));let c=()=>i.abort();o.addEventListener(`abort`,c,{once:!0}),a&&(a.aborted?i.abort():a.addEventListener(`abort`,c,{once:!0}));try{let n=await fetch(e,{...t,signal:i.signal});return o.removeEventListener(`abort`,c),a&&a.removeEventListener(`abort`,c),s&&clearTimeout(s),n}catch(e){throw o.removeEventListener(`abort`,c),a&&a.removeEventListener(`abort`,c),s&&clearTimeout(s),e.name===`AbortError`?a?.aborted?e:Error(`请求超时 (${r}ms)`):e}}async function dr(e,t,n,r=3,i=1e3,a=null){let o;for(let s=0;s<=r;s++)try{let c=await ur(e,t,n);if((c.status>=500||c.status===429)&&s<r){let e=await c.text().catch(()=>``);o=Error(`HTTP ${c.status}: ${e.substring(0,200)}`);let t=i*2**s;console.log(`[Background] API return ${c.status},${t}ms after retry (${s+1}/${r})`),a&&a(s+1,o,t),await new Promise(e=>setTimeout(e,t));continue}return c}catch(e){if(o=e,s>=r||e.name===`AbortError`&&!e.message.includes(`超时`))break;let t=i*2**s;console.log(`[Background] API call with failed,${t}ms after retry (${s+1}/${r}):`,e.message),a&&a(s+1,e,t),await new Promise(e=>setTimeout(e,t))}throw o}async function fr(e,n){let{url:r,method:i=`GET`,headers:a={},body:o,timeout:s=15e3}=e;if(console.log(`[Background] exec HTTP request:`,`method=`,i,`url=`,r,`timeout=`,s),!r)return{success:!1,error:t(`toolExec.missingUrlParam`),tool_call_id:n};try{new URL(r)}catch{return{success:!1,error:t(`toolExec.invalidUrlFormat`,{url:r}),tool_call_id:n}}let c={};if(a&&typeof a==`object`)for(let[e,t]of Object.entries(a))c[e]=String(t??``);let l={method:i.toUpperCase(),headers:c};o&&i.toUpperCase()!==`GET`&&i.toUpperCase()!==`HEAD`&&(l.body=typeof o==`object`?JSON.stringify(o):o),console.log(`[Background] fetch options:`,JSON.stringify(l));try{let e=await dr(r,l,s,1);console.log(`[Background] HTTP response status:`,e.status,e.statusText);try{let t=await e.text(),r={success:e.status>=200&&e.status<300,status:e.status,statusText:e.statusText,content:t.substring(0,1e4),contentLength:t.length,url:e.url};return console.log(`[Background] HTTP response contentlength:`,t.length),{...r,tool_call_id:n}}catch(r){return console.error(`[Background] readresponse content failed:`,r),{success:!1,error:t(`toolExec.readResponseFailed`,{error:r.message}),status:e.status,tool_call_id:n}}}catch(e){let i=e.message;return e.name===`AbortError`?(console.warn(`[Background] HTTP request timed out:`,r,`(${s}ms)`),i=t(`toolExec.requestTimeout`,{timeout:s})):(console.error(`[Background] HTTP request failed:`,e.name,e.message),e.message===`Failed to fetch`?i=t(`toolExec.requestFailed`):e.message.includes(`CORS`)&&(i=`CORS 跨域限制,目标服务器不允许跨域访问`)),{success:!1,error:i,originalError:e.message,url:r,tool_call_id:n}}}async function pr(e,n,r){let i=e.action;if(!i)return{success:!1,error:t(`toolExec.missingAction`),tool_call_id:n};let a=r?Se(r):null,o=e.tabId||a||await Kn();if(!o)return{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n};try{await chrome.scripting.executeScript({target:{tabId:o},world:`MAIN`,func:e=>e===`restore`?(window.__aihOriginalAlert&&(window.alert=window.__aihOriginalAlert,window.confirm=window.__aihOriginalConfirm,window.prompt=window.__aihOriginalPrompt,delete window.__aihOriginalAlert,delete window.__aihOriginalConfirm,delete window.__aihOriginalPrompt),`restored`):(window.__aihOriginalAlert||(window.__aihOriginalAlert=window.alert,window.__aihOriginalConfirm=window.confirm,window.__aihOriginalPrompt=window.prompt),e===`accept`?(window.alert=function(){},window.confirm=function(){return!0},window.prompt=function(){return``}):e===`dismiss`&&(window.alert=function(){},window.confirm=function(){return!1},window.prompt=function(){return null}),e),args:[i]});let e={accept:t(`toolExec.dialogAccept`),dismiss:t(`toolExec.dialogDismiss`),restore:t(`toolExec.dialogRestore`)};return Z(!0,t(`toolExec.dialogSet`,{mode:e[i]||i}),{tool_call_id:n})}catch(e){return{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}function mr(e,t){console.log(`[Background] get browserinfo`);let n={success:!0,browserName:navigator.appName,browserVersion:navigator.appVersion,platform:navigator.platform,language:navigator.language,userAgent:navigator.userAgent,cookieEnabled:navigator.cookieEnabled,onLine:navigator.onLine,prefersDarkMode:typeof window<`u`&&window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches,screenWidth:typeof screen<`u`?screen.width:null,screenHeight:typeof screen<`u`?screen.height:null,colorDepth:typeof screen<`u`?screen.colorDepth:null};return typeof chrome<`u`&&chrome.runtime&&(n.extensionVersion=chrome.runtime.getManifest().version),Promise.resolve(n)}function hr(e,n){let{url:r,filename:i}=e;return console.log(`[Background] download file:`,`url=`,r,`filename=`,i),new Promise(e=>{let n=i;if(!n){let e=r.split(`/`);n=e[e.length-1].split(`?`)[0]||`download`}chrome.downloads.download({url:r,filename:`Downloads/`+n,saveAs:!0},r=>{chrome.runtime.lastError?(console.error(`[Background] download failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message})):(console.log(`[Background] download created,ID:`,r),e({success:!0,message:t(`toolExec.downloadStarted`),downloadId:r,filename:n}))})})}function gr(e,n,r){let{url:i,active:a=!0,waitForLoad:o=!1,loadTimeout:s=15e3}=e,c=typeof a==`boolean`?a:String(a).toLowerCase()===`true`;return console.log(`[Background] opennewlabelpage:`,`url=`,i,`active=`,c,`waitForLoad=`,o,`loadTimeout=`,s),new Promise(e=>{chrome.tabs.create({url:i,active:c},a=>{if(chrome.runtime.lastError){console.error(`[Background] openlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n});return}r&&xe(r,a.id);let c=`后续操作此页的工具请传 tabId=${a.id}(不传则默认用此页)`;if(!o){e({success:!0,message:t(`toolExec.tabOpened`,{tabId:a.id,hint:c}),tabId:a.id,url:a.url,tool_call_id:n});return}let l=!1,u=Math.max(1e3,Math.floor(Number(s)||15e3)),d=setTimeout(()=>{l||(l=!0,chrome.tabs.onUpdated.removeListener(f),console.warn(`[Background] page loadtimeout:`,i,`(${u}ms)`),e({success:!0,message:t(`toolExec.tabOpenTimeout`,{timeout:u,hint:c}),tabId:a.id,url:a.url,loadTimedOut:!0,tool_call_id:n}))},u),f=(r,i,o)=>{if(r===a.id&&i.status===`complete`){if(l)return;l=!0,clearTimeout(d),chrome.tabs.onUpdated.removeListener(f),console.log(`[Background] page loadcomplete:`,o.url),e({success:!0,message:t(`toolExec.tabLoaded`,{url:o.url,hint:c}),tabId:a.id,url:o.url,tool_call_id:n})}};chrome.tabs.onUpdated.addListener(f)})})}function _r(e,n,r){let{tabId:i}=e,a=parseInt(i,10);return console.log(`[Background] switchlabelpage:`,`tabId=`,a),new Promise(e=>{chrome.tabs.update(a,{active:!0},n=>{chrome.runtime.lastError?(console.error(`[Background] switchlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message})):(r&&xe(r,n.id),e({success:!0,message:t(`toolExec.tabSwitched`,{tabId:n.id}),tabId:n.id,url:n.url}))})})}function vr(e,n){let{tabId:r}=e,i=r===void 0?void 0:parseInt(r,10);return console.log(`[Background] closelabelpage:`,`tabId=`,i),new Promise(e=>{(i||null)===null?chrome.tabs.query({active:!0,currentWindow:!0},n=>{n&&n.length>0?chrome.tabs.remove(n[0].id,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message}):e({success:!0,message:t(`toolExec.tabClosed`)})}):e({success:!1,error:t(`toolExec.tabNotFound`)})}):chrome.tabs.remove(i,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message}):e({success:!0,message:t(`toolExec.tabClosedWithId`,{tabId:i})})})})}function yr(e,t){let{mode:n=`all`,includeUrl:r=!0,includeTitle:i=!0}=e;return console.log(`[Background] getlabelpage column table:`,`mode=`,n,`includeUrl=`,r,`includeTitle=`,i),new Promise(e=>{let t=n===`active`?{active:!0,currentWindow:!0}:{currentWindow:!0};chrome.tabs.query(t,t=>{if(chrome.runtime.lastError)console.error(`[Background] getlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message});else{let n=t.map(e=>{let t={id:e.id};return r&&(t.url=e.url),i&&(t.title=e.title),t.active=e.active,t});e({success:!0,count:n.length,tabs:n})}})})}function br(e,n){return new Promise(r=>{let{action:i,name:a,value:o,domain:s,path:c=`/`,secure:l=!1,httpOnly:u=!1,expirationDate:d}=e,f=l===!0||l===`true`,p=u===!0||u===`true`,m=d===void 0?void 0:parseFloat(d);(e=>{chrome.tabs.query({active:!0,currentWindow:!0},t=>{if(t&&t[0]&&t[0].url)try{e(new URL(t[0].url).hostname)}catch{e(``)}else e(``)})})(e=>{let l=s||e;switch(i){case`get`:if(!a){r({success:!1,error:t(`toolExec.getRequiresName`),tool_call_id:n});return}chrome.cookies.get({url:`https://${l}`,name:a},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookie:e,tool_call_id:n})});break;case`set`:if(!a||o===void 0){r({success:!1,error:t(`toolExec.setRequiresNameValue`),tool_call_id:n});return}let e={url:`https://${l}`,name:a,value:o,path:c,secure:f,httpOnly:p,domain:l.startsWith(`.`)?l:`.`+l};m&&(e.expirationDate=m),chrome.cookies.set(e,e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookie:e,message:t(`toolExec.cookieSet`,{name:a}),tool_call_id:n})});break;case`remove`:if(!a){r({success:!1,error:t(`toolExec.removeRequiresName`),tool_call_id:n});return}chrome.cookies.remove({url:`https://${l}`,name:a},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):(r({success:!0,message:t(`toolExec.cookieDeleted`,{name:a}),tool_call_id:n}),Mn(`cookie_write`,`Delete cookie: ${a}`,{domain:l,name:a}))});break;case`list`:chrome.cookies.getAll({domain:l},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookies:e,total:e.length,tool_call_id:n})});break;default:r({success:!1,error:t(`toolExec.unknownAction`,{action:i}),tool_call_id:n})}})})}function xr(e,n){let{taskDescription:r,subtasks:i=[],isComplex:a=!0,strategy:o=`sequential`}=e;if(console.log(`[Background] exec task planningtool:`,JSON.stringify(e)),!r)return Promise.resolve({success:!1,error:t(`toolExec.missingTaskDesc`),tool_call_id:n});if(!Array.isArray(i)||i.length===0)return Promise.resolve({success:!1,error:t(`toolExec.emptySubtasks`),tool_call_id:n});if(i.filter(e=>!e.id||!e.name||!e.description).length>0)return Promise.resolve({success:!1,error:t(`toolExec.invalidSubtaskStructure`),tool_call_id:n});let s={taskDescription:r,isComplex:a,strategy:o,totalSubtasks:i.length,estimatedTotalSteps:i.reduce((e,t)=>e+(t.estimatedSteps||1),0),subtasks:i.map(e=>({id:e.id,name:e.name,description:e.description,dependencies:e.dependencies||[],requiredTools:e.requiredTools||[],estimatedSteps:e.estimatedSteps||1})),planId:n||crypto.randomUUID(),createdAt:new Date().toISOString()};return Promise.resolve({success:!0,data:s,message:(()=>{let e=`📋 任务规划完成
294
+ `);return console.log(`[Background] conversation memorysearch successful,return:`,l.length,`result`),Z(!0,u)}catch(e){return console.error(`[Background] conversation memorysearch failed:`,e),Z(!1,t(`toolExec.chatSearchError`,{error:e.message}))}}async function ur(e,n,r=null){let{question:i,recommendedOption:a,allowCustomInput:o=!0,allowAdditionalInfo:s=!0}=e,c=Array.isArray(e.options)?e.options:e.options?[String(e.options)]:[];console.log(`[Background] exec clarificationtool:`,e,`toolCallId:`,n,`sessionId:`,r);let l=(await z()).reactConfig.clarifyTimeout;return new Promise(e=>{let u={question:i,options:c,recommendedOption:a===void 0?0:a,allowCustomInput:o,allowAdditionalInfo:s,toolCallId:n,timeout:l,sessionId:r},d=null,f=null,p=null,m=()=>{d&&=(clearTimeout(d),null),p&&=(clearInterval(p),null),f&&=(chrome.runtime.onMessage.removeListener(f),null)},h=r=>{if(r.type===`CLARIFY_RESPONSE`&&r.toolCallId===n){m(),console.log(`[Background] received clarificationresponse:`,r);let{selectedOption:n,customInput:i,additionalInfo:a}=r,o=``;o=n>=0&&c[n]?t(`toolExec.selectedOption`,{option:c[n]}):i&&i.trim()?t(`toolExec.customInput`,{input:i.trim()}):t(`toolExec.noClarification`),a&&a.trim()&&(o+=`\n补充说明: ${a.trim()}`),e(Z(!0,o))}};chrome.runtime.sendMessage({type:`SHOW_CLARIFY_DIALOG`,sessionId:r,data:u},i=>{if(chrome.runtime.lastError){console.error(`[Background] send clarificationmessage failed:`,chrome.runtime.lastError.message),m(),e({success:!1,error:t(`toolExec.clarifyDialogFailed`,{error:chrome.runtime.lastError.message}),tool_call_id:n});return}console.log(`[Background] clarification dialogsent to Side Panel,timeout:`,l,`ms`),d=setTimeout(()=>{console.error(`[Background] clarification dialogtimeout`),m(),chrome.runtime.sendMessage({type:`CLARIFY_TIMEOUT`,toolCallId:n,sessionId:r}).catch(()=>{}),e({success:!1,error:t(`toolExec.clarifyTimeout`,{seconds:Math.round(l/1e3)}),tool_call_id:n})},l),p=setInterval(async()=>{try{let i=await chrome.runtime.getContexts({contextTypes:[`SIDE_PANEL`]});(!i||i.length===0)&&(console.warn(`[Background] Side Panel closed,early terminateclarificationwaiting`),m(),chrome.runtime.sendMessage({type:`CLARIFY_TIMEOUT`,toolCallId:n,sessionId:r}).catch(()=>{}),e({success:!1,error:t(`toolExec.clarifyPanelClosed`),tool_call_id:n}))}catch{}},5e3),f=(e,t,n)=>{h(e)},chrome.runtime.onMessage.addListener(f)})})}function dr(e,n){let{title:r,message:i,icon:a,silent:o=!1,requireInteraction:s=!1,playSound:c=!1,soundType:l=`default`}=e;return console.log(`[Background] exec browser notification:`,e,`toolCallId:`,n),new Promise(e=>{let n={type:`basic`,title:r,message:i,iconUrl:a||`icons/icon128.png`,silent:o===!0||o===`true`,requireInteraction:s===!0||s===`true`};chrome.notifications.create(n,n=>{if(chrome.runtime.lastError){console.error(`[Background] create notification failed:`,chrome.runtime.lastError.message),e(Z(!1,t(`toolExec.notificationFailed`,{error:chrome.runtime.lastError.message})));return}console.log(`[Background] notification created,ID:`,n),c&&chrome.runtime.sendMessage({type:`PLAY_NOTIFICATION_SOUND`,soundType:l}),e(Z(!0,t(`toolExec.notificationSent`)))})})}async function fr(e,t,n){let r=Math.max(1,Math.floor(Number(n)||6e4)),i=new AbortController,a=t?.signal,o,s;typeof AbortSignal.timeout==`function`?o=AbortSignal.timeout(r):(o=i.signal,s=setTimeout(()=>i.abort(),r));let c=()=>i.abort();o.addEventListener(`abort`,c,{once:!0}),a&&(a.aborted?i.abort():a.addEventListener(`abort`,c,{once:!0}));try{let n=await fetch(e,{...t,signal:i.signal});return o.removeEventListener(`abort`,c),a&&a.removeEventListener(`abort`,c),s&&clearTimeout(s),n}catch(e){throw o.removeEventListener(`abort`,c),a&&a.removeEventListener(`abort`,c),s&&clearTimeout(s),e.name===`AbortError`?a?.aborted?e:Error(`请求超时 (${r}ms)`):e}}async function pr(e,t,n,r=3,i=1e3,a=null){let o;for(let s=0;s<=r;s++)try{let c=await fr(e,t,n);if((c.status>=500||c.status===429)&&s<r){let e=await c.text().catch(()=>``);o=Error(`HTTP ${c.status}: ${e.substring(0,200)}`);let t=i*2**s;console.log(`[Background] API return ${c.status},${t}ms after retry (${s+1}/${r})`),a&&a(s+1,o,t),await new Promise(e=>setTimeout(e,t));continue}return c}catch(e){if(o=e,s>=r||e.name===`AbortError`&&!e.message.includes(`超时`))break;let t=i*2**s;console.log(`[Background] API call with failed,${t}ms after retry (${s+1}/${r}):`,e.message),a&&a(s+1,e,t),await new Promise(e=>setTimeout(e,t))}throw o}async function mr(e,n){let{url:r,method:i=`GET`,headers:a={},body:o,timeout:s=15e3}=e;if(console.log(`[Background] exec HTTP request:`,`method=`,i,`url=`,r,`timeout=`,s),!r)return{success:!1,error:t(`toolExec.missingUrlParam`),tool_call_id:n};try{new URL(r)}catch{return{success:!1,error:t(`toolExec.invalidUrlFormat`,{url:r}),tool_call_id:n}}let c={};if(a&&typeof a==`object`)for(let[e,t]of Object.entries(a))c[e]=String(t??``);let l={method:i.toUpperCase(),headers:c};o&&i.toUpperCase()!==`GET`&&i.toUpperCase()!==`HEAD`&&(l.body=typeof o==`object`?JSON.stringify(o):o),console.log(`[Background] fetch options:`,JSON.stringify(l));try{let e=await pr(r,l,s,1);console.log(`[Background] HTTP response status:`,e.status,e.statusText);try{let t=await e.text(),r={success:e.status>=200&&e.status<300,status:e.status,statusText:e.statusText,content:t.substring(0,1e4),contentLength:t.length,url:e.url};return console.log(`[Background] HTTP response contentlength:`,t.length),{...r,tool_call_id:n}}catch(r){return console.error(`[Background] readresponse content failed:`,r),{success:!1,error:t(`toolExec.readResponseFailed`,{error:r.message}),status:e.status,tool_call_id:n}}}catch(e){let i=e.message;return e.name===`AbortError`?(console.warn(`[Background] HTTP request timed out:`,r,`(${s}ms)`),i=t(`toolExec.requestTimeout`,{timeout:s})):(console.error(`[Background] HTTP request failed:`,e.name,e.message),e.message===`Failed to fetch`?i=t(`toolExec.requestFailed`):e.message.includes(`CORS`)&&(i=`CORS 跨域限制,目标服务器不允许跨域访问`)),{success:!1,error:i,originalError:e.message,url:r,tool_call_id:n}}}async function hr(e,n,r){let i=e.action;if(!i)return{success:!1,error:t(`toolExec.missingAction`),tool_call_id:n};let a=r?Se(r):null,o=e.tabId||a||await Jn();if(!o)return{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n};try{await chrome.scripting.executeScript({target:{tabId:o},world:`MAIN`,func:e=>e===`restore`?(window.__aihOriginalAlert&&(window.alert=window.__aihOriginalAlert,window.confirm=window.__aihOriginalConfirm,window.prompt=window.__aihOriginalPrompt,delete window.__aihOriginalAlert,delete window.__aihOriginalConfirm,delete window.__aihOriginalPrompt),`restored`):(window.__aihOriginalAlert||(window.__aihOriginalAlert=window.alert,window.__aihOriginalConfirm=window.confirm,window.__aihOriginalPrompt=window.prompt),e===`accept`?(window.alert=function(){},window.confirm=function(){return!0},window.prompt=function(){return``}):e===`dismiss`&&(window.alert=function(){},window.confirm=function(){return!1},window.prompt=function(){return null}),e),args:[i]});let e={accept:t(`toolExec.dialogAccept`),dismiss:t(`toolExec.dialogDismiss`),restore:t(`toolExec.dialogRestore`)};return Z(!0,t(`toolExec.dialogSet`,{mode:e[i]||i}),{tool_call_id:n})}catch(e){return{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}function gr(e,t){console.log(`[Background] get browserinfo`);let n={success:!0,browserName:navigator.appName,browserVersion:navigator.appVersion,platform:navigator.platform,language:navigator.language,userAgent:navigator.userAgent,cookieEnabled:navigator.cookieEnabled,onLine:navigator.onLine,prefersDarkMode:typeof window<`u`&&window.matchMedia&&window.matchMedia(`(prefers-color-scheme: dark)`).matches,screenWidth:typeof screen<`u`?screen.width:null,screenHeight:typeof screen<`u`?screen.height:null,colorDepth:typeof screen<`u`?screen.colorDepth:null};return typeof chrome<`u`&&chrome.runtime&&(n.extensionVersion=chrome.runtime.getManifest().version),Promise.resolve(n)}function _r(e,n){let{url:r,filename:i}=e;return console.log(`[Background] download file:`,`url=`,r,`filename=`,i),new Promise(e=>{let n=i;if(!n){let e=r.split(`/`);n=e[e.length-1].split(`?`)[0]||`download`}chrome.downloads.download({url:r,filename:`Downloads/`+n,saveAs:!0},r=>{chrome.runtime.lastError?(console.error(`[Background] download failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message})):(console.log(`[Background] download created,ID:`,r),e({success:!0,message:t(`toolExec.downloadStarted`),downloadId:r,filename:n}))})})}function vr(e,n,r){let{url:i,active:a=!0,waitForLoad:o=!1,loadTimeout:s=15e3}=e,c=typeof a==`boolean`?a:String(a).toLowerCase()===`true`;return console.log(`[Background] opennewlabelpage:`,`url=`,i,`active=`,c,`waitForLoad=`,o,`loadTimeout=`,s),new Promise(e=>{chrome.tabs.create({url:i,active:c},a=>{if(chrome.runtime.lastError){console.error(`[Background] openlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n});return}r&&xe(r,a.id);let c=`后续操作此页的工具请传 tabId=${a.id}(不传则默认用此页)`;if(!o){e({success:!0,message:t(`toolExec.tabOpened`,{tabId:a.id,hint:c}),tabId:a.id,url:a.url,tool_call_id:n});return}let l=!1,u=Math.max(1e3,Math.floor(Number(s)||15e3)),d=setTimeout(()=>{l||(l=!0,chrome.tabs.onUpdated.removeListener(f),console.warn(`[Background] page loadtimeout:`,i,`(${u}ms)`),e({success:!0,message:t(`toolExec.tabOpenTimeout`,{timeout:u,hint:c}),tabId:a.id,url:a.url,loadTimedOut:!0,tool_call_id:n}))},u),f=(r,i,o)=>{if(r===a.id&&i.status===`complete`){if(l)return;l=!0,clearTimeout(d),chrome.tabs.onUpdated.removeListener(f),console.log(`[Background] page loadcomplete:`,o.url),e({success:!0,message:t(`toolExec.tabLoaded`,{url:o.url,hint:c}),tabId:a.id,url:o.url,tool_call_id:n})}};chrome.tabs.onUpdated.addListener(f)})})}function yr(e,n,r){let{tabId:i}=e,a=parseInt(i,10);return console.log(`[Background] switchlabelpage:`,`tabId=`,a),new Promise(e=>{chrome.tabs.update(a,{active:!0},n=>{chrome.runtime.lastError?(console.error(`[Background] switchlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message})):(r&&xe(r,n.id),e({success:!0,message:t(`toolExec.tabSwitched`,{tabId:n.id}),tabId:n.id,url:n.url}))})})}function br(e,n){let{tabId:r}=e,i=r===void 0?void 0:parseInt(r,10);return console.log(`[Background] closelabelpage:`,`tabId=`,i),new Promise(e=>{(i||null)===null?chrome.tabs.query({active:!0,currentWindow:!0},n=>{n&&n.length>0?chrome.tabs.remove(n[0].id,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message}):e({success:!0,message:t(`toolExec.tabClosed`)})}):e({success:!1,error:t(`toolExec.tabNotFound`)})}):chrome.tabs.remove(i,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message}):e({success:!0,message:t(`toolExec.tabClosedWithId`,{tabId:i})})})})}function xr(e,t){let{mode:n=`all`,includeUrl:r=!0,includeTitle:i=!0}=e;return console.log(`[Background] getlabelpage column table:`,`mode=`,n,`includeUrl=`,r,`includeTitle=`,i),new Promise(e=>{let t=n===`active`?{active:!0,currentWindow:!0}:{currentWindow:!0};chrome.tabs.query(t,t=>{if(chrome.runtime.lastError)console.error(`[Background] getlabelpage failed:`,chrome.runtime.lastError.message),e({success:!1,error:chrome.runtime.lastError.message});else{let n=t.map(e=>{let t={id:e.id};return r&&(t.url=e.url),i&&(t.title=e.title),t.active=e.active,t});e({success:!0,count:n.length,tabs:n})}})})}function Sr(e,n){return new Promise(r=>{let{action:i,name:a,value:o,domain:s,path:c=`/`,secure:l=!1,httpOnly:u=!1,expirationDate:d}=e,f=l===!0||l===`true`,p=u===!0||u===`true`,m=d===void 0?void 0:parseFloat(d);(e=>{chrome.tabs.query({active:!0,currentWindow:!0},t=>{if(t&&t[0]&&t[0].url)try{e(new URL(t[0].url).hostname)}catch{e(``)}else e(``)})})(e=>{let l=s||e;switch(i){case`get`:if(!a){r({success:!1,error:t(`toolExec.getRequiresName`),tool_call_id:n});return}chrome.cookies.get({url:`https://${l}`,name:a},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookie:e,tool_call_id:n})});break;case`set`:if(!a||o===void 0){r({success:!1,error:t(`toolExec.setRequiresNameValue`),tool_call_id:n});return}let e={url:`https://${l}`,name:a,value:o,path:c,secure:f,httpOnly:p,domain:l.startsWith(`.`)?l:`.`+l};m&&(e.expirationDate=m),chrome.cookies.set(e,e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookie:e,message:t(`toolExec.cookieSet`,{name:a}),tool_call_id:n})});break;case`remove`:if(!a){r({success:!1,error:t(`toolExec.removeRequiresName`),tool_call_id:n});return}chrome.cookies.remove({url:`https://${l}`,name:a},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):(r({success:!0,message:t(`toolExec.cookieDeleted`,{name:a}),tool_call_id:n}),Pn(`cookie_write`,`Delete cookie: ${a}`,{domain:l,name:a}))});break;case`list`:chrome.cookies.getAll({domain:l},e=>{chrome.runtime.lastError?r({success:!1,error:chrome.runtime.lastError.message,tool_call_id:n}):r({success:!0,cookies:e,total:e.length,tool_call_id:n})});break;default:r({success:!1,error:t(`toolExec.unknownAction`,{action:i}),tool_call_id:n})}})})}function Cr(e,n){let{taskDescription:r,subtasks:i=[],isComplex:a=!0,strategy:o=`sequential`}=e;if(console.log(`[Background] exec task planningtool:`,JSON.stringify(e)),!r)return Promise.resolve({success:!1,error:t(`toolExec.missingTaskDesc`),tool_call_id:n});if(!Array.isArray(i)||i.length===0)return Promise.resolve({success:!1,error:t(`toolExec.emptySubtasks`),tool_call_id:n});if(i.filter(e=>!e.id||!e.name||!e.description).length>0)return Promise.resolve({success:!1,error:t(`toolExec.invalidSubtaskStructure`),tool_call_id:n});let s={taskDescription:r,isComplex:a,strategy:o,totalSubtasks:i.length,estimatedTotalSteps:i.reduce((e,t)=>e+(t.estimatedSteps||1),0),subtasks:i.map(e=>({id:e.id,name:e.name,description:e.description,dependencies:e.dependencies||[],requiredTools:e.requiredTools||[],estimatedSteps:e.estimatedSteps||1})),planId:n||crypto.randomUUID(),createdAt:new Date().toISOString()};return Promise.resolve({success:!0,data:s,message:(()=>{let e=`📋 任务规划完成
295
295
 
296
296
  `;return e+=`**原始任务**: ${r}\n\n`,e+=`**任务复杂度**: ${a?`复杂任务(已拆解)`:`简单任务`}\n`,e+=`**执行策略**: ${o===`sequential`?`顺序执行`:o===`parallel`?`并行执行`:`条件执行`}\n`,e+=`**子任务数量**: ${i.length}\n\n`,e+=`**子任务列表**:
297
- `,i.forEach((t,n)=>{e+=`\n${n+1}. **${t.name}**\n`,e+=` - ID: ${t.id}\n`,e+=` - 描述: ${t.description}\n`,t.dependencies&&t.dependencies.length>0&&(e+=` - 依赖: ${t.dependencies.join(`, `)}\n`),t.requiredTools&&t.requiredTools.length>0&&(e+=` - 所需工具: ${t.requiredTools.join(`, `)}\n`),e+=` - 预估步骤: ${t.estimatedSteps||1}\n`}),e})(),tool_call_id:n})}function Sr(e,n){let{site:r}=e;return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}let a=i[0],o;try{o=new URL(a.url).origin}catch{e({success:!1,error:t(`toolExec.cannotParseTabUrl`),tool_call_id:n});return}let s=r||o,c=[],l=[];l.push(new Promise(e=>{chrome.cookies.getAll({},t=>{if(chrome.runtime.lastError){console.warn(`[Background] get cookies failed:`,chrome.runtime.lastError.message),e();return}let n=t.filter(e=>{let t=e.domain.startsWith(`.`)?e.domain.substring(1):e.domain;try{let e=new URL(s).hostname;return e.endsWith(t)||t.endsWith(e)}catch{return!1}});if(n.length===0){e();return}let r=0;n.forEach(t=>{let i=`${t.secure?`https:`:`http:`}//${t.domain.replace(/^\./,``)}${t.path}`;chrome.cookies.remove({url:i,name:t.name},()=>{r++,r===n.length&&(c.push(`cookies`),e())})})})})),l.push(new Promise(e=>{chrome.tabs.sendMessage(a.id,{type:`CLEAR_PAGE_DATA`,storageTypes:[`localStorage`,`sessionStorage`]},t=>{if(chrome.runtime.lastError){console.warn(`[Background] send CLEAR_PAGE_DATA message failed:`,chrome.runtime.lastError.message);let t=(chrome.runtime.getManifest().content_scripts?.[0]?.js||[]).find(e=>e.includes(`content-`))||`content.js`;chrome.scripting.executeScript({target:{tabId:a.id},files:[t]}).then(()=>{setTimeout(()=>{chrome.tabs.sendMessage(a.id,{type:`CLEAR_PAGE_DATA`,storageTypes:[`localStorage`,`sessionStorage`]},t=>{chrome.runtime.lastError||t?.cleared&&c.push(...t.cleared),e()})},500)}).catch(()=>{e()})}else t?.cleared&&c.push(...t.cleared),e()})})),Promise.allSettled(l).then(()=>{let t=[...new Set(c)];Mn(`page_data_clear`,`Clear page data: ${s}`,{site:s,cleared:t}),e({success:!0,cleared:t,site:s,tool_call_id:n})})})})}function Cr(e,n){let{direction:r=`back`}=e;return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}let a=i[0].id;r===`forward`?chrome.tabs.goForward(a,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,direction:r,tool_call_id:n}):e({success:!0,direction:r,tool_call_id:n})}):chrome.tabs.goBack(a,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,direction:r,tool_call_id:n}):e({success:!0,direction:r,tool_call_id:n})})})})}function wr(e,n){let{tabId:r,bypassCache:i=!1}=e,a=r===void 0?void 0:parseInt(r,10);return new Promise(e=>{let r=t=>{chrome.tabs.reload(t,{bypassCache:!!i},()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,tabId:t,bypassCache:!!i,tool_call_id:n}):e({success:!0,tabId:t,bypassCache:!!i,tool_call_id:n})})};a===void 0?chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}r(i[0].id)}):r(a)})}async function Tr(e,n,r=null){let{action:i=`preview`,html:a,title:o,description:s,prototypeId:c}=e;if(i===`get`){if(console.log(`[Background] exec get UI prototype:`,`prototypeId=`,c),!c||!c.trim())return{success:!1,error:t(`toolExec.missingPrototypeId`),tool_call_id:n};try{let e=await v(c.trim());return e?(console.log(`[Background] get prototype successful:`,e.title,`HTMLlength:`,e.html?.length),{success:!0,message:t(`toolExec.prototypeCodeLoaded`,{title:e.title}),prototypeId:e.id,title:e.title,description:e.description||``,html:e.html,tool_call_id:n}):{success:!1,error:t(`toolExec.prototypeNotFound`,{id:c}),tool_call_id:n}}catch(e){return console.error(`[Background] get UI prototype failed:`,e),{success:!1,error:t(`toolExec.fetchFailed`,{error:e.message}),tool_call_id:n}}}if(console.log(`[Background] exec UI prototype preview:`,`title=`,o,`sessionId=`,r),!a||!a.trim())return{success:!1,error:t(`toolExec.missingHtmlParam`),tool_call_id:n};if(!o||!o.trim())return{success:!1,error:t(`toolExec.missingTitleParam`),tool_call_id:n};try{let e=`proto_`+Date.now()+`_`+Math.random().toString(36).substr(2,9),i={id:e,title:o.trim(),description:s||``,html:a.trim(),sessionId:r||null,createdAt:Date.now()};if(!await oe(i))return{success:!1,error:t(`toolExec.savePrototypeFailed`),tool_call_id:n};console.log(`[Background] UI prototype saved,ID:`,e);let c=!1,l=null,u=!1;try{if((await U()).connected){let t=await Ne(`prototypes/${e}/index.html`,a.trim());if(t.success){if(l=t.path,console.log(`[Background] prototype written Agent:`,l),await oe({...i,localPath:l}),await st()){let e=await q(l);e.success?(c=!0,console.log(`[Background] prototype inagent-side browseropen:`,l)):console.warn(`[Background] agent-side browseropen failed:`,e.error)}else u=!0,console.log(`[Background] agent is remote,in browser sidelabelpageopenprototype`)}else console.warn(`[Background] Agent filewrite failed:`,t.error)}}catch(e){console.warn(`[Background] Agent prototype write/open failed,fallback to Side Panel:`,e.message)}return chrome.runtime.sendMessage({type:`SHOW_UI_PROTOTYPE`,data:{prototypeId:e,title:i.title,description:i.description,localOpened:c,localPath:l,isRemoteAgent:u}}).catch(()=>{}),{success:!0,message:c?`UI 原型 "${o}" 已创建并在代理端浏览器打开`:`UI 原型 "${o}" 已创建`,prototypeId:e,localOpened:c,isRemoteAgent:u,localPath:l,tool_call_id:n}}catch(e){return console.error(`[Background] exec UI prototype preview failed:`,e),{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}var Er=new Map;function Dr(){Er.clear()}async function Or(e,n){let{action:r,name:i,params:a={}}=e;if(!i)return{success:!1,error:t(`toolExec.missingNameParam`),tool_call_id:n};if(r===`run`)try{let e=await qe(i,a);return e.success?{success:!0,content:e.message||`Skill "${i}" 执行完成`,execId:e.execId,partial:e.partial||!1,results:e.results,tool_call_id:n}:{success:!1,error:e.error||t(`toolExec.skillExecFailed`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.skillExecException`,{error:e.message}),tool_call_id:n}}let o=Er.get(i);if(o&&Date.now()-o.timestamp<6e4)return{success:!0,content:t(`toolExec.skillLoadedCached`,{name:i,prompt:o.prompt}),skill:o.skill,tool_call_id:n};try{let e=await et(i);return e.success?(Er.set(i,{timestamp:Date.now(),prompt:e.prompt,skill:e.skill}),{success:!0,content:t(`toolExec.skillLoaded`,{name:i,prompt:e.prompt}),skill:e.skill,tool_call_id:n}):{success:!1,error:e.error||t(`toolExec.skillLoadFailed`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.skillLoadException`,{error:e.message}),tool_call_id:n}}}async function kr(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await je(r);return i.success?{success:!0,content:i.content,size:i.size,path:i.path,tool_call_id:n}:{success:!1,error:i.error,tool_call_id:n}}async function Ar(e,n,r){let{timeout:i=3e4,waitUntil:a=`load`,tabId:o}=e;try{let e=r?Se(r):null,s=o||e||await Kn();return s?(console.log(`[Background] waitingpage navigationcomplete: tabId=`,s,`waitUntil=`,a,`timeout=`,i),new Promise(e=>{let r=!1,o=setTimeout(()=>{r||(r=!0,chrome.tabs.onUpdated.removeListener(c),console.warn(`[Background] waitingnavigatetimeout:`,i+`ms`),e({success:!1,error:t(`toolExec.navWaitTimeout`,{timeout:i}),tool_call_id:n}))},i);chrome.tabs.get(s,i=>{if(chrome.runtime.lastError||!i){clearTimeout(o),r||(r=!0,e({success:!1,error:t(`toolExec.tabUnavailable`),tool_call_id:n}));return}if(i.status===`complete`&&a===`load`){clearTimeout(o),r||(r=!0,e({success:!0,status:`complete`,url:i.url,message:t(`toolExec.pageLoaded`),tool_call_id:n}));return}if(i.status===`complete`&&a===`domcontentloaded`){clearTimeout(o),r||(r=!0,e({success:!0,status:`complete`,url:i.url,message:t(`toolExec.domReady`),tool_call_id:n}));return}});let c=(i,l,u)=>{i===s&&(r||(a===`networkidle`?l.status===`complete`&&setTimeout(()=>{r||(r=!0,clearTimeout(o),chrome.tabs.onUpdated.removeListener(c),e({success:!0,status:`complete`,url:u.url,message:t(`toolExec.networkIdle`),tool_call_id:n}))},500):l.status===`complete`?(r=!0,clearTimeout(o),chrome.tabs.onUpdated.removeListener(c),e({success:!0,status:`complete`,url:u.url,message:t(`toolExec.pageLoadComplete`),tool_call_id:n})):l.status))};chrome.tabs.onUpdated.addListener(c)})):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}async function jr(e,n){let{path:r,content:i}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};if(i==null)return{success:!1,error:t(`toolExec.missingContent`),tool_call_id:n};let a=await Ne(r,i);return a.success?(Mn(`file_write`,`Write file: ${a.path}`,{path:a.path,size:a.size}),{success:!0,message:t(`toolExec.fileWritten`,{path:a.path,size:a.size}),path:a.path,size:a.size,tool_call_id:n}):{success:!1,error:a.error,tool_call_id:n}}async function Mr(e,n){let{path:r}=e,i=await Pe(r||`.`);if(i.success){let e=i.entries?.filter(e=>e.type===`file`)||[],r=i.entries?.filter(e=>e.type===`directory`)||[];return{success:!0,content:`${t(`toolExec.dirContent`,{path:i.path,count:i.entries?.length||0})}\n 📁 ${r.length} 个目录\n 📄 ${e.length} 个文件\n\n`+(i.entries||[]).map(e=>` ${e.type===`directory`?`📁`:`📄`} ${e.name}${e.type===`file`?` (${e.size} 字节)`:``}`).join(`
298
- `),path:i.path,entries:i.entries,tool_call_id:n}}return{success:!1,error:i.error,tool_call_id:n}}async function Nr(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await Fe(r);if(i.success){let e=t(i.isDir?`toolExec.typeDirectory`:`toolExec.typeFile`);return Mn(`file_delete`,`Delete ${i.isDir?`directory`:`file`}: ${i.path}`,{path:i.path,isDir:i.isDir}),{success:!0,message:t(`toolExec.trashDeleted`,{typeLabel:e,path:i.path}),path:i.path,isDir:i.isDir,tool_call_id:n}}return{success:!1,error:i.error,tool_call_id:n}}async function Pr(e,n){let r=await at();if(r.success){let i=r.entries||[];if(e.type===`file`?i=i.filter(e=>!e.isDir):e.type===`directory`&&(i=i.filter(e=>e.isDir)),e.hours&&typeof e.hours==`number`&&e.hours>0){let t=Date.now()-e.hours*3600*1e3;i=i.filter(e=>e.deletedAt>=t)}if(i.length===0){let r=e.type===`file`?`文件`:e.type===`directory`?`目录`:`项目`;return{success:!0,content:t(`toolExec.trashEmpty`,{typeHint:r}),entries:[],tool_call_id:n}}let a=Date.now();return{success:!0,content:`回收站中共有 ${i.length} 个项目(7天后自动清理):\n\n`+i.map((e,t)=>{let n=Math.round((a-e.deletedAt)/36e5),r=n<1?`刚刚`:n<24?`${n}小时前`:`${Math.round(n/24)}天前`,i=e.isDir?`📁 目录`:`📄 文件`;return` ${t+1}. trashId: ${e.id}\n ${i}: ${e.name}\n 原路径: ${e.originalPath}\n 大小: ${e.size} 字节 · ${r}`}).join(`
297
+ `,i.forEach((t,n)=>{e+=`\n${n+1}. **${t.name}**\n`,e+=` - ID: ${t.id}\n`,e+=` - 描述: ${t.description}\n`,t.dependencies&&t.dependencies.length>0&&(e+=` - 依赖: ${t.dependencies.join(`, `)}\n`),t.requiredTools&&t.requiredTools.length>0&&(e+=` - 所需工具: ${t.requiredTools.join(`, `)}\n`),e+=` - 预估步骤: ${t.estimatedSteps||1}\n`}),e})(),tool_call_id:n})}function wr(e,n){let{site:r}=e;return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}let a=i[0],o;try{o=new URL(a.url).origin}catch{e({success:!1,error:t(`toolExec.cannotParseTabUrl`),tool_call_id:n});return}let s=r||o,c=[],l=[];l.push(new Promise(e=>{chrome.cookies.getAll({},t=>{if(chrome.runtime.lastError){console.warn(`[Background] get cookies failed:`,chrome.runtime.lastError.message),e();return}let n=t.filter(e=>{let t=e.domain.startsWith(`.`)?e.domain.substring(1):e.domain;try{let e=new URL(s).hostname;return e.endsWith(t)||t.endsWith(e)}catch{return!1}});if(n.length===0){e();return}let r=0;n.forEach(t=>{let i=`${t.secure?`https:`:`http:`}//${t.domain.replace(/^\./,``)}${t.path}`;chrome.cookies.remove({url:i,name:t.name},()=>{r++,r===n.length&&(c.push(`cookies`),e())})})})})),l.push(new Promise(e=>{chrome.tabs.sendMessage(a.id,{type:`CLEAR_PAGE_DATA`,storageTypes:[`localStorage`,`sessionStorage`]},t=>{if(chrome.runtime.lastError){console.warn(`[Background] send CLEAR_PAGE_DATA message failed:`,chrome.runtime.lastError.message);let t=(chrome.runtime.getManifest().content_scripts?.[0]?.js||[]).find(e=>e.includes(`content-`))||`content.js`;chrome.scripting.executeScript({target:{tabId:a.id},files:[t]}).then(()=>{setTimeout(()=>{chrome.tabs.sendMessage(a.id,{type:`CLEAR_PAGE_DATA`,storageTypes:[`localStorage`,`sessionStorage`]},t=>{chrome.runtime.lastError||t?.cleared&&c.push(...t.cleared),e()})},500)}).catch(()=>{e()})}else t?.cleared&&c.push(...t.cleared),e()})})),Promise.allSettled(l).then(()=>{let t=[...new Set(c)];Pn(`page_data_clear`,`Clear page data: ${s}`,{site:s,cleared:t}),e({success:!0,cleared:t,site:s,tool_call_id:n})})})})}function Tr(e,n){let{direction:r=`back`}=e;return new Promise(e=>{chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}let a=i[0].id;r===`forward`?chrome.tabs.goForward(a,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,direction:r,tool_call_id:n}):e({success:!0,direction:r,tool_call_id:n})}):chrome.tabs.goBack(a,()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,direction:r,tool_call_id:n}):e({success:!0,direction:r,tool_call_id:n})})})})}function Er(e,n){let{tabId:r,bypassCache:i=!1}=e,a=r===void 0?void 0:parseInt(r,10);return new Promise(e=>{let r=t=>{chrome.tabs.reload(t,{bypassCache:!!i},()=>{chrome.runtime.lastError?e({success:!1,error:chrome.runtime.lastError.message,tabId:t,bypassCache:!!i,tool_call_id:n}):e({success:!0,tabId:t,bypassCache:!!i,tool_call_id:n})})};a===void 0?chrome.tabs.query({active:!0,currentWindow:!0},i=>{if(chrome.runtime.lastError||!i||i.length===0){e({success:!1,error:t(`toolExec.cannotGetCurrentTab`),tool_call_id:n});return}r(i[0].id)}):r(a)})}async function Dr(e,n,r=null){let{action:i=`preview`,html:a,title:o,description:s,prototypeId:c}=e;if(i===`get`){if(console.log(`[Background] exec get UI prototype:`,`prototypeId=`,c),!c||!c.trim())return{success:!1,error:t(`toolExec.missingPrototypeId`),tool_call_id:n};try{let e=await v(c.trim());return e?(console.log(`[Background] get prototype successful:`,e.title,`HTMLlength:`,e.html?.length),{success:!0,message:t(`toolExec.prototypeCodeLoaded`,{title:e.title}),prototypeId:e.id,title:e.title,description:e.description||``,html:e.html,tool_call_id:n}):{success:!1,error:t(`toolExec.prototypeNotFound`,{id:c}),tool_call_id:n}}catch(e){return console.error(`[Background] get UI prototype failed:`,e),{success:!1,error:t(`toolExec.fetchFailed`,{error:e.message}),tool_call_id:n}}}if(console.log(`[Background] exec UI prototype preview:`,`title=`,o,`sessionId=`,r),!a||!a.trim())return{success:!1,error:t(`toolExec.missingHtmlParam`),tool_call_id:n};if(!o||!o.trim())return{success:!1,error:t(`toolExec.missingTitleParam`),tool_call_id:n};try{let e=`proto_`+Date.now()+`_`+Math.random().toString(36).substr(2,9),i={id:e,title:o.trim(),description:s||``,html:a.trim(),sessionId:r||null,createdAt:Date.now()};if(!await oe(i))return{success:!1,error:t(`toolExec.savePrototypeFailed`),tool_call_id:n};console.log(`[Background] UI prototype saved,ID:`,e);let c=!1,l=null,u=!1;try{if((await U()).connected){let t=await Ne(`prototypes/${e}/index.html`,a.trim());if(t.success){if(l=t.path,console.log(`[Background] prototype written Agent:`,l),await oe({...i,localPath:l}),await st()){let e=await q(l);e.success?(c=!0,console.log(`[Background] prototype inagent-side browseropen:`,l)):console.warn(`[Background] agent-side browseropen failed:`,e.error)}else u=!0,console.log(`[Background] agent is remote,in browser sidelabelpageopenprototype`)}else console.warn(`[Background] Agent filewrite failed:`,t.error)}}catch(e){console.warn(`[Background] Agent prototype write/open failed,fallback to Side Panel:`,e.message)}return chrome.runtime.sendMessage({type:`SHOW_UI_PROTOTYPE`,data:{prototypeId:e,title:i.title,description:i.description,localOpened:c,localPath:l,isRemoteAgent:u}}).catch(()=>{}),{success:!0,message:c?`UI 原型 "${o}" 已创建并在代理端浏览器打开`:`UI 原型 "${o}" 已创建`,prototypeId:e,localOpened:c,isRemoteAgent:u,localPath:l,tool_call_id:n}}catch(e){return console.error(`[Background] exec UI prototype preview failed:`,e),{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}var Or=new Map;function kr(){Or.clear()}async function Ar(e,n){let{action:r,name:i,params:a={}}=e;if(!i)return{success:!1,error:t(`toolExec.missingNameParam`),tool_call_id:n};if(r===`run`)try{let e=await qe(i,a);return e.success?{success:!0,content:e.message||`Skill "${i}" 执行完成`,execId:e.execId,partial:e.partial||!1,results:e.results,tool_call_id:n}:{success:!1,error:e.error||t(`toolExec.skillExecFailed`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.skillExecException`,{error:e.message}),tool_call_id:n}}let o=Or.get(i);if(o&&Date.now()-o.timestamp<6e4)return{success:!0,content:t(`toolExec.skillLoadedCached`,{name:i,prompt:o.prompt}),skill:o.skill,tool_call_id:n};try{let e=await et(i);return e.success?(Or.set(i,{timestamp:Date.now(),prompt:e.prompt,skill:e.skill}),{success:!0,content:t(`toolExec.skillLoaded`,{name:i,prompt:e.prompt}),skill:e.skill,tool_call_id:n}):{success:!1,error:e.error||t(`toolExec.skillLoadFailed`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.skillLoadException`,{error:e.message}),tool_call_id:n}}}async function jr(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await je(r);return i.success?{success:!0,content:i.content,size:i.size,path:i.path,tool_call_id:n}:{success:!1,error:i.error,tool_call_id:n}}async function Mr(e,n,r){let{timeout:i=3e4,waitUntil:a=`load`,tabId:o}=e;try{let e=r?Se(r):null,s=o||e||await Jn();return s?(console.log(`[Background] waitingpage navigationcomplete: tabId=`,s,`waitUntil=`,a,`timeout=`,i),new Promise(e=>{let r=!1,o=setTimeout(()=>{r||(r=!0,chrome.tabs.onUpdated.removeListener(c),console.warn(`[Background] waitingnavigatetimeout:`,i+`ms`),e({success:!1,error:t(`toolExec.navWaitTimeout`,{timeout:i}),tool_call_id:n}))},i);chrome.tabs.get(s,i=>{if(chrome.runtime.lastError||!i){clearTimeout(o),r||(r=!0,e({success:!1,error:t(`toolExec.tabUnavailable`),tool_call_id:n}));return}if(i.status===`complete`&&a===`load`){clearTimeout(o),r||(r=!0,e({success:!0,status:`complete`,url:i.url,message:t(`toolExec.pageLoaded`),tool_call_id:n}));return}if(i.status===`complete`&&a===`domcontentloaded`){clearTimeout(o),r||(r=!0,e({success:!0,status:`complete`,url:i.url,message:t(`toolExec.domReady`),tool_call_id:n}));return}});let c=(i,l,u)=>{i===s&&(r||(a===`networkidle`?l.status===`complete`&&setTimeout(()=>{r||(r=!0,clearTimeout(o),chrome.tabs.onUpdated.removeListener(c),e({success:!0,status:`complete`,url:u.url,message:t(`toolExec.networkIdle`),tool_call_id:n}))},500):l.status===`complete`?(r=!0,clearTimeout(o),chrome.tabs.onUpdated.removeListener(c),e({success:!0,status:`complete`,url:u.url,message:t(`toolExec.pageLoadComplete`),tool_call_id:n})):l.status))};chrome.tabs.onUpdated.addListener(c)})):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.executionFailed`,{error:e.message}),tool_call_id:n}}}async function Nr(e,n){let{path:r,content:i}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};if(i==null)return{success:!1,error:t(`toolExec.missingContent`),tool_call_id:n};let a=await Ne(r,i);return a.success?(Pn(`file_write`,`Write file: ${a.path}`,{path:a.path,size:a.size}),{success:!0,message:t(`toolExec.fileWritten`,{path:a.path,size:a.size}),path:a.path,size:a.size,tool_call_id:n}):{success:!1,error:a.error,tool_call_id:n}}async function Pr(e,n){let{path:r}=e,i=await Pe(r||`.`);if(i.success){let e=i.entries?.filter(e=>e.type===`file`)||[],r=i.entries?.filter(e=>e.type===`directory`)||[];return{success:!0,content:`${t(`toolExec.dirContent`,{path:i.path,count:i.entries?.length||0})}\n 📁 ${r.length} 个目录\n 📄 ${e.length} 个文件\n\n`+(i.entries||[]).map(e=>` ${e.type===`directory`?`📁`:`📄`} ${e.name}${e.type===`file`?` (${e.size} 字节)`:``}`).join(`
298
+ `),path:i.path,entries:i.entries,tool_call_id:n}}return{success:!1,error:i.error,tool_call_id:n}}async function Fr(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await Fe(r);if(i.success){let e=t(i.isDir?`toolExec.typeDirectory`:`toolExec.typeFile`);return Pn(`file_delete`,`Delete ${i.isDir?`directory`:`file`}: ${i.path}`,{path:i.path,isDir:i.isDir}),{success:!0,message:t(`toolExec.trashDeleted`,{typeLabel:e,path:i.path}),path:i.path,isDir:i.isDir,tool_call_id:n}}return{success:!1,error:i.error,tool_call_id:n}}async function Ir(e,n){let r=await at();if(r.success){let i=r.entries||[];if(e.type===`file`?i=i.filter(e=>!e.isDir):e.type===`directory`&&(i=i.filter(e=>e.isDir)),e.hours&&typeof e.hours==`number`&&e.hours>0){let t=Date.now()-e.hours*3600*1e3;i=i.filter(e=>e.deletedAt>=t)}if(i.length===0){let r=e.type===`file`?`文件`:e.type===`directory`?`目录`:`项目`;return{success:!0,content:t(`toolExec.trashEmpty`,{typeHint:r}),entries:[],tool_call_id:n}}let a=Date.now();return{success:!0,content:`回收站中共有 ${i.length} 个项目(7天后自动清理):\n\n`+i.map((e,t)=>{let n=Math.round((a-e.deletedAt)/36e5),r=n<1?`刚刚`:n<24?`${n}小时前`:`${Math.round(n/24)}天前`,i=e.isDir?`📁 目录`:`📄 文件`;return` ${t+1}. trashId: ${e.id}\n ${i}: ${e.name}\n 原路径: ${e.originalPath}\n 大小: ${e.size} 字节 · ${r}`}).join(`
299
299
 
300
- `),entries:i,tool_call_id:n}}return{success:!1,error:r.error,tool_call_id:n}}async function Fr(e,n){let{trashId:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingTrashId`),tool_call_id:n};let i=await ot(r);return i.success?(Mn(`file_restore`,`Restore file: ${i.restoredPath}`,{trashId:r,restoredPath:i.restoredPath}),{success:!0,message:t(`toolExec.trashRestored`,{path:i.restoredPath}),restoredPath:i.restoredPath,tool_call_id:n}):{success:!1,error:i.error,tool_call_id:n}}async function Ir(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await Ie(r);if(!i.success)return{success:!1,error:i.error,tool_call_id:n};try{let e=`data:${i.mimeType||`application/octet-stream`};base64,${i.content}`,t=await new Promise((t,n)=>{chrome.downloads.download({url:e,filename:i.name,saveAs:!1},e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})});return{success:!0,content:i.type===`directory`?`目录 "${r}" 已打包为 ${i.name} 并开始下载 (${Un(i.size)})`:`文件 "${i.name}" 已开始下载 (${Un(i.size)})`,name:i.name,size:i.size,type:i.type,downloadId:t,tool_call_id:n}}catch(e){return{success:!1,error:`下载触发失败: ${e.message}`,tool_call_id:n}}}async function Lr(e,t,n){let r,i=new Promise(e=>{r=()=>e(!0)});e&&X.set(e,{execId:null,ws:null,toolCallId:t,resolve:r});try{let e=await Promise.race([n,i]);return e===!0?{cancelled:!0}:{cancelled:!1,value:e}}finally{e&&X.delete(e)}}async function Rr(e,n,r){let{command:i,cwd:a,force:o,timeoutMs:s}=e;if(!i)return{success:!1,error:t(`toolExec.missingCommand`),tool_call_id:n};let c=await z(),l=!!o||!c.reactConfig.toolConfirmationEnabled,u=c.streamConfig?.streamEnabled!==!1,d=typeof s==`number`&&s>0?Math.max(5e3,s):c.reactConfig.toolTimeout,f=Math.max(12e4,Math.min(d*.8,6e5));if(u){let e=await ze(i,a,l);if(e.level===`deny`)return{success:!1,error:e.error||t(`toolExec.commandExecDenied`),level:`deny`,tool_call_id:n};if(!e.success&&!e.level)return{success:!1,error:e.error||t(`toolExec.commandExecFailed`),tool_call_id:n};if(e.level===`confirm`)return{success:!0,level:`confirm`,message:t(`toolExec.commandNeedConfirm`,{reason:e.reason,command:i}),reason:e.reason,command:i,cwd:a,tool_call_id:n};let{execId:o,wsUrl:s}=e,c=``,u=``,p=null,m=!1,h=null,g=!1,_=!1,v=!1,y=async e=>{if(h)try{h.close()}catch{}if(!g&&o){_=!0;try{await Ve(o),console.log(`[AgentExec] terminated commandprocess:`,o,e?`(origin reason : ${e})`:``)}catch(e){console.warn(`[AgentExec] terminate commandprocess failed:`,e.message)}}};try{if(h=await He(s,e=>{e.type===`stdout`?(c+=e.data,ut(r,o,n,`stdout`,e.data)):e.type===`stderr`?(u+=e.data,ut(r,o,n,`stderr`,e.data)):e.type===`exit`&&(p=e.exitCode,m=e.killed,g=!0,J(r,o,n,p))},()=>{},e=>{console.warn(`[AgentExec] WebSocket error:`,e)},f),!h)throw Error(`创建 WebSocket 连接失败`);r&&X.set(r,{execId:o,ws:h,toolCallId:n}),await new Promise((e,t)=>{if(r){let t=X.get(r);t&&(t.resolve=e)}if(g){e();return}let i=Date.now(),a=null,s=Date.now(),c=0,l=!1,u=setInterval(()=>_n.has(r)?(console.warn(`[AgentExec] cancelfallbacktimeouttrigger,force resolve:`,r),p=-1,J(r,o,n,-1),clearInterval(u),clearTimeout(m),e(),!0):!1,500),m=setTimeout(()=>{console.error(`[AgentExec] globalhard timeouttrigger (120s ),force killcommand:`,r),clearInterval(u),clearTimeout(a),p=-1,J(r,o,n,-1),y(`命令执行超时`).then(()=>{t(Error(`命令执行超时`))})},12e4),_=n=>{l||(l=!0,clearTimeout(a),clearInterval(u),clearTimeout(m),n===`resolve`?e():t(n))},b=()=>{a&&clearTimeout(a);let e=Date.now(),t=e-i,n=e-s,r=d*(1+c);if(n>=f){if(v=!0,console.warn(`[AgentExec] command idletimeout (`,Math.round(n/1e3),`s no output), possibly issuspended service,keep backgroundprocess`),h)try{h.close()}catch{}a&&clearTimeout(a),_(`resolve`);return}if(t>=r){if(c<5){c++;let e=d*(1+c);console.log(`[AgentExec] command stillexec ,auto extendtimeout (${c} times,total count${Math.round(e/1e3)}s)`),b();return}{let e=`命令执行总超时(${Math.round(r/1e3)}s,已延长5次)`;console.warn(`[AgentExec]`,e),y(e).then(()=>{_(Error(e))});return}}let o=r-t;a=setTimeout(b,Math.min(f,o))};b();let x=h.onmessage;h.onmessage=e=>{x(e);try{let t=JSON.parse(e.data);if(t.type===`stdout`||t.type===`stderr`)s=Date.now(),b();else if(t.type===`exit`){g=!0,a&&clearTimeout(a);try{h.close()}catch{}_(`resolve`)}else if(t.type===`error`){console.warn(`[AgentExec] Agent return error:`,t.error,`execId:`,t.execId),a&&clearTimeout(a);try{h.close()}catch{}y(t.error||`Agent 执行错误`).then(()=>{_(Error(t.error||`Agent 端命令执行失败`))})}}catch{}};let S=h.onclose;h.onclose=()=>{if(a&&clearTimeout(a),X.delete(r),_n.has(r)){p=-1,J(r,o,n,-1),_(`resolve`);return}if(S&&S(),v){_(`resolve`);return}g?_(`resolve`):(p=-1,J(r,o,n,-1),y(`WebSocket 连接意外关闭`).then(()=>{_(Error(`命令执行中断:WebSocket 连接意外关闭`))}))};let C=h.onerror;h.onerror=e=>{if(a&&clearTimeout(a),X.delete(r),_n.has(r)){p=-1,J(r,o,n,-1),_(`resolve`);return}C&&C(e),y(e.message).then(()=>{_(e)})}})}catch(e){let s=e.message||(e instanceof Error?`未知错误`:String(e));if(console.warn(`[AgentExec] WebSocket streaming failed:`,s),h)try{h.close()}catch{}if(X.delete(r),_n.has(r))return J(r,o,n,-1),Mn(`command_exec`,`Command cancelled: ${i}`,{command:i,cwd:a,exitCode:-1,error:t(`toolExec.userCancelled`)}),{success:!1,level:`allow`,execId:o,exitCode:-1,stdout:c,stderr:u,killed:!0,content:`${t(`toolExec.commandCancelledWithOutput`)}${c?"stdout:\n```\n"+c+"\n```":``}${u?`
300
+ `),entries:i,tool_call_id:n}}return{success:!1,error:r.error,tool_call_id:n}}async function Lr(e,n){let{trashId:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingTrashId`),tool_call_id:n};let i=await ot(r);return i.success?(Pn(`file_restore`,`Restore file: ${i.restoredPath}`,{trashId:r,restoredPath:i.restoredPath}),{success:!0,message:t(`toolExec.trashRestored`,{path:i.restoredPath}),restoredPath:i.restoredPath,tool_call_id:n}):{success:!1,error:i.error,tool_call_id:n}}async function Rr(e,n){let{path:r}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let i=await Ie(r);if(!i.success)return{success:!1,error:i.error,tool_call_id:n};try{let e=`data:${i.mimeType||`application/octet-stream`};base64,${i.content}`,t=await new Promise((t,n)=>{chrome.downloads.download({url:e,filename:i.name,saveAs:!1},e=>{chrome.runtime.lastError?n(Error(chrome.runtime.lastError.message)):t(e)})});return{success:!0,content:i.type===`directory`?`目录 "${r}" 已打包为 ${i.name} 并开始下载 (${Gn(i.size)})`:`文件 "${i.name}" 已开始下载 (${Gn(i.size)})`,name:i.name,size:i.size,type:i.type,downloadId:t,tool_call_id:n}}catch(e){return{success:!1,error:`下载触发失败: ${e.message}`,tool_call_id:n}}}async function zr(e,t,n){let r,i=new Promise(e=>{r=()=>e(!0)});e&&X.set(e,{execId:null,ws:null,toolCallId:t,resolve:r});try{let e=await Promise.race([n,i]);return e===!0?{cancelled:!0}:{cancelled:!1,value:e}}finally{e&&X.delete(e)}}async function Br(e,n,r){let{command:i,cwd:a,force:o,timeoutMs:s}=e;if(!i)return{success:!1,error:t(`toolExec.missingCommand`),tool_call_id:n};let c=await z(),l=!!o||!c.reactConfig.toolConfirmationEnabled,u=c.streamConfig?.streamEnabled!==!1,d=typeof s==`number`&&s>0?Math.max(5e3,s):c.reactConfig.toolTimeout,f=Math.max(12e4,Math.min(d*.8,6e5));if(u){let e=await ze(i,a,l);if(e.level===`deny`)return{success:!1,error:e.error||t(`toolExec.commandExecDenied`),level:`deny`,tool_call_id:n};if(!e.success&&!e.level)return{success:!1,error:e.error||t(`toolExec.commandExecFailed`),tool_call_id:n};if(e.level===`confirm`)return{success:!0,level:`confirm`,message:t(`toolExec.commandNeedConfirm`,{reason:e.reason,command:i}),reason:e.reason,command:i,cwd:a,tool_call_id:n};let{execId:o,wsUrl:s}=e,c=``,u=``,p=null,m=!1,h=null,g=!1,_=!1,v=!1,y=async e=>{if(h)try{h.close()}catch{}if(!g&&o){_=!0;try{await Ve(o),console.log(`[AgentExec] terminated commandprocess:`,o,e?`(origin reason : ${e})`:``)}catch(e){console.warn(`[AgentExec] terminate commandprocess failed:`,e.message)}}};try{if(h=await He(s,e=>{e.type===`stdout`?(c+=e.data,ut(r,o,n,`stdout`,e.data)):e.type===`stderr`?(u+=e.data,ut(r,o,n,`stderr`,e.data)):e.type===`exit`&&(p=e.exitCode,m=e.killed,g=!0,J(r,o,n,p))},()=>{},e=>{console.warn(`[AgentExec] WebSocket error:`,e)},f),!h)throw Error(`创建 WebSocket 连接失败`);r&&X.set(r,{execId:o,ws:h,toolCallId:n}),await new Promise((e,t)=>{if(r){let t=X.get(r);t&&(t.resolve=e)}if(g){e();return}let i=Date.now(),a=null,s=Date.now(),c=0,l=!1,u=setInterval(()=>yn.has(r)?(console.warn(`[AgentExec] cancelfallbacktimeouttrigger,force resolve:`,r),p=-1,J(r,o,n,-1),clearInterval(u),clearTimeout(m),e(),!0):!1,500),m=setTimeout(()=>{console.error(`[AgentExec] globalhard timeouttrigger (120s ),force killcommand:`,r),clearInterval(u),clearTimeout(a),p=-1,J(r,o,n,-1),y(`命令执行超时`).then(()=>{t(Error(`命令执行超时`))})},12e4),_=n=>{l||(l=!0,clearTimeout(a),clearInterval(u),clearTimeout(m),n===`resolve`?e():t(n))},b=()=>{a&&clearTimeout(a);let e=Date.now(),t=e-i,n=e-s,r=d*(1+c);if(n>=f){if(v=!0,console.warn(`[AgentExec] command idletimeout (`,Math.round(n/1e3),`s no output), possibly issuspended service,keep backgroundprocess`),h)try{h.close()}catch{}a&&clearTimeout(a),_(`resolve`);return}if(t>=r){if(c<5){c++;let e=d*(1+c);console.log(`[AgentExec] command stillexec ,auto extendtimeout (${c} times,total count${Math.round(e/1e3)}s)`),b();return}{let e=`命令执行总超时(${Math.round(r/1e3)}s,已延长5次)`;console.warn(`[AgentExec]`,e),y(e).then(()=>{_(Error(e))});return}}let o=r-t;a=setTimeout(b,Math.min(f,o))};b();let x=h.onmessage;h.onmessage=e=>{x(e);try{let t=JSON.parse(e.data);if(t.type===`stdout`||t.type===`stderr`)s=Date.now(),b();else if(t.type===`exit`){g=!0,a&&clearTimeout(a);try{h.close()}catch{}_(`resolve`)}else if(t.type===`error`){console.warn(`[AgentExec] Agent return error:`,t.error,`execId:`,t.execId),a&&clearTimeout(a);try{h.close()}catch{}y(t.error||`Agent 执行错误`).then(()=>{_(Error(t.error||`Agent 端命令执行失败`))})}}catch{}};let S=h.onclose;h.onclose=()=>{if(a&&clearTimeout(a),X.delete(r),yn.has(r)){p=-1,J(r,o,n,-1),_(`resolve`);return}if(S&&S(),v){_(`resolve`);return}g?_(`resolve`):(p=-1,J(r,o,n,-1),y(`WebSocket 连接意外关闭`).then(()=>{_(Error(`命令执行中断:WebSocket 连接意外关闭`))}))};let C=h.onerror;h.onerror=e=>{if(a&&clearTimeout(a),X.delete(r),yn.has(r)){p=-1,J(r,o,n,-1),_(`resolve`);return}C&&C(e),y(e.message).then(()=>{_(e)})}})}catch(e){let s=e.message||(e instanceof Error?`未知错误`:String(e));if(console.warn(`[AgentExec] WebSocket streaming failed:`,s),h)try{h.close()}catch{}if(X.delete(r),yn.has(r))return J(r,o,n,-1),Pn(`command_exec`,`Command cancelled: ${i}`,{command:i,cwd:a,exitCode:-1,error:t(`toolExec.userCancelled`)}),{success:!1,level:`allow`,execId:o,exitCode:-1,stdout:c,stderr:u,killed:!0,content:`${t(`toolExec.commandCancelledWithOutput`)}${c?"stdout:\n```\n"+c+"\n```":``}${u?`
301
301
  stderr:
302
302
  \`\`\`
303
303
  `+u+"\n```":``}`,message:`${t(`toolExec.commandCancelledWithOutput`)}${c?"stdout:\n```\n"+c+"\n```":``}${u?`
304
304
  stderr:
305
305
  \`\`\`
306
- `+u+"\n```":``}`,error:t(`toolExec.userCancelled`)};if(s.includes(`超时`)||s.includes(`中断`)||_)return J(r,o,n,-1),Mn(`command_exec`,`Command failed: ${i}`,{command:i,cwd:a,exitCode:-1,error:s}),{success:!1,level:`allow`,execId:o,exitCode:-1,stdout:c,stderr:u,killed:!0,message:t(`toolExec.commandExecFailedWithOutput`,{error:s,output:(c?"stdout:\n```\n"+c+"\n```":``)+(u?`
306
+ `+u+"\n```":``}`,error:t(`toolExec.userCancelled`)};if(s.includes(`超时`)||s.includes(`中断`)||_)return J(r,o,n,-1),Pn(`command_exec`,`Command failed: ${i}`,{command:i,cwd:a,exitCode:-1,error:s}),{success:!1,level:`allow`,execId:o,exitCode:-1,stdout:c,stderr:u,killed:!0,message:t(`toolExec.commandExecFailedWithOutput`,{error:s,output:(c?"stdout:\n```\n"+c+"\n```":``)+(u?`
307
307
  stderr:
308
308
  \`\`\`
309
- `+u+"\n```":``)}),error:s};console.warn(`[AgentExec] fallback to syncmode:`,s);let f=await Lr(r,n,Be(i,a,l,d));return f.cancelled?{success:!1,content:t(`toolExec.commandCancelled`),error:t(`toolExec.userCancelled`),tool_call_id:n}:zr(f.value,i,a,n)}if(Mn(`command_exec`,`Execute command: ${i}`,{command:i,cwd:a,exitCode:p}),v){J(r,o,n,0),console.log(`[AgentExec] idletimeout,returned partialresult (command possibly stillbackgroundrun )`);let e=`命令仍在后台运行(已空闲超时,进程未终止)。\n\n执行期间输出:\n${c?"stdout:\n```\n"+c+"\n```":`(无输出)`}${u?`
309
+ `+u+"\n```":``)}),error:s};console.warn(`[AgentExec] fallback to syncmode:`,s);let f=await zr(r,n,Be(i,a,l,d));return f.cancelled?{success:!1,content:t(`toolExec.commandCancelled`),error:t(`toolExec.userCancelled`),tool_call_id:n}:Vr(f.value,i,a,n)}if(Pn(`command_exec`,`Execute command: ${i}`,{command:i,cwd:a,exitCode:p}),v){J(r,o,n,0),console.log(`[AgentExec] idletimeout,returned partialresult (command possibly stillbackgroundrun )`);let e=`命令仍在后台运行(已空闲超时,进程未终止)。\n\n执行期间输出:\n${c?"stdout:\n```\n"+c+"\n```":`(无输出)`}${u?`
310
310
  stderr:
311
311
  \`\`\`
312
312
  `+u+"\n```":``}\n\n⚠️ 注意:此命令为挂起型进程(如服务/守护进程),进程仍在后台运行中。`;return{success:!0,level:`allow`,execId:o,partial:!0,stdout:c,stderr:u,content:e,message:e,hint:`命令为挂起型进程,仍在后台运行`,tool_call_id:n}}let b=p!=null,x=b&&p>=0&&p<=127,S=b?t(`toolExec.exitCodeInfo`,{code:p}):t(`toolExec.noExitCodeInfo`),C=t(`toolExec.commandExecComplete`,{exitInfo:S});return c&&(C+=`
@@ -314,19 +314,19 @@ stderr:
314
314
  `+t(`toolExec.stdoutOutput`,{stdout:c})),u&&(C+=`
315
315
  `+t(`toolExec.stderrOutput`,{stderr:u})),m&&(C+=`
316
316
  `+t(`toolExec.commandKilledWarning`)),b||(C+=`
317
- `+t(`toolExec.commandNoExitCodeWarning`)),{success:x,level:`allow`,execId:o,exitCode:b?p:void 0,stdout:c,stderr:u,killed:m,content:C,message:C,error:x?void 0:b?t(`toolExec.commandExitCodeError`,{code:p}):t(`toolExec.commandNoExitCodeErrorMsg`),tool_call_id:n}}let p=await Lr(r,n,Be(i,a,l,d));return p.cancelled?{success:!1,content:t(`toolExec.commandCancelled`),error:t(`toolExec.userCancelled`),tool_call_id:n}:zr(p.value,i,a,n)}function zr(e,n,r,i){if(e.level===`deny`)return{success:!1,error:e.error||t(`toolExec.commandExecDenied`),level:`deny`,tool_call_id:i};if(!e.success&&!e.level)return{success:!1,error:e.error||t(`toolExec.commandExecFailed`),tool_call_id:i};if(e.level===`confirm`)return{success:!0,level:`confirm`,message:t(`toolExec.commandNeedConfirm`,{reason:e.reason,command:n}),reason:e.reason,command:n,cwd:r,tool_call_id:i};Mn(`command_exec`,`Execute command: ${n}`,{command:n,cwd:r,exitCode:e.exitCode});let a=e.exitCode!==null&&e.exitCode!==void 0,o=a&&e.exitCode>=0&&e.exitCode<=127,s=a?t(`toolExec.exitCodeInfo`,{code:e.exitCode}):t(`toolExec.noExitCodeInfo`),c=t(`toolExec.commandExecComplete`,{exitInfo:s});return e.stdout&&(c+=`
317
+ `+t(`toolExec.commandNoExitCodeWarning`)),{success:x,level:`allow`,execId:o,exitCode:b?p:void 0,stdout:c,stderr:u,killed:m,content:C,message:C,error:x?void 0:b?t(`toolExec.commandExitCodeError`,{code:p}):t(`toolExec.commandNoExitCodeErrorMsg`),tool_call_id:n}}let p=await zr(r,n,Be(i,a,l,d));return p.cancelled?{success:!1,content:t(`toolExec.commandCancelled`),error:t(`toolExec.userCancelled`),tool_call_id:n}:Vr(p.value,i,a,n)}function Vr(e,n,r,i){if(e.level===`deny`)return{success:!1,error:e.error||t(`toolExec.commandExecDenied`),level:`deny`,tool_call_id:i};if(!e.success&&!e.level)return{success:!1,error:e.error||t(`toolExec.commandExecFailed`),tool_call_id:i};if(e.level===`confirm`)return{success:!0,level:`confirm`,message:t(`toolExec.commandNeedConfirm`,{reason:e.reason,command:n}),reason:e.reason,command:n,cwd:r,tool_call_id:i};Pn(`command_exec`,`Execute command: ${n}`,{command:n,cwd:r,exitCode:e.exitCode});let a=e.exitCode!==null&&e.exitCode!==void 0,o=a&&e.exitCode>=0&&e.exitCode<=127,s=a?t(`toolExec.exitCodeInfo`,{code:e.exitCode}):t(`toolExec.noExitCodeInfo`),c=t(`toolExec.commandExecComplete`,{exitInfo:s});return e.stdout&&(c+=`
318
318
 
319
319
  `+t(`toolExec.stdoutOutput`,{stdout:e.stdout})),e.stderr&&(c+=`
320
320
  `+t(`toolExec.stderrOutput`,{stderr:e.stderr})),e.killed&&(c+=`
321
321
  `+t(`toolExec.commandKilledWarning`)),a||(c+=`
322
- `+t(`toolExec.commandNoExitCodeWarning`)),{success:o,level:`allow`,execId:e.execId,exitCode:a?e.exitCode:void 0,stdout:e.stdout||``,stderr:e.stderr||``,killed:e.killed||!1,message:c,error:o?void 0:a?t(`toolExec.commandExitCodeError`,{code:e.exitCode}):t(`toolExec.commandNoExitCodeErrorMsg`),tool_call_id:i}}async function Br(e,n){let{path:r,pattern:i,recursive:a,maxResults:o}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let s=await Le(r,i||`*`,a!==!1,o||200);if(s.success){let e=s.engine===`fd`?t(`toolExec.engineLabelFd`):t(`toolExec.engineLabelNodejs`),r=s.results.slice(0,50).map(e=>`${e.path} (${e.size} bytes)`).join(`
322
+ `+t(`toolExec.commandNoExitCodeWarning`)),{success:o,level:`allow`,execId:e.execId,exitCode:a?e.exitCode:void 0,stdout:e.stdout||``,stderr:e.stderr||``,killed:e.killed||!1,message:c,error:o?void 0:a?t(`toolExec.commandExitCodeError`,{code:e.exitCode}):t(`toolExec.commandNoExitCodeErrorMsg`),tool_call_id:i}}async function Hr(e,n){let{path:r,pattern:i,recursive:a,maxResults:o}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};let s=await Le(r,i||`*`,a!==!1,o||200);if(s.success){let e=s.engine===`fd`?t(`toolExec.engineLabelFd`):t(`toolExec.engineLabelNodejs`),r=s.results.slice(0,50).map(e=>`${e.path} (${e.size} bytes)`).join(`
323
323
  `);return{success:!0,results:s.results,total:s.total,engine:s.engine,message:t(`toolExec.agentSearchFilesResult`,{total:s.total,engineLabel:e})+`
324
324
 
325
- `+r+(s.total>50?t(`toolExec.fileListLimitHint`,{count:50}):``),tool_call_id:n}}return{success:!1,error:s.error,tool_call_id:n}}async function Vr(e,n){let{path:r,pattern:i,filePattern:a,caseSensitive:o,recursive:s,maxResults:c,contextLines:l}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};if(!i)return{success:!1,error:t(`toolExec.missingPattern`),tool_call_id:n};let u=await Re(r,i,a||null,o||!1,s!==!1,c||100,l===void 0?2:l);if(u.success){let e=u.engine===`rg`?t(`toolExec.engineLabelRipgrep`):t(`toolExec.engineLabelNodejs`),r=u.results.slice(0,30).map(e=>`${e.file}:${e.line}\n${e.content}`).join(`
325
+ `+r+(s.total>50?t(`toolExec.fileListLimitHint`,{count:50}):``),tool_call_id:n}}return{success:!1,error:s.error,tool_call_id:n}}async function Ur(e,n){let{path:r,pattern:i,filePattern:a,caseSensitive:o,recursive:s,maxResults:c,contextLines:l}=e;if(!r)return{success:!1,error:t(`toolExec.missingPathParam`),tool_call_id:n};if(!i)return{success:!1,error:t(`toolExec.missingPattern`),tool_call_id:n};let u=await Re(r,i,a||null,o||!1,s!==!1,c||100,l===void 0?2:l);if(u.success){let e=u.engine===`rg`?t(`toolExec.engineLabelRipgrep`):t(`toolExec.engineLabelNodejs`),r=u.results.slice(0,30).map(e=>`${e.file}:${e.line}\n${e.content}`).join(`
326
326
 
327
327
  `);return{success:!0,results:u.results,total:u.total,engine:u.engine,message:t(`toolExec.agentSearchContentResult`,{total:u.total,engineLabel:e})+`
328
328
 
329
- `+r+(u.total>30?t(`toolExec.matchListLimitHint`,{count:30}):``),tool_call_id:n}}return{success:!1,error:u.error,tool_call_id:n}}var Hr=null;async function Ur(){let e=chrome.runtime.getURL(`offscreen/offscreen.html`);if(!((await chrome.runtime.getContexts({contextTypes:[`OFFSCREEN_DOCUMENT`],documentUrls:[e]})).length>0)){if(Hr){await Hr;return}Hr=chrome.offscreen.createDocument({url:`offscreen/offscreen.html`,reasons:[`CLIPBOARD`],justification:`用于读写系统剪贴板内容`});try{await Hr}finally{Hr=null}}}async function Wr(e,n,r,i){let{format:a=`text`,selector:o,maxLength:s=15e3,tabId:c}=e,l={text:`GET_PAGE_TEXT`,html:`GET_FULL_HTML`}[a];if(!l)return{success:!1,error:`不支持的格式: ${a},可选: text, html`,tool_call_id:n};try{let e=r?Se(r):null,i=c||e||await Kn();return i?await qn(i,{type:l,selector:o,maxLength:s},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function Gr(e,n,r,i){let{dataType:a,selector:o,filterType:s=`all`,includeHeaders:c=!0,format:l=`json`,includeImages:u=!1,minWidth:d=0,minHeight:f=0,maxResults:p=100,tabId:m}=e;if(!a)return{success:!1,error:t(`toolExec.missingDataType`),tool_call_id:n};let h={table:`EXTRACT_TABLE`,metadata:`EXTRACT_METADATA`,links:`EXTRACT_LINKS`,forms:`EXTRACT_FORMS`,images:`EXTRACT_IMAGES`}[a];if(!h)return{success:!1,error:`不支持的数据类型: ${a},可选: table, metadata, links, forms, images`,tool_call_id:n};try{let e=r?Se(r):null,i=m||e||await Kn();return i?await qn(i,{type:h,selector:o,filterType:s,includeHeaders:c,format:l,includeImages:u,minWidth:d,minHeight:f,maxResults:p},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function Kr(e,n){let{action:r,text:i,format:a=`text`}=e;if(!r)return{success:!1,error:t(`toolExec.missingAction`),tool_call_id:n};if(r===`copy`)return qr({text:i},n);if(r===`paste`)return Jr({},n);if(r===`get_selected`)try{let e=await Kn();return e?await qn(e,{type:`GET_SELECTED_CONTENT`,format:a},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}return{success:!1,error:`不支持的操作: ${r},可选: copy, paste, get_selected`,tool_call_id:n}}async function qr(e,n){let{text:r}=e;if(r==null)return{success:!1,error:t(`toolExec.missingText`),tool_call_id:n};try{await Ur();let e=await chrome.runtime.sendMessage({type:`COPY_TO_CLIPBOARD`,text:r});return e?.success?{success:!0,message:e.message||t(`toolExec.copiedToClipboard`),tool_call_id:n}:{success:!1,error:e?.error||t(`toolExec.copyFailed`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function Jr(e,t){try{await Ur();let e=await chrome.runtime.sendMessage({type:`PASTE_FROM_CLIPBOARD`});return e?.success?{success:!0,text:e.text,tool_call_id:t}:{success:!1,error:e?.error||`粘贴失败`,tool_call_id:t}}catch(e){return{success:!1,error:e.message,tool_call_id:t}}}async function Yr(e,t=`kill`){console.log(`[Background] cancelrunning Agent command,sessionId:`,e,`mode:`,t),_n.add(e);let n=X.get(e);if(!n){console.warn(`[Background] runningAgentCommands not found entry:`,e),setTimeout(()=>{_n.delete(e)},3e3);return}let{execId:r,ws:i,resolve:a,toolCallId:o}=n;console.log(`[Background] find to runningcommand,execId:`,r),X.delete(e),J(e,r,o,-1),a&&(a(),console.log(`[Background] Promise direct resolve,task continuesexec `));try{i.close()}catch{}t===`kill`?Ve(r).then(()=>{console.log(`[Background] stopped Agent command process:`,r)}).catch(e=>{console.warn(`[Background] stop Agent command process failed:`,e.message)}):console.log(`[Background] only disconnect WebSocket,command process continuesrun :`,r),setTimeout(()=>{_n.delete(e)},3e3)}async function Xr(e,n){try{let e=await W(),r=await ke(),i=[];for(let t of e){let e=H(t.id);i.push({id:t.id,name:t.name,url:t.url,reachable:e,disabled:t.disabled||!1,isActive:r?.id===t.id})}let a=i.map(e=>{let n=e.disabled?t(`toolExec.agentStatusDisabled`):e.reachable===!0?t(`toolExec.agentStatusOnline`):e.reachable===!1?t(`toolExec.agentStatusOffline`):t(`toolExec.agentStatusUnknown`),r=e.isActive?t(`toolExec.agentStatusActive`):``;return`- ${e.name} (${e.id}): ${n}${r}`}).join(`
330
- `);return{success:!0,content:t(`toolExec.agentListContent`,{summary:a,data:JSON.stringify(i,null,2)}),agents:i,activeAgentId:r?.id||null,tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.agentListFailed`,{error:e.message}),tool_call_id:n}}}async function Zr(e,n){let{agentId:r,agentName:i}=e;if(!r&&!i)return{success:!1,error:t(`toolExec.missingAgentId`),tool_call_id:n};try{let e=await W(),a;if(r&&(a=e.find(e=>e.id===r)),!a&&i&&(a=e.find(e=>e.name===i),a||=e.find(e=>e.name&&e.name.toLowerCase().includes(i.toLowerCase()))),!a){let a=e.map(e=>`- ${e.name} (${e.id})`).join(`
331
- `);return{success:!1,error:t(`toolExec.agentNotFound`,{id:r||i,list:a}),tool_call_id:n}}if(a.disabled)return{success:!1,error:t(`toolExec.agentDisabled`,{name:a.name}),tool_call_id:n};if(!await Ae(a.id))return{success:!1,error:t(`toolExec.agentSwitchFailedSimple`,{name:a.name}),tool_call_id:n};let o=H(a.id),s=o===!0?``:t(`toolExec.agentOfflineWarning`);return{success:!0,content:t(`toolExec.agentSwitchSuccess`,{name:a.name,id:a.id,warning:s}),agentId:a.id,agentName:a.name,offline:o!==!0,tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.agentSwitchFailed`,{error:e.message}),tool_call_id:n}}}e(`zh`,{bg:{missingSessionId:`缺少 sessionId`,resumingFromCheckpoint:`从 checkpoint 恢复中...`,checkpointNotFound:`未找到可恢复的任务 checkpoint,可能已过期或被清理。请检查 Service Worker 控制台中的诊断日志(搜索 "checkpoint" 关键字)。`,resumeFailed:`恢复失败`,missingSkillName:`缺少技能名称`,fetchFailed:`获取失败`,preparing:`准备中...`,toolPreselect:`工具预筛选`,requestCancelled:`请求已被用户取消`,reactCancelled:`ReAct 循环已被用户取消`,apiCallFailed:`API 调用失败`}}),e(`en`,{bg:{missingSessionId:`Missing sessionId`,resumingFromCheckpoint:`Resuming from checkpoint...`,checkpointNotFound:`No checkpoint found for resumption. It may have expired or been cleaned. Check Service Worker console logs (search "checkpoint").`,resumeFailed:`Resume failed`,missingSkillName:`Missing skill name`,fetchFailed:`Fetch failed`,preparing:`Preparing...`,toolPreselect:`Tool Pre-filter`,requestCancelled:`Request was cancelled by user`,reactCancelled:`ReAct loop was cancelled by user`}}),n(),Promise.all([j().then(()=>le()),Oe()]).then(([e,t])=>{r.debug(`[Background] DB self-check passed,current has ${e.length} checkpoint`+(t?`,completedoldformat Agent migrate`:``))}).catch(e=>{r.warn(`[Background] cleanup expired checkpoint or DB self-check failed:`,e)});var Qr=1e3,Q=null,$r=null,ei=new Map,$=null;chrome.storage.local.get(`_detachWindowId`,e=>{$=e._detachWindowId||null,$&&chrome.windows.get($).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})})}),chrome.runtime.onConnect.addListener(async e=>{if(e.name?.startsWith(`keepalive-`)){let t=e.name.replace(`keepalive-`,``),n=ei.has(t);if(ei.set(t,e),r.debug(`[Background] keepalive portconnected, sessionId:`,t,n?`(reconnect)`:`(first times)`),n&&!Nt.has(t)){r.warn(`[Background] ⚠️ detected SW re started,sessionId`,t,` API call lost`);let n=null;try{let e=await P(t);e&&(n={iteration:e.iteration,interruptedReason:e.interruptedReason,updatedAt:e.updatedAt,messageCount:e.currentMessages?.length||0,subtaskPlan:e.subtaskPlan?{subtaskCount:e.subtaskPlan.subtasks?.length||0}:null},r.debug(`[Background] detected recoverable checkpoint:`,n))}catch(e){r.warn(`[Background] read checkpoint failed:`,e.message)}try{e.postMessage({type:`SW_RESTARTED`,sessionId:t,checkpoint:n})}catch(e){r.warn(`[Background] send SW_RESTARTED message failed:`,e.message)}}e.onDisconnect.addListener(()=>{ei.delete(t),r.debug(`[Background] keepalive port disconnected, sessionId:`,t)})}}),chrome.sidePanel?.setPanelBehavior?.({openPanelOnActionClick:!1}),chrome.action.onClicked.addListener(e=>{if($){try{chrome.windows.update($,{focused:!0}).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})})}catch{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})}return}chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})}),chrome.windows.onRemoved.addListener(e=>{$===e&&($=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),r.debug(`[Background] detached window closed, cleaned up windowId:`,e))}),chrome.tabs.onUpdated.addListener((e,t,n)=>{t.status===`complete`&&n.url?.startsWith(`http`)&&chrome.sidePanel?.setOptions?.({enabled:!0})}),chrome.commands?.onCommand?.addListener(e=>{if(e===`_toggle_sidepanel`)try{if($){try{chrome.windows.update($,{focused:!0}).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})})}catch{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})}return}chrome.extension.getViews({type:`side_panel`}).length>0?chrome.runtime.sendMessage({type:`CLOSE_SIDEPANEL`}).catch(e=>{r.warn(`[Background] send CLOSE_SIDEPANEL failed:`,e?.message)}):chrome.tabs.query({active:!0,currentWindow:!0},e=>{e[0]?.id&&chrome.sidePanel?.open?.({tabId:e[0].id}).catch(e=>{r.warn(`[Background] open sidePanel failed:`,e?.message)})})}catch(e){r.warn(`[Background] toggle sidePanel exception:`,e?.message)}}),chrome.runtime.onMessage.addListener((e,n,i)=>{if(e.type===`IFRAME_SELECTION`){let t=n.tab?.id;return t&&chrome.tabs.sendMessage(t,{type:`IFRAME_SELECTION`,text:e.text,x:e.x,y:e.y},{frameId:0}).catch(()=>{}),!1}if(e.type===`IFRAME_CLICK_DISMISS`){let e=n.tab?.id;return e&&chrome.tabs.sendMessage(e,{type:`IFRAME_CLICK_DISMISS`}).catch(()=>{}),!1}if(e.type===`IFRAME_SELECTION_CLEAR`){let e=n.tab?.id;return e&&chrome.tabs.sendMessage(e,{type:`IFRAME_SELECTION_CLEAR`}).catch(()=>{}),!1}if(e.type===`CANCEL_REACT`){let{tabId:t,sessionId:n}=e;return n?(he(n),Yr(n)):he(t),!1}if(e.type===`GET_CHECKPOINT`){let{sessionId:t}=e;return t?(P(t).then(e=>{if(!e){i({exists:!1});return}i({exists:!0,checkpoint:{iteration:e.iteration,interruptedReason:e.interruptedReason,updatedAt:e.updatedAt,messageCount:e.currentMessages?.length||0,subtaskPlan:e.subtaskPlan?{subtaskCount:e.subtaskPlan.subtasks?.length||0}:null}})}).catch(e=>{r.warn(`[Background] GET_CHECKPOINT query failed:`,e),i({exists:!1})}),!0):(i({exists:!1}),!1)}if(e.type===`DELETE_CHECKPOINT`){let{sessionId:t}=e;return t?ie(t).then(e=>{i({success:e})}).catch(e=>{r.warn(`[Background] DELETE_CHECKPOINT failed:`,e),i({success:!1})}):i({success:!1}),!0}if(e.type===`RESUME_REACT`){let{sessionId:n,callId:a,userGuidance:o=``}=e;if(!n)return i({error:t(`bg.missingSessionId`)}),!1;r.debug(`[Background] recei to RESUME_REACT,sessionId:`,n,`userGuidance:`,o?`"${o.substring(0,50)}..."`:`( no )`);let s=Nt.has(n),c=()=>{L(n);let e={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.resumingFromCheckpoint`),status:`processing`,executionLog:[],sessionId:n};a&&(e.callId=a),chrome.runtime.sendMessage(e).catch(()=>{}),Vt(n,o,a).then(e=>{if(!e){r.warn(`[Background] RESUME_REACT: not found checkpoint or restore failed`),P(n).then(e=>{r.warn(`[Background] RESUME_REACT: re-query checkpoint result:`,e?`exists`:`not found`)}).catch(()=>{}),chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:n,callId:a,error:t(`bg.checkpointNotFound`),executionLog:[],resumed:!0}).catch(()=>{});return}r.debug(`[Background] RESUME_REACT complete,content length:`,e.content?.length);let i=(e.executionLog||[]).length>Qr?e.executionLog.slice(-1e3):e.executionLog||[];chrome.runtime.sendMessage({type:`API_COMPLETE`,sessionId:n,callId:a,content:e.content||``,executionLog:i,reflectionScore:e.reflectionScore,reasoningContent:e.reasoningContent||null,wasRevised:e.wasRevised||!1,resumed:!0}).catch(e=>{r.warn(`[Background] send RESUME completemessage failed:`,e)})}).catch(e=>{let i=e.name===`AbortError`||e.message===t(`bg.requestCancelled`)||e.message===t(`bg.reactCancelled`);r.debug(`[Background] RESUME_REACT failed:`,i?`(usercancel)`:e.message);let o=e.executionLog||[],s=o.length>Qr?o.slice(-1e3):o;chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:n,callId:a,error:e.message||t(`bg.resumeFailed`),executionLog:s,resumed:!0}).catch(()=>{})})};return s?(r.debug(`[Background] RESUME_REACT: detectedoldtaskstill running , first cancel`),he(n),Yr(n),setTimeout(c,300)):c(),!1}if(e.type===`TERMINATE_COMMAND`){let{sessionId:t,mode:n}=e;return t&&Yr(t,n||`kill`),!1}if(e.type===`ABORT_CURRENT_TOOL`){let{sessionId:t}=e;return i({success:we(t)}),!1}if(e.type===`RELOAD_MCP_TOOLS`)return Q=null,En().then(e=>{i({success:!0,count:e})}).catch(e=>{i({success:!1,error:e.message})}),!0;if(e.type===`GET_MCP_TOOLS`){let e=Date.now();return Q&&e-Q.loadedAt<3e4?(r.debug(`[Background] GET_MCP_TOOLS usingcache (${Q.tools.length} tool,${Math.round((e-Q.loadedAt)/1e3)}s before )`),i({success:!0,tools:Q.tools}),!0):(En().then(e=>{let t=f.filter(e=>e.id.startsWith(`mcp_`)).map(e=>({id:e.id,name:e.function?.name||e.id,description:e.function?.description||``,category:e.category||`mcp`,execution:e.execution||`background`,parallelizable:e.parallelizable!==!1,requiresConfirmation:e.requiresConfirmation||!1,enabled:!0}));Q={tools:t,loadedAt:Date.now()},r.debug(`[Background] GET_MCP_TOOLS return ${t.length} tool ( reloads ${e} )`),i({success:!0,tools:t})}).catch(e=>{i({success:!1,error:e.message})}),!0)}if(e.type===`GET_AGENT_SKILL_PROMPTS`){let t=Date.now(),n=e.skillNames||null;return!n&&$r&&t-$r.loadedAt<6e4?(i({success:!0,prompts:$r.prompts}),!0):((n&&n.length>0?$e(n):Qe()).then(e=>{let t=e.success&&e.prompts||``;n||($r={prompts:t,loadedAt:Date.now()}),i({success:!0,prompts:t})}).catch(e=>{i({success:!1,error:e.message})}),!0)}if(e.type===`GET_AGENT_SKILL_PROMPT`){let n=e.name;return n?(et(n).then(e=>{i(e)}).catch(e=>{i({success:!1,error:e.message})}),!0):(i({success:!1,error:t(`bg.missingSkillName`)}),!0)}if(e.type===`GET_SKILL_LIST`)return Ke().then(e=>{e?.success?i({success:!0,skills:e.skills||[]}):i({success:!1,skills:[],error:e?.error||t(`bg.fetchFailed`)})}).catch(e=>{i({success:!1,skills:[],error:e.message})}),!0;if(e.type===`CAPTURE_TAB`)return chrome.tabs.captureVisibleTab(null,{format:`jpeg`,quality:100},e=>{chrome.runtime.lastError?(r.error(`[Background] screenshot failed:`,chrome.runtime.lastError.message),i({error:chrome.runtime.lastError.message})):i({dataUrl:e})}),!0;if(e.type===`CAPTURE_TAB_FROM_PAGE`)return chrome.tabs.captureVisibleTab(null,{format:`jpeg`,quality:100},e=>{chrome.runtime.lastError?r.error(`[Background] pageshortcutscreenshot failed:`,chrome.runtime.lastError.message):chrome.runtime.sendMessage({type:`SCREENSHOT_RESULT`,dataUrl:e,mode:`full`}).catch(()=>{})}),!0;if(e.type===`CAPTURE_REGION_FROM_PAGE`){let e=n.tab?.id;return e?(chrome.tabs.sendMessage(e,{type:`START_REGION_SELECTION`},e=>{e&&chrome.tabs.captureVisibleTab(null,{format:`png`},t=>{chrome.runtime.lastError?r.error(`[Background] region screenshot failed:`,chrome.runtime.lastError.message):chrome.runtime.sendMessage({type:`SCREENSHOT_RESULT`,dataUrl:t,mode:`region`,rect:e}).catch(()=>{})})}),!0):!1}if(e.type===`CALL_API`){let{messages:n,model:i,useTools:a,tabId:o,apiParams:s,sessionId:c,imageApiBase:l,imageApiKey:u,agentId:d,agentToolIds:f,agentSkillIds:p,callId:m}=e;l&&(s.imageApiBase=l),u&&(s.imageApiKey=u),L(c);let h={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.preparing`),status:`processing`,executionLog:[]};return c&&(h.sessionId=c),m&&(h.callId=m),chrome.runtime.sendMessage(h).catch(()=>{}),r.debug(`[Background] recei to CALL_API message,sessionId:`,c,`useTools:`,a,`tabId:`,o,`apiParams:`,s),(a?(async()=>{let e=await Ln(f,d,p);if(e.length===0)return r.debug(`[Background] no available tools, skip pre-filter, direct normal conversation`),Jt(n,i,s,c,{},m);r.debug(`[Background] get to ${e.length} tool`);let a=(await z()).reactConfig.enableToolPreselect,l;if(a?l=await vt(n,i,e,s):(r.debug(`[Background] toolpre-filterclosed,using alltool`),l={type:`tools`,tools:e,executionLog:[]}),l.executionLog.length>0){let e={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.toolPreselect`),status:`success`,executionLog:l.executionLog};c&&(e.sessionId=c),m&&(e.callId=m),r.debug(`[Background] sendpre-filterstateupdate:`,e),chrome.runtime.sendMessage(e).then(()=>{r.debug(`[Background] pre-filterstateupdatesend successful`)}).catch(e=>{r.error(`[Background] pre-filterstateupdatesend failed:`,e)})}if(l.type===`answer`)return r.debug(`[Background] pre-filtermodeldirect answer,skip mainmodelcall with `),{content:l.content,executionLog:l.executionLog};let{tools:u,executionLog:h}=l;r.debug(`[Background] after pre-filter ${u.length} tool`),r.debug(`[Background] pre-filter executionlog:`,JSON.stringify(h).substring(0,500)),h.length>0&&chrome.runtime.sendMessage({type:`STREAM_PRESELECT`,sessionId:c,callId:m,preselectLog:h}).catch(()=>{});let g=await Ht(n,i,u,o,s,c,null,null,{value:1},h,m);return r.debug(`[Background] ReAct complete,executionLog total:`,g.executionLog?.length),{content:g.content===void 0?g:g.content,executionLog:g.executionLog||h,reflectionScore:g.reflectionScore,wasRevised:g.wasRevised||!1,reasoningContent:g.reasoningContent||null}})():Jt(n,i,s,c)).then(e=>{let t=e.content===void 0?e:e.content,n=e.executionLog||[],o=e.reflectionScore,s=e.wasRevised||!1,l=e.reasoningContent||null;e.usage&&(yt({sessionId:c,model:i||``,usage:e.usage,callType:`non_stream`}).catch(()=>{}),n.length===0&&(n=[{nodeType:`api_call`,nodeName:`API Call`,status:`success`,timestamp:new Date().toISOString(),apiResponse:{tokenUsage:e.usage}}])),r.debug(`[Background] API call complete,content length:`,t.length,`execution logcount:`,n.length),console.log(`[Background API_COMPLETE] useTools:`,a,`| executionLog entries:`,n.length,`| agent_file entries:`,n.filter(e=>e.nodeType===`tool_exec`&&e.action?.name===`agent_file`).length,`| first few types:`,n.slice(0,5).map(e=>`${e.nodeType}${e.action?`(${e.action.name})`:``}`));let u=n.length>Qr?n.slice(-1e3):n;chrome.runtime.sendMessage({type:`API_COMPLETE`,sessionId:c,callId:m,content:t,executionLog:u,reflectionScore:o,reasoningContent:l,wasRevised:s}).catch(e=>{r.warn(`[Background] send backmessage failed:`,e)})}).catch(e=>{e.name===`AbortError`||e.message===t(`bg.requestCancelled`)||e.message===t(`bg.reactCancelled`)?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e);let n=e.executionLog||[],i=n.length>Qr?n.slice(-1e3):n;chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:c,callId:m,error:e.message||t(`bg.apiCallFailed`),executionLog:i}).catch(e=>{r.warn(`[Background] send errormessage failed:`,e)})}),!1}if(e.type===`GET_SESSION`)return z().then(e=>{i({modelName:e.modelName})}),!0;if(e.type===`GET_CHAT_CONFIG`)return Ee().then(e=>{i(e)}),!0;if(e.type===`GET_PERMANENT_NOTES`)return on().then(e=>{if(!e.success){i({success:!1,facts:[],error:e.error});return}i({success:!0,facts:(e.data.facts||[]).sort((e,t)=>(t.importance||0)-(e.importance||0))})}).catch(e=>{i({success:!1,facts:[],error:e.message})}),!0;if(e.type===`OPEN_OPTIONS_PAGE`){let t=e.hash||``;return chrome.runtime.openOptionsPage(()=>{t&&chrome.tabs.query({url:chrome.runtime.getURL(`options.html`)+`*`},e=>{e.length>0&&chrome.tabs.update(e[0].id,{url:chrome.runtime.getURL(`options.html`)+`#`+t})})}),!1}if(e.type===`DETACH_SIDEPANEL`){let t=Math.min(Math.max(e.width||480,320),900);return(async()=>{try{let e=null;if(n.tab?.windowId)try{e=await chrome.windows.get(n.tab.windowId)}catch{}if(!e)try{e=await chrome.windows.getLastFocused()}catch{}let a=e?Math.max(e.left,Math.round(e.left+(e.width-t)/2)):void 0,o=e?Math.max(e.top,Math.round(e.top+(e.height-720)/2)):void 0,s=await chrome.windows.create({url:chrome.runtime.getURL(`side_panel.html`)+`?popup=1`,type:`popup`,width:t,height:720,left:a,top:o});$=s.id,await chrome.storage.local.set({_detachWindowId:s.id}).catch(()=>{}),r.debug(`[Background] sidePanel detached, windowId:`,s.id),i({success:!0,windowId:s.id})}catch(e){r.warn(`[Background] detach sidePanel failed:`,e?.message),i({success:!1,error:e?.message})}})(),!0}if(e.type===`ATTACH_SIDEPANEL`)return $=null,e.windowId&&chrome.windows.remove(e.windowId).catch(()=>{}),chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.tabs.query({active:!0,currentWindow:!0},e=>{e[0]?.id&&chrome.sidePanel?.open?.({tabId:e[0].id}).catch(e=>{r.warn(`[Background] open sidePanel after attach failed:`,e?.message)})}),i({success:!0}),!1;if(e.type===`SELECTION_TOOLBAR_ACTION`){let{prompt:i,action:a,text:o,systemPrompt:s}=e,c=n.tab?.id,l=n.frameId;if(r.debug(`[Background] received selected text toolbar operation:`,a,`tabId:`,c),a===`ai-search`)return!chrome.extension.getViews().some(e=>e.location?.search?.includes(`popup=1`))&&c&&chrome.sidePanel.open({tabId:c}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),ti(i,o,c),!1;let u=[{role:`system`,content:s||{explain:`你正在处理用户在网页上选中的内容。用1-3句简洁解释选中内容,必要时补充一个简短示例。不要展开长篇论述。`,translate:`你正在处理用户在网页上选中的内容。自动检测语言:中文→英文,英文→中文,其他语言→同时给出中英文。只输出翻译结果,不添加额外说明。`,summary:`你正在处理用户在网页上选中的内容。用3-5个要点总结选中内容,每条要点一句话,提炼核心信息即可。`}[a]||`你正在处理用户在网页上选中的内容,请用简洁的语言回答用户的问题。`},{role:`user`,content:i}];return L(),z().then(async e=>{try{if(e.streamConfig?.streamEnabled!==!1&&c){let t=`toolbar_${c}_${Date.now()}`,n=await Jt(u,e.modelName,{},t,{sendFn:e=>chrome.tabs.sendMessage(c,e,{frameId:l}).catch(()=>{}),typePrefix:`SELECTION_TOOLBAR_`}),i=n.content===void 0?n:n.content;n.usage&&yt({sessionId:`selection_toolbar`,model:e.modelName,usage:n.usage,callType:`stream`}).catch(()=>{}),r.debug(`[Background] selected texttoolbarstreaming API complete,content length:`,i.length)}else{let t=await Jt(u,e.modelName,{}),n=t.content===void 0?t:t.content;t.usage&&yt({sessionId:`selection_toolbar`,model:e.modelName,usage:t.usage,callType:`non_stream`}).catch(()=>{}),r.debug(`[Background] selected texttoolbar API complete,content length:`,n.length),c&&chrome.tabs.sendMessage(c,{type:`SELECTION_TOOLBAR_RESULT`,content:n},{frameId:l}).catch(()=>{r.warn(`[Background] send SELECTION_TOOLBAR_RESULT to tab failed`)})}}catch(e){r.error(`[Background] selected texttoolbar API failed:`,e),c&&chrome.tabs.sendMessage(c,{type:`SELECTION_TOOLBAR_RESULT`,error:e.message||t(`bg.apiCallFailed`)},{frameId:l}).catch(()=>{})}}),!1}if(e.type===`FILL_SIDEPANEL_INPUT`){let t=n.tab?.id,i=e.text;return r.debug(`[Background] received follow-upfillrequested :`,i?.substring(0,50)),t&&chrome.sidePanel.open({tabId:t}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),chrome.storage.session.set({pendingFillInput:{text:i,timestamp:Date.now()}}).catch(()=>{}),chrome.runtime.sendMessage({type:`FILL_SIDEPANEL_INPUT`,text:i}).catch(()=>{r.debug(`[Background] Side Panel not open,fillcontentstorage,waiting Side Panel load`)}),!1}if(e.type===`DIRECT_SEND`){let t=n.tab?.id,i=e.text,a=e.selectedText||``;return r.debug(`[Background] received directsendrequested :`,i?.substring(0,50)),t&&chrome.sidePanel.open({tabId:t}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),chrome.storage.session.set({pendingDirectSend:{text:i,selectedText:a,timestamp:Date.now()}}).catch(()=>{}),chrome.runtime.sendMessage({type:`DIRECT_SEND`,text:i,selectedText:a}).catch(()=>{r.debug(`[Background] Side Panel not open,sendcontentstorage,waiting Side Panel load`)}),!1}if(e.type===`TRIGGER_AGENT_HEALTH_CHECK`)return ai.clear(),ci(),!1;if(e.type===`OPTIONS_PAGE_OPEN`)return ii=!0,ai.clear(),ci(),!1;if(e.type===`OPTIONS_PAGE_CLOSED`)return ii=!1,!1;if(e.type===`AGENT_CONNECTION_CHANGED`)return chrome.runtime.sendMessage({type:`AGENT_CONNECTION_CHANGED`,connected:e.connected,agentId:e.agentId}).catch(()=>{}),e.connected&&e.agentId?(Xe(),$r=null,Q=null,Dr(),ai.clear(),Fn(),V(e.agentId,!0),di(),En().then(e=>{e>0&&r.debug(`[Background] switchagent after loaded: ${e} MCP tool`)}).catch(()=>{}),setTimeout(()=>{ci()},3e3)):e.connected||(di(),Q=null,$r=null,Dr(),ci()),!1;if(e.type===`CHECK_FILES_EXIST`){let t=e.paths||[];return t.length===0?(i({success:!0,results:{}}),!1):((async()=>{let e=await Promise.allSettled(t.map(e=>Me(e))),n={};e.forEach((e,r)=>{e.status===`fulfilled`&&e.value.success?n[t[r]]=e.value.exists:n[t[r]]=!0}),i({success:!0,results:n})})(),!0)}if(e.type===`AGENT_RESTART`)return(async()=>{i(await tt())})(),!0;if(e.type===`AGENT_UPDATE`)return(async()=>{i(await nt())})(),!0;if(e.type===`AGENT_STOP`)return(async()=>{i(await rt())})(),!0;if(e.type===`OPEN_LOCAL_PROTOTYPE`)return(async()=>{i(await q(e.path))})(),!0;if(e.type===`DELETE_LOCAL_PROTOTYPE`)return(async()=>{try{let t=e.path.replace(/[\\/][^\\/]+\.html$/,``),n=await Fe(t);n.success?r.debug(`[Background] local prototypefile deleted:`,t):r.warn(`[Background] local prototypefiledelete failed:`,n.error),i(n)}catch(e){r.warn(`[Background] local prototypefiledelete failed:`,e.message),i({success:!1,error:e.message})}})(),!0;if(e.type===`QUERY_AUDIT_LOGS`)return it({category:e.category,limit:e.limit}).then(e=>{i(e)}).catch(e=>{i({success:!1,error:e.message})}),!0});async function ti(e,t,n){r.debug(`[Background] processselected text AI search:`,e.substring(0,50)+`...`),await chrome.storage.session.set({pendingSelectionSearch:{prompt:e,selectedText:t,timestamp:Date.now()}}),chrome.runtime.sendMessage({type:`SELECTION_AI_SEARCH`,prompt:e,selectedText:t}).catch(()=>{r.debug(`[Background] Side Panel not open,searchcontentstorage,waiting Side Panel load`)})}var ni=null,ri=null,ii=!1,ai=new Map,oi=new Map;async function si(e){let t=!1,n=5e3;try{let r=new AbortController,i=setTimeout(()=>r.abort(),n),a=await fetch(`${e.url}/api/status`,{signal:r.signal,cache:`no-cache`});clearTimeout(i),t=a.ok}catch{t=!1}if(!t){await new Promise(e=>setTimeout(e,500));try{let r=new AbortController,i=setTimeout(()=>r.abort(),n),a=await fetch(`${e.url}/api/status`,{signal:r.signal,cache:`no-cache`});clearTimeout(i),t=a.ok}catch{t=!1}}return t}async function ci(){try{let e=await W();if(e.length===0){ai.size>0&&(ai.clear(),Fn(),V(`__global__`,!1),pi(!1,`未配对`));return}let t=await ke(),n=e.filter(e=>!e.disabled),i=ii?n:t&&!t.disabled?[t]:[];if(i.length===0)return;let a=(await Promise.allSettled(i.map(async e=>{let t=await si(e);return ai.get(e.id)===t?{agentId:e.id,name:e.name,connected:t,changed:!1}:(ai.set(e.id,t),V(e.id,t),r.debug(`[Background] agent ${e.name} status change: ${t?`online`:`offline`}`),{agentId:e.id,name:e.name,connected:t,changed:!0})}))).filter(e=>e.status===`fulfilled`&&e.value.changed).map(e=>e.value);if(a.length>0){Fn();let e=a.find(e=>e.agentId===t?.id);e&&(pi(e.connected,e.connected?`在线`:`离线`,e.agentId),e.connected?(ui(e.agentId),En().then(e=>{e>0&&r.debug(`[Background] Agent after reconnect loaded: ${e} MCP tool`)}).catch(()=>{})):(await On(),Q=null,r.debug(`[Background] Agent disconnect,cleaned MCP tool`),li(t)))}}catch(e){r.warn(`[Background] agenthealth checkexception:`,e.message)}}function li(e){if(!e||e.disabled||oi.get(e.id))return;let t=n=>{if(n>=20){oi.delete(e.id),r.debug(`[Background] agent ${e.name} auto reconnectabandoned (exceed maxretry times)`);return}let i=setTimeout(async()=>{let i=(await W()).find(t=>t.id===e.id);if(!i||i.disabled){oi.delete(e.id),r.debug(`[Background] agent ${e.name} ${i?.disabled?`disable`:`delete`},stopauto reconnect`);return}r.debug(`[Background] agent ${e.name} auto reconnectattempt ${n+1}/20`),await si(e)?(oi.delete(e.id),ai.set(e.id,!0),V(e.id,!0),Fn(),pi(!0,`在线`,e.id),fi(e.id),En().then(t=>{t>0&&r.debug(`[Background] Agent ${e.name} reconnect successful,loaded: ${t} MCP tool`)}).catch(()=>{}),r.debug(`[Background] agent ${e.name} auto reconnect successful`)):t(n+1)},15e3);oi.set(e.id,{timer:i,retries:n})};t(0)}function ui(e){let t=oi.get(e);t&&(clearTimeout(t.timer),oi.delete(e))}function di(){for(let[e,t]of oi)clearTimeout(t.timer);oi.clear()}async function fi(e){try{let t=await ke();t&&t.id===e&&En().then(e=>{e>0&&r.debug(`[Background] active agentafter reconnect loaded: ${e} MCP tool`)}).catch(()=>{})}catch(e){r.warn(`[Background] refreshactive agentstate failed:`,e.message)}}function pi(e,t,n){chrome.runtime.sendMessage({type:`AGENT_STATUS_CHANGE`,connected:e,status:t,agentId:n}).catch(()=>{})}function mi(){hi(),r.debug(`[Background] start Agent health check (30s interval)`),ci(),ni=setInterval(ci,3e4),_i()}function hi(){ni&&(clearInterval(ni),ni=null,ai.clear()),vi()}async function gi(){try{let e=await ke();if(!e||e.disabled)return;let t=new AbortController,n=setTimeout(()=>t.abort(),5e3);try{await fetch(`${e.url}/api/heartbeat`,{headers:{Authorization:`Bearer ${e.token}`},signal:t.signal,cache:`no-cache`})}finally{clearTimeout(n)}}catch{}}function _i(){vi(),gi(),ri=setInterval(gi,6e4)}function vi(){ri&&=(clearInterval(ri),null)}mi();
332
- //# sourceMappingURL=background-BijIuvGz.js.map
329
+ `+r+(u.total>30?t(`toolExec.matchListLimitHint`,{count:30}):``),tool_call_id:n}}return{success:!1,error:u.error,tool_call_id:n}}var Wr=null;async function Gr(){let e=chrome.runtime.getURL(`offscreen/offscreen.html`);if(!((await chrome.runtime.getContexts({contextTypes:[`OFFSCREEN_DOCUMENT`],documentUrls:[e]})).length>0)){if(Wr){await Wr;return}Wr=chrome.offscreen.createDocument({url:`offscreen/offscreen.html`,reasons:[`CLIPBOARD`],justification:`用于读写系统剪贴板内容`});try{await Wr}finally{Wr=null}}}async function Kr(e,n,r,i){let{format:a=`text`,selector:o,maxLength:s=15e3,tabId:c}=e,l={text:`GET_PAGE_TEXT`,html:`GET_FULL_HTML`}[a];if(!l)return{success:!1,error:`不支持的格式: ${a},可选: text, html`,tool_call_id:n};try{let e=r?Se(r):null,i=c||e||await Jn();return i?await Yn(i,{type:l,selector:o,maxLength:s},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function qr(e,n,r,i){let{dataType:a,selector:o,filterType:s=`all`,includeHeaders:c=!0,format:l=`json`,includeImages:u=!1,minWidth:d=0,minHeight:f=0,maxResults:p=100,tabId:m}=e;if(!a)return{success:!1,error:t(`toolExec.missingDataType`),tool_call_id:n};let h={table:`EXTRACT_TABLE`,metadata:`EXTRACT_METADATA`,links:`EXTRACT_LINKS`,forms:`EXTRACT_FORMS`,images:`EXTRACT_IMAGES`}[a];if(!h)return{success:!1,error:`不支持的数据类型: ${a},可选: table, metadata, links, forms, images`,tool_call_id:n};try{let e=r?Se(r):null,i=m||e||await Jn();return i?await Yn(i,{type:h,selector:o,filterType:s,includeHeaders:c,format:l,includeImages:u,minWidth:d,minHeight:f,maxResults:p},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function Jr(e,n){let{action:r,text:i,format:a=`text`}=e;if(!r)return{success:!1,error:t(`toolExec.missingAction`),tool_call_id:n};if(r===`copy`)return Yr({text:i},n);if(r===`paste`)return Xr({},n);if(r===`get_selected`)try{let e=await Jn();return e?await Yn(e,{type:`GET_SELECTED_CONTENT`,format:a},n):{success:!1,error:t(`toolExec.noTabAvailable`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}return{success:!1,error:`不支持的操作: ${r},可选: copy, paste, get_selected`,tool_call_id:n}}async function Yr(e,n){let{text:r}=e;if(r==null)return{success:!1,error:t(`toolExec.missingText`),tool_call_id:n};try{await Gr();let e=await chrome.runtime.sendMessage({type:`COPY_TO_CLIPBOARD`,text:r});return e?.success?{success:!0,message:e.message||t(`toolExec.copiedToClipboard`),tool_call_id:n}:{success:!1,error:e?.error||t(`toolExec.copyFailed`),tool_call_id:n}}catch(e){return{success:!1,error:e.message,tool_call_id:n}}}async function Xr(e,t){try{await Gr();let e=await chrome.runtime.sendMessage({type:`PASTE_FROM_CLIPBOARD`});return e?.success?{success:!0,text:e.text,tool_call_id:t}:{success:!1,error:e?.error||`粘贴失败`,tool_call_id:t}}catch(e){return{success:!1,error:e.message,tool_call_id:t}}}async function Zr(e,t=`kill`){console.log(`[Background] cancelrunning Agent command,sessionId:`,e,`mode:`,t),yn.add(e);let n=X.get(e);if(!n){console.warn(`[Background] runningAgentCommands not found entry:`,e),setTimeout(()=>{yn.delete(e)},3e3);return}let{execId:r,ws:i,resolve:a,toolCallId:o}=n;console.log(`[Background] find to runningcommand,execId:`,r),X.delete(e),J(e,r,o,-1),a&&(a(),console.log(`[Background] Promise direct resolve,task continuesexec `));try{i.close()}catch{}t===`kill`?Ve(r).then(()=>{console.log(`[Background] stopped Agent command process:`,r)}).catch(e=>{console.warn(`[Background] stop Agent command process failed:`,e.message)}):console.log(`[Background] only disconnect WebSocket,command process continuesrun :`,r),setTimeout(()=>{yn.delete(e)},3e3)}async function Qr(e,n){try{let e=await W(),r=await ke(),i=[];for(let t of e){let e=H(t.id);i.push({id:t.id,name:t.name,url:t.url,reachable:e,disabled:t.disabled||!1,isActive:r?.id===t.id})}let a=i.map(e=>{let n=e.disabled?t(`toolExec.agentStatusDisabled`):e.reachable===!0?t(`toolExec.agentStatusOnline`):e.reachable===!1?t(`toolExec.agentStatusOffline`):t(`toolExec.agentStatusUnknown`),r=e.isActive?t(`toolExec.agentStatusActive`):``;return`- ${e.name} (${e.id}): ${n}${r}`}).join(`
330
+ `);return{success:!0,content:t(`toolExec.agentListContent`,{summary:a,data:JSON.stringify(i,null,2)}),agents:i,activeAgentId:r?.id||null,tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.agentListFailed`,{error:e.message}),tool_call_id:n}}}async function $r(e,n){let{agentId:r,agentName:i}=e;if(!r&&!i)return{success:!1,error:t(`toolExec.missingAgentId`),tool_call_id:n};try{let e=await W(),a;if(r&&(a=e.find(e=>e.id===r)),!a&&i&&(a=e.find(e=>e.name===i),a||=e.find(e=>e.name&&e.name.toLowerCase().includes(i.toLowerCase()))),!a){let a=e.map(e=>`- ${e.name} (${e.id})`).join(`
331
+ `);return{success:!1,error:t(`toolExec.agentNotFound`,{id:r||i,list:a}),tool_call_id:n}}if(a.disabled)return{success:!1,error:t(`toolExec.agentDisabled`,{name:a.name}),tool_call_id:n};if(!await Ae(a.id))return{success:!1,error:t(`toolExec.agentSwitchFailedSimple`,{name:a.name}),tool_call_id:n};let o=H(a.id),s=o===!0?``:t(`toolExec.agentOfflineWarning`);return{success:!0,content:t(`toolExec.agentSwitchSuccess`,{name:a.name,id:a.id,warning:s}),agentId:a.id,agentName:a.name,offline:o!==!0,tool_call_id:n}}catch(e){return{success:!1,error:t(`toolExec.agentSwitchFailed`,{error:e.message}),tool_call_id:n}}}e(`zh`,{bg:{missingSessionId:`缺少 sessionId`,resumingFromCheckpoint:`从 checkpoint 恢复中...`,checkpointNotFound:`未找到可恢复的任务 checkpoint,可能已过期或被清理。请检查 Service Worker 控制台中的诊断日志(搜索 "checkpoint" 关键字)。`,resumeFailed:`恢复失败`,missingSkillName:`缺少技能名称`,fetchFailed:`获取失败`,preparing:`准备中...`,toolPreselect:`工具预筛选`,requestCancelled:`请求已被用户取消`,reactCancelled:`ReAct 循环已被用户取消`,apiCallFailed:`API 调用失败`}}),e(`en`,{bg:{missingSessionId:`Missing sessionId`,resumingFromCheckpoint:`Resuming from checkpoint...`,checkpointNotFound:`No checkpoint found for resumption. It may have expired or been cleaned. Check Service Worker console logs (search "checkpoint").`,resumeFailed:`Resume failed`,missingSkillName:`Missing skill name`,fetchFailed:`Fetch failed`,preparing:`Preparing...`,toolPreselect:`Tool Pre-filter`,requestCancelled:`Request was cancelled by user`,reactCancelled:`ReAct loop was cancelled by user`}}),n(),Promise.all([j().then(()=>le()),Oe()]).then(([e,t])=>{r.debug(`[Background] DB self-check passed,current has ${e.length} checkpoint`+(t?`,completedoldformat Agent migrate`:``))}).catch(e=>{r.warn(`[Background] cleanup expired checkpoint or DB self-check failed:`,e)});var ei=1e3,Q=null,ti=null,ni=new Map,$=null;chrome.storage.local.get(`_detachWindowId`,e=>{$=e._detachWindowId||null,$&&chrome.windows.get($).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})})}),chrome.runtime.onConnect.addListener(async e=>{if(e.name?.startsWith(`keepalive-`)){let t=e.name.replace(`keepalive-`,``),n=ni.has(t);if(ni.set(t,e),r.debug(`[Background] keepalive portconnected, sessionId:`,t,n?`(reconnect)`:`(first times)`),n&&!Nt.has(t)){r.warn(`[Background] ⚠️ detected SW re started,sessionId`,t,` API call lost`);let n=null;try{let e=await P(t);e&&(n={iteration:e.iteration,interruptedReason:e.interruptedReason,updatedAt:e.updatedAt,messageCount:e.currentMessages?.length||0,subtaskPlan:e.subtaskPlan?{subtaskCount:e.subtaskPlan.subtasks?.length||0}:null},r.debug(`[Background] detected recoverable checkpoint:`,n))}catch(e){r.warn(`[Background] read checkpoint failed:`,e.message)}try{e.postMessage({type:`SW_RESTARTED`,sessionId:t,checkpoint:n})}catch(e){r.warn(`[Background] send SW_RESTARTED message failed:`,e.message)}}e.onDisconnect.addListener(()=>{ni.delete(t),r.debug(`[Background] keepalive port disconnected, sessionId:`,t)})}}),chrome.sidePanel?.setPanelBehavior?.({openPanelOnActionClick:!1}),chrome.action.onClicked.addListener(e=>{if($){try{chrome.windows.update($,{focused:!0}).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})})}catch{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})}return}chrome.sidePanel?.open?.({tabId:e.id}).catch(()=>{})}),chrome.windows.onRemoved.addListener(e=>{$===e&&($=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),r.debug(`[Background] detached window closed, cleaned up windowId:`,e))}),chrome.tabs.onUpdated.addListener((e,t,n)=>{t.status===`complete`&&n.url?.startsWith(`http`)&&chrome.sidePanel?.setOptions?.({enabled:!0})}),chrome.commands?.onCommand?.addListener(e=>{if(e===`_toggle_sidepanel`)try{if($){try{chrome.windows.update($,{focused:!0}).catch(()=>{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})})}catch{$=null,chrome.storage.local.remove(`_detachWindowId`).catch(()=>{})}return}chrome.extension.getViews({type:`side_panel`}).length>0?chrome.runtime.sendMessage({type:`CLOSE_SIDEPANEL`}).catch(e=>{r.warn(`[Background] send CLOSE_SIDEPANEL failed:`,e?.message)}):chrome.tabs.query({active:!0,currentWindow:!0},e=>{e[0]?.id&&chrome.sidePanel?.open?.({tabId:e[0].id}).catch(e=>{r.warn(`[Background] open sidePanel failed:`,e?.message)})})}catch(e){r.warn(`[Background] toggle sidePanel exception:`,e?.message)}}),chrome.runtime.onMessage.addListener((e,n,i)=>{if(e.type===`IFRAME_SELECTION`){let t=n.tab?.id;return t&&chrome.tabs.sendMessage(t,{type:`IFRAME_SELECTION`,text:e.text,x:e.x,y:e.y},{frameId:0}).catch(()=>{}),!1}if(e.type===`IFRAME_CLICK_DISMISS`){let e=n.tab?.id;return e&&chrome.tabs.sendMessage(e,{type:`IFRAME_CLICK_DISMISS`}).catch(()=>{}),!1}if(e.type===`IFRAME_SELECTION_CLEAR`){let e=n.tab?.id;return e&&chrome.tabs.sendMessage(e,{type:`IFRAME_SELECTION_CLEAR`}).catch(()=>{}),!1}if(e.type===`CANCEL_REACT`){let{tabId:t,sessionId:n}=e;return n?(he(n),Zr(n)):he(t),!1}if(e.type===`GET_CHECKPOINT`){let{sessionId:t}=e;return t?(P(t).then(e=>{if(!e){i({exists:!1});return}i({exists:!0,checkpoint:{iteration:e.iteration,interruptedReason:e.interruptedReason,updatedAt:e.updatedAt,messageCount:e.currentMessages?.length||0,subtaskPlan:e.subtaskPlan?{subtaskCount:e.subtaskPlan.subtasks?.length||0}:null}})}).catch(e=>{r.warn(`[Background] GET_CHECKPOINT query failed:`,e),i({exists:!1})}),!0):(i({exists:!1}),!1)}if(e.type===`DELETE_CHECKPOINT`){let{sessionId:t}=e;return t?ie(t).then(e=>{i({success:e})}).catch(e=>{r.warn(`[Background] DELETE_CHECKPOINT failed:`,e),i({success:!1})}):i({success:!1}),!0}if(e.type===`RESUME_REACT`){let{sessionId:n,callId:a,userGuidance:o=``}=e;if(!n)return i({error:t(`bg.missingSessionId`)}),!1;r.debug(`[Background] recei to RESUME_REACT,sessionId:`,n,`userGuidance:`,o?`"${o.substring(0,50)}..."`:`( no )`);let s=Nt.has(n),c=()=>{L(n);let e={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.resumingFromCheckpoint`),status:`processing`,executionLog:[],sessionId:n};a&&(e.callId=a),chrome.runtime.sendMessage(e).catch(()=>{}),Ut(n,o,a).then(e=>{if(!e){r.warn(`[Background] RESUME_REACT: not found checkpoint or restore failed`),P(n).then(e=>{r.warn(`[Background] RESUME_REACT: re-query checkpoint result:`,e?`exists`:`not found`)}).catch(()=>{}),chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:n,callId:a,error:t(`bg.checkpointNotFound`),executionLog:[],resumed:!0}).catch(()=>{});return}r.debug(`[Background] RESUME_REACT complete,content length:`,e.content?.length);let i=(e.executionLog||[]).length>ei?e.executionLog.slice(-1e3):e.executionLog||[];chrome.runtime.sendMessage({type:`API_COMPLETE`,sessionId:n,callId:a,content:e.content||``,executionLog:i,reflectionScore:e.reflectionScore,reasoningContent:e.reasoningContent||null,wasRevised:e.wasRevised||!1,resumed:!0}).catch(e=>{r.warn(`[Background] send RESUME completemessage failed:`,e)})}).catch(e=>{let i=e.name===`AbortError`||e.message===t(`bg.requestCancelled`)||e.message===t(`bg.reactCancelled`);r.debug(`[Background] RESUME_REACT failed:`,i?`(usercancel)`:e.message);let o=e.executionLog||[],s=o.length>ei?o.slice(-1e3):o;chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:n,callId:a,error:e.message||t(`bg.resumeFailed`),executionLog:s,resumed:!0}).catch(()=>{})})};return s?(r.debug(`[Background] RESUME_REACT: detectedoldtaskstill running , first cancel`),he(n),Zr(n),setTimeout(c,300)):c(),!1}if(e.type===`TERMINATE_COMMAND`){let{sessionId:t,mode:n}=e;return t&&Zr(t,n||`kill`),!1}if(e.type===`ABORT_CURRENT_TOOL`){let{sessionId:t}=e;return i({success:we(t)}),!1}if(e.type===`RELOAD_MCP_TOOLS`)return Q=null,On().then(e=>{i({success:!0,count:e})}).catch(e=>{i({success:!1,error:e.message})}),!0;if(e.type===`GET_MCP_TOOLS`){let e=Date.now();return Q&&e-Q.loadedAt<3e4?(r.debug(`[Background] GET_MCP_TOOLS usingcache (${Q.tools.length} tool,${Math.round((e-Q.loadedAt)/1e3)}s before )`),i({success:!0,tools:Q.tools}),!0):(On().then(e=>{let t=f.filter(e=>e.id.startsWith(`mcp_`)).map(e=>({id:e.id,name:e.function?.name||e.id,description:e.function?.description||``,category:e.category||`mcp`,execution:e.execution||`background`,parallelizable:e.parallelizable!==!1,requiresConfirmation:e.requiresConfirmation||!1,enabled:!0}));Q={tools:t,loadedAt:Date.now()},r.debug(`[Background] GET_MCP_TOOLS return ${t.length} tool ( reloads ${e} )`),i({success:!0,tools:t})}).catch(e=>{i({success:!1,error:e.message})}),!0)}if(e.type===`GET_AGENT_SKILL_PROMPTS`){let t=Date.now(),n=e.skillNames||null;return!n&&ti&&t-ti.loadedAt<6e4?(i({success:!0,prompts:ti.prompts}),!0):((n&&n.length>0?$e(n):Qe()).then(e=>{let t=e.success&&e.prompts||``;n||(ti={prompts:t,loadedAt:Date.now()}),i({success:!0,prompts:t})}).catch(e=>{i({success:!1,error:e.message})}),!0)}if(e.type===`GET_AGENT_SKILL_PROMPT`){let n=e.name;return n?(et(n).then(e=>{i(e)}).catch(e=>{i({success:!1,error:e.message})}),!0):(i({success:!1,error:t(`bg.missingSkillName`)}),!0)}if(e.type===`GET_SKILL_LIST`)return Ke().then(e=>{e?.success?i({success:!0,skills:e.skills||[]}):i({success:!1,skills:[],error:e?.error||t(`bg.fetchFailed`)})}).catch(e=>{i({success:!1,skills:[],error:e.message})}),!0;if(e.type===`CAPTURE_TAB`)return chrome.tabs.captureVisibleTab(null,{format:`jpeg`,quality:100},e=>{chrome.runtime.lastError?(r.error(`[Background] screenshot failed:`,chrome.runtime.lastError.message),i({error:chrome.runtime.lastError.message})):i({dataUrl:e})}),!0;if(e.type===`CAPTURE_TAB_FROM_PAGE`)return chrome.tabs.captureVisibleTab(null,{format:`jpeg`,quality:100},e=>{chrome.runtime.lastError?r.error(`[Background] pageshortcutscreenshot failed:`,chrome.runtime.lastError.message):chrome.runtime.sendMessage({type:`SCREENSHOT_RESULT`,dataUrl:e,mode:`full`}).catch(()=>{})}),!0;if(e.type===`CAPTURE_REGION_FROM_PAGE`){let e=n.tab?.id;return e?(chrome.tabs.sendMessage(e,{type:`START_REGION_SELECTION`},e=>{e&&chrome.tabs.captureVisibleTab(null,{format:`png`},t=>{chrome.runtime.lastError?r.error(`[Background] region screenshot failed:`,chrome.runtime.lastError.message):chrome.runtime.sendMessage({type:`SCREENSHOT_RESULT`,dataUrl:t,mode:`region`,rect:e}).catch(()=>{})})}),!0):!1}if(e.type===`CALL_API`){let{messages:n,model:i,useTools:a,tabId:o,apiParams:s,sessionId:c,imageApiBase:l,imageApiKey:u,agentId:d,agentToolIds:f,agentSkillIds:p,callId:m}=e;l&&(s.imageApiBase=l),u&&(s.imageApiKey=u),L(c);let h={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.preparing`),status:`processing`,executionLog:[]};return c&&(h.sessionId=c),m&&(h.callId=m),chrome.runtime.sendMessage(h).catch(()=>{}),r.debug(`[Background] recei to CALL_API message,sessionId:`,c,`useTools:`,a,`tabId:`,o,`apiParams:`,s),(a?(async()=>{let e=await zn(f,d,p);if(e.length===0)return r.debug(`[Background] no available tools, skip pre-filter, direct normal conversation`),Xt(n,i,s,c,{},m);r.debug(`[Background] get to ${e.length} tool`);let a=(await z()).reactConfig.enableToolPreselect,l;if(a?l=await vt(n,i,e,s):(r.debug(`[Background] toolpre-filterclosed,using alltool`),l={type:`tools`,tools:e,executionLog:[]}),l.executionLog.length>0){let e={type:`EXECUTION_STATUS_UPDATE`,nodeName:t(`bg.toolPreselect`),status:`success`,executionLog:l.executionLog};c&&(e.sessionId=c),m&&(e.callId=m),r.debug(`[Background] sendpre-filterstateupdate:`,e),chrome.runtime.sendMessage(e).then(()=>{r.debug(`[Background] pre-filterstateupdatesend successful`)}).catch(e=>{r.error(`[Background] pre-filterstateupdatesend failed:`,e)})}if(l.type===`answer`)return r.debug(`[Background] pre-filtermodeldirect answer,skip mainmodelcall with `),{content:l.content,executionLog:l.executionLog};let{tools:u,executionLog:h}=l;r.debug(`[Background] after pre-filter ${u.length} tool`),r.debug(`[Background] pre-filter executionlog:`,JSON.stringify(h).substring(0,500)),h.length>0&&chrome.runtime.sendMessage({type:`STREAM_PRESELECT`,sessionId:c,callId:m,preselectLog:h}).catch(()=>{});let g=await Wt(n,i,u,o,s,c,null,null,{value:1},h,m);return r.debug(`[Background] ReAct complete,executionLog total:`,g.executionLog?.length),{content:g.content===void 0?g:g.content,executionLog:g.executionLog||h,reflectionScore:g.reflectionScore,wasRevised:g.wasRevised||!1,reasoningContent:g.reasoningContent||null}})():Xt(n,i,s,c)).then(e=>{let t=e.content===void 0?e:e.content,n=e.executionLog||[],o=e.reflectionScore,s=e.wasRevised||!1,l=e.reasoningContent||null;e.usage&&(yt({sessionId:c,model:i||``,usage:e.usage,callType:`non_stream`}).catch(()=>{}),n.length===0&&(n=[{nodeType:`api_call`,nodeName:`API Call`,status:`success`,timestamp:new Date().toISOString(),apiResponse:{tokenUsage:e.usage}}])),r.debug(`[Background] API call complete,content length:`,t.length,`execution logcount:`,n.length),console.log(`[Background API_COMPLETE] useTools:`,a,`| executionLog entries:`,n.length,`| agent_file entries:`,n.filter(e=>e.nodeType===`tool_exec`&&e.action?.name===`agent_file`).length,`| first few types:`,n.slice(0,5).map(e=>`${e.nodeType}${e.action?`(${e.action.name})`:``}`));let u=n.length>ei?n.slice(-1e3):n;chrome.runtime.sendMessage({type:`API_COMPLETE`,sessionId:c,callId:m,content:t,executionLog:u,reflectionScore:o,reasoningContent:l,wasRevised:s}).catch(e=>{r.warn(`[Background] send backmessage failed:`,e)})}).catch(e=>{e.name===`AbortError`||e.message===t(`bg.requestCancelled`)||e.message===t(`bg.reactCancelled`)?r.debug(`[Background] API call with by usercancel`):r.error(`[Background] API call with failed:`,e.message||e);let n=e.executionLog||[],i=n.length>ei?n.slice(-1e3):n;chrome.runtime.sendMessage({type:`API_ERROR`,sessionId:c,callId:m,error:e.message||t(`bg.apiCallFailed`),executionLog:i}).catch(e=>{r.warn(`[Background] send errormessage failed:`,e)})}),!1}if(e.type===`GET_SESSION`)return z().then(e=>{i({modelName:e.modelName})}),!0;if(e.type===`GET_CHAT_CONFIG`)return Ee().then(e=>{i(e)}),!0;if(e.type===`GET_PERMANENT_NOTES`)return cn().then(e=>{if(!e.success){i({success:!1,facts:[],error:e.error});return}i({success:!0,facts:(e.data.facts||[]).sort((e,t)=>(t.importance||0)-(e.importance||0))})}).catch(e=>{i({success:!1,facts:[],error:e.message})}),!0;if(e.type===`OPEN_OPTIONS_PAGE`){let t=e.hash||``;return chrome.runtime.openOptionsPage(()=>{t&&chrome.tabs.query({url:chrome.runtime.getURL(`options.html`)+`*`},e=>{e.length>0&&chrome.tabs.update(e[0].id,{url:chrome.runtime.getURL(`options.html`)+`#`+t})})}),!1}if(e.type===`DETACH_SIDEPANEL`){let t=Math.min(Math.max(e.width||480,320),900);return(async()=>{try{let e=null;if(n.tab?.windowId)try{e=await chrome.windows.get(n.tab.windowId)}catch{}if(!e)try{e=await chrome.windows.getLastFocused()}catch{}let a=e?Math.max(e.left,Math.round(e.left+(e.width-t)/2)):void 0,o=e?Math.max(e.top,Math.round(e.top+(e.height-720)/2)):void 0,s=await chrome.windows.create({url:chrome.runtime.getURL(`side_panel.html`)+`?popup=1`,type:`popup`,width:t,height:720,left:a,top:o});$=s.id,await chrome.storage.local.set({_detachWindowId:s.id}).catch(()=>{}),r.debug(`[Background] sidePanel detached, windowId:`,s.id),i({success:!0,windowId:s.id})}catch(e){r.warn(`[Background] detach sidePanel failed:`,e?.message),i({success:!1,error:e?.message})}})(),!0}if(e.type===`ATTACH_SIDEPANEL`)return $=null,e.windowId&&chrome.windows.remove(e.windowId).catch(()=>{}),chrome.storage.local.remove(`_detachWindowId`).catch(()=>{}),chrome.tabs.query({active:!0,currentWindow:!0},e=>{e[0]?.id&&chrome.sidePanel?.open?.({tabId:e[0].id}).catch(e=>{r.warn(`[Background] open sidePanel after attach failed:`,e?.message)})}),i({success:!0}),!1;if(e.type===`SELECTION_TOOLBAR_ACTION`){let{prompt:i,action:a,text:o,systemPrompt:s}=e,c=n.tab?.id,l=n.frameId;if(r.debug(`[Background] received selected text toolbar operation:`,a,`tabId:`,c),a===`ai-search`)return!chrome.extension.getViews().some(e=>e.location?.search?.includes(`popup=1`))&&c&&chrome.sidePanel.open({tabId:c}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),ri(i,o,c),!1;let u=[{role:`system`,content:s||{explain:`你正在处理用户在网页上选中的内容。用1-3句简洁解释选中内容,必要时补充一个简短示例。不要展开长篇论述。`,translate:`你正在处理用户在网页上选中的内容。自动检测语言:中文→英文,英文→中文,其他语言→同时给出中英文。只输出翻译结果,不添加额外说明。`,summary:`你正在处理用户在网页上选中的内容。用3-5个要点总结选中内容,每条要点一句话,提炼核心信息即可。`}[a]||`你正在处理用户在网页上选中的内容,请用简洁的语言回答用户的问题。`},{role:`user`,content:i}];return L(),z().then(async e=>{try{if(e.streamConfig?.streamEnabled!==!1&&c){let t=`toolbar_${c}_${Date.now()}`,n=await Xt(u,e.modelName,{},t,{sendFn:e=>chrome.tabs.sendMessage(c,e,{frameId:l}).catch(()=>{}),typePrefix:`SELECTION_TOOLBAR_`}),i=n.content===void 0?n:n.content;n.usage&&yt({sessionId:`selection_toolbar`,model:e.modelName,usage:n.usage,callType:`stream`}).catch(()=>{}),r.debug(`[Background] selected texttoolbarstreaming API complete,content length:`,i.length)}else{let t=await Xt(u,e.modelName,{}),n=t.content===void 0?t:t.content;t.usage&&yt({sessionId:`selection_toolbar`,model:e.modelName,usage:t.usage,callType:`non_stream`}).catch(()=>{}),r.debug(`[Background] selected texttoolbar API complete,content length:`,n.length),c&&chrome.tabs.sendMessage(c,{type:`SELECTION_TOOLBAR_RESULT`,content:n},{frameId:l}).catch(()=>{r.warn(`[Background] send SELECTION_TOOLBAR_RESULT to tab failed`)})}}catch(e){r.error(`[Background] selected texttoolbar API failed:`,e),c&&chrome.tabs.sendMessage(c,{type:`SELECTION_TOOLBAR_RESULT`,error:e.message||t(`bg.apiCallFailed`)},{frameId:l}).catch(()=>{})}}),!1}if(e.type===`FILL_SIDEPANEL_INPUT`){let t=n.tab?.id,i=e.text;return r.debug(`[Background] received follow-upfillrequested :`,i?.substring(0,50)),t&&chrome.sidePanel.open({tabId:t}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),chrome.storage.session.set({pendingFillInput:{text:i,timestamp:Date.now()}}).catch(()=>{}),chrome.runtime.sendMessage({type:`FILL_SIDEPANEL_INPUT`,text:i}).catch(()=>{r.debug(`[Background] Side Panel not open,fillcontentstorage,waiting Side Panel load`)}),!1}if(e.type===`DIRECT_SEND`){let t=n.tab?.id,i=e.text,a=e.selectedText||``;return r.debug(`[Background] received directsendrequested :`,i?.substring(0,50)),t&&chrome.sidePanel.open({tabId:t}).catch(e=>{r.warn(`[Background] open Side Panel failed:`,e?.message||e)}),chrome.storage.session.set({pendingDirectSend:{text:i,selectedText:a,timestamp:Date.now()}}).catch(()=>{}),chrome.runtime.sendMessage({type:`DIRECT_SEND`,text:i,selectedText:a}).catch(()=>{r.debug(`[Background] Side Panel not open,sendcontentstorage,waiting Side Panel load`)}),!1}if(e.type===`TRIGGER_AGENT_HEALTH_CHECK`)return si.clear(),ui(),!1;if(e.type===`OPTIONS_PAGE_OPEN`)return oi=!0,si.clear(),ui(),!1;if(e.type===`OPTIONS_PAGE_CLOSED`)return oi=!1,!1;if(e.type===`AGENT_CONNECTION_CHANGED`)return chrome.runtime.sendMessage({type:`AGENT_CONNECTION_CHANGED`,connected:e.connected,agentId:e.agentId}).catch(()=>{}),e.connected&&e.agentId?(Xe(),ti=null,Q=null,kr(),si.clear(),Ln(),V(e.agentId,!0),pi(),On().then(e=>{e>0&&r.debug(`[Background] switchagent after loaded: ${e} MCP tool`)}).catch(()=>{}),setTimeout(()=>{ui()},3e3)):e.connected||(pi(),Q=null,ti=null,kr(),ui()),!1;if(e.type===`CHECK_FILES_EXIST`){let t=e.paths||[];return t.length===0?(i({success:!0,results:{}}),!1):((async()=>{let e=await Promise.allSettled(t.map(e=>Me(e))),n={};e.forEach((e,r)=>{e.status===`fulfilled`&&e.value.success?n[t[r]]=e.value.exists:n[t[r]]=!0}),i({success:!0,results:n})})(),!0)}if(e.type===`AGENT_RESTART`)return(async()=>{i(await tt())})(),!0;if(e.type===`AGENT_UPDATE`)return(async()=>{i(await nt())})(),!0;if(e.type===`AGENT_STOP`)return(async()=>{i(await rt())})(),!0;if(e.type===`OPEN_LOCAL_PROTOTYPE`)return(async()=>{i(await q(e.path))})(),!0;if(e.type===`DELETE_LOCAL_PROTOTYPE`)return(async()=>{try{let t=e.path.replace(/[\\/][^\\/]+\.html$/,``),n=await Fe(t);n.success?r.debug(`[Background] local prototypefile deleted:`,t):r.warn(`[Background] local prototypefiledelete failed:`,n.error),i(n)}catch(e){r.warn(`[Background] local prototypefiledelete failed:`,e.message),i({success:!1,error:e.message})}})(),!0;if(e.type===`QUERY_AUDIT_LOGS`)return it({category:e.category,limit:e.limit}).then(e=>{i(e)}).catch(e=>{i({success:!1,error:e.message})}),!0});async function ri(e,t,n){r.debug(`[Background] processselected text AI search:`,e.substring(0,50)+`...`),await chrome.storage.session.set({pendingSelectionSearch:{prompt:e,selectedText:t,timestamp:Date.now()}}),chrome.runtime.sendMessage({type:`SELECTION_AI_SEARCH`,prompt:e,selectedText:t}).catch(()=>{r.debug(`[Background] Side Panel not open,searchcontentstorage,waiting Side Panel load`)})}var ii=null,ai=null,oi=!1,si=new Map,ci=new Map;async function li(e){let t=!1,n=5e3;try{let r=new AbortController,i=setTimeout(()=>r.abort(),n),a=await fetch(`${e.url}/api/status`,{signal:r.signal,cache:`no-cache`});clearTimeout(i),t=a.ok}catch{t=!1}if(!t){await new Promise(e=>setTimeout(e,500));try{let r=new AbortController,i=setTimeout(()=>r.abort(),n),a=await fetch(`${e.url}/api/status`,{signal:r.signal,cache:`no-cache`});clearTimeout(i),t=a.ok}catch{t=!1}}return t}async function ui(){try{let e=await W();if(e.length===0){si.size>0&&(si.clear(),Ln(),V(`__global__`,!1),hi(!1,`未配对`));return}let t=await ke(),n=e.filter(e=>!e.disabled),i=oi?n:t&&!t.disabled?[t]:[];if(i.length===0)return;let a=(await Promise.allSettled(i.map(async e=>{let t=await li(e);return si.get(e.id)===t?{agentId:e.id,name:e.name,connected:t,changed:!1}:(si.set(e.id,t),V(e.id,t),r.debug(`[Background] agent ${e.name} status change: ${t?`online`:`offline`}`),{agentId:e.id,name:e.name,connected:t,changed:!0})}))).filter(e=>e.status===`fulfilled`&&e.value.changed).map(e=>e.value);if(a.length>0){Ln();let e=a.find(e=>e.agentId===t?.id);e&&(hi(e.connected,e.connected?`在线`:`离线`,e.agentId),e.connected?(fi(e.agentId),On().then(e=>{e>0&&r.debug(`[Background] Agent after reconnect loaded: ${e} MCP tool`)}).catch(()=>{})):(await An(),Q=null,r.debug(`[Background] Agent disconnect,cleaned MCP tool`),di(t)))}}catch(e){r.warn(`[Background] agenthealth checkexception:`,e.message)}}function di(e){if(!e||e.disabled||ci.get(e.id))return;let t=n=>{if(n>=20){ci.delete(e.id),r.debug(`[Background] agent ${e.name} auto reconnectabandoned (exceed maxretry times)`);return}let i=setTimeout(async()=>{let i=(await W()).find(t=>t.id===e.id);if(!i||i.disabled){ci.delete(e.id),r.debug(`[Background] agent ${e.name} ${i?.disabled?`disable`:`delete`},stopauto reconnect`);return}r.debug(`[Background] agent ${e.name} auto reconnectattempt ${n+1}/20`),await li(e)?(ci.delete(e.id),si.set(e.id,!0),V(e.id,!0),Ln(),hi(!0,`在线`,e.id),mi(e.id),On().then(t=>{t>0&&r.debug(`[Background] Agent ${e.name} reconnect successful,loaded: ${t} MCP tool`)}).catch(()=>{}),r.debug(`[Background] agent ${e.name} auto reconnect successful`)):t(n+1)},15e3);ci.set(e.id,{timer:i,retries:n})};t(0)}function fi(e){let t=ci.get(e);t&&(clearTimeout(t.timer),ci.delete(e))}function pi(){for(let[e,t]of ci)clearTimeout(t.timer);ci.clear()}async function mi(e){try{let t=await ke();t&&t.id===e&&On().then(e=>{e>0&&r.debug(`[Background] active agentafter reconnect loaded: ${e} MCP tool`)}).catch(()=>{})}catch(e){r.warn(`[Background] refreshactive agentstate failed:`,e.message)}}function hi(e,t,n){chrome.runtime.sendMessage({type:`AGENT_STATUS_CHANGE`,connected:e,status:t,agentId:n}).catch(()=>{})}function gi(){_i(),r.debug(`[Background] start Agent health check (30s interval)`),ui(),ii=setInterval(ui,3e4),yi()}function _i(){ii&&(clearInterval(ii),ii=null,si.clear()),bi()}async function vi(){try{let e=await ke();if(!e||e.disabled)return;let t=new AbortController,n=setTimeout(()=>t.abort(),5e3);try{await fetch(`${e.url}/api/heartbeat`,{headers:{Authorization:`Bearer ${e.token}`},signal:t.signal,cache:`no-cache`})}finally{clearTimeout(n)}}catch{}}function yi(){bi(),vi(),ai=setInterval(vi,6e4)}function bi(){ai&&=(clearInterval(ai),null)}gi();
332
+ //# sourceMappingURL=background-SRfrMgVQ.js.map