From 385c8154ea974a58542bb571536dc08ebfd54667 Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Tue, 16 Dec 2025 22:27:19 +0800 Subject: [PATCH] chore: pause container polling when tab hidden --- .DS_Store | Bin 24580 -> 30724 bytes modules/file_manager.py | 4 ++-- static/src/app.ts | 8 ++++--- .../components/chat/VirtualMonitorSurface.vue | 1 + static/src/stores/resource.ts | 17 ++++++++++++++ sub_agent/core/main_terminal.py | 22 ++++++++++++------ test/.DS_Store | Bin 6148 -> 6148 bytes 7 files changed, 40 insertions(+), 12 deletions(-) diff --git a/.DS_Store b/.DS_Store index 4516de11bd5844ce9a03edbc5035618c08d34b62..de1f64067353ef607806331a11fd910190af5a8b 100644 GIT binary patch delta 2554 zcmd5;Z%kWN6hHU%wPm)@LJN#i%5!X*!6Ze9jOm9*TLRh4KnRizbSo{6&6WZ!9os&X zx#^r@mU+~;_y_&s;)l7BH{+r)f{R%eml)#*7n3EJeVIC!1!H1FjpvoN?><%%{AQEa zci%mKe!p|>IrrY$R#d4`0ZBn_u9oH?^qE&J^dB(4v zT4tOPXl!_aO$TKe#a8LOuy?nzC`DL`UrZ2dE)xxr>Mlmv9paJ3hd<7C3n$kA^T~C% zVwW0X&NkUIJ`#zIC_@`O%*O3H4DQq@$(pOiE*>3Vs<0uPDWx#2djf)dDdm&%=*%jE z(zv;XRSHd4)vidlCa*yrvh9Z!uSIcn9TU0@RBbT`@l4LhJDdJqZtt8_%fh`<9fmNc z1ijY;vCuGgSZQed#Ay2BtaRw*NxZYwl^qtfxD16&7nHh|2ov63KyT@J^wm1oLY!?> z-tB%}K$~1?O4M&X`ePEkvZM{2ct9><@8MXB1E=M7d`qstliRGK`NT~JzA3xWBU=l; za=wsm0(F9FO^b~ekRz+1U||8jkuRDL(AFJ-1kQRK{bnlPamra{j?Wxr_>ZTa$?Qoh zv^12}wUAXilq0PY6ShB$@Ay2Xp9(KgN#eXu(uPi4@)fZu#weZY>p{Z-1TK#i_!D{g(=r_8i98}QG~18Z5UR1sC7nU1{> zEukKM8nyU(HMmT+R%mHFSJ&d}uG%3Hm>vx$cl6??{t0ta;}+?m=0|X*RK}Mc zcNu)IU02T1TWRinML=(_5sU5Rrp`AGZ@N8!^>)vL%fmD?6Y-}`Oz*)V9ual|#_gRr z<|#){?M6%nD*nf-VPWVU5RK}YAu79Sy#@o_Nt83&S_}f1aHg$P`K9AI0lzFR#q0LV z*x%O2?^yqF=`C!NdLyIXsD=L8vKKP|i7sefdSrUKtg~Y`4QLy9!Y(Xd;U?2I^oOGZ OCzZ~}jxmkg82cBrA+5sz delta 998 zcmcIjTS${(82;Yx-=?`A_WN(@T))dap;Gv3R8$DH&3T~IQEX6wyvE}9>i;lw% z5M}RG2vLOIRG58)g#|@WH-dSWH-Q&XAVFOP718IWIm25o-tT+f^MUtGe1pU*PzWJl z8|bPgq>aN&PK&=J64I(4R<;=iIj7|ULj1vKJTh_YkpZ@1r$^CwpF8HqdhvqCx(r7> zo2V$^TTcs`dgoA-iUs@6Gk8=oW0RDnlY6d=8hf!_Dp`UoA>9V3K&zauo2@+jB(D!^ zWy><`kQMNP}uP=h&9)oC&rU$mUJr#{@104=CKg0 zzaR&HZ{CHUiXPC;@9b7_5Lmpl6xd|h3oV=3k_Q5DePEJT71*G%1JQe7F|k!Uu;Dnq2At( z1&+t8qs|Pp;U1oJT6L%QUuu~P;A^J|$DQH|TLckw)fw3jXFuR&*}&9B6R_^45&^55 zjBL0&LGfIx7aOzV=q{+o5tl{SkTu1g@qakxL^Y<-3Vb&-OjNH^wE1%xcAux9V>5?t zQk*TX!UF-hn6KvIHu4kH^QUh43<)XZ=csbpD^8sFETAFgk|1@gNpp_97>QlQ&YIn; HV`l#a)7KU@ diff --git a/modules/file_manager.py b/modules/file_manager.py index c4fd612..1b14e8d 100644 --- a/modules/file_manager.py +++ b/modules/file_manager.py @@ -158,8 +158,8 @@ class FileManager: if full_path.parent == self.project_path: return { "success": False, - "error": "禁止在项目根目录直接创建文件,请先创建或选择子目录(例如 ./data 或 ./docs)。", - "suggestion": "请先创建文件夹,再在该文件夹中创建新文件。" + "error": "禁止在项目根目录直接创建文件,请先创建或选择合适的子目录。", + "suggestion": "然后必须**重新**再次创建文件。" } if self._use_container(): result = self._container_call("create_file", { diff --git a/static/src/app.ts b/static/src/app.ts index 1929628..f5633fb 100644 --- a/static/src/app.ts +++ b/static/src/app.ts @@ -195,9 +195,10 @@ const appOptions = { this.$nextTick(() => { this.autoResizeInput(); }); - this.resourceStartContainerStatsPolling(); - this.resourceStartProjectStoragePolling(); - this.resourceStartUsageQuotaPolling(); + this.resourceBindContainerVisibilityWatcher(); + this.resourceStartContainerStatsPolling(); + this.resourceStartProjectStoragePolling(); + this.resourceStartUsageQuotaPolling(); }, computed: { @@ -563,6 +564,7 @@ const appOptions = { resourceStartUsageQuotaPolling: 'startUsageQuotaPolling', resourceStopUsageQuotaPolling: 'stopUsageQuotaPolling', resourcePollContainerStats: 'pollContainerStats', + resourceBindContainerVisibilityWatcher: 'bindContainerVisibilityWatcher', resourcePollProjectStorage: 'pollProjectStorage', resourceFetchUsageQuota: 'fetchUsageQuota', resourceResetTokenStatistics: 'resetTokenStatistics', diff --git a/static/src/components/chat/VirtualMonitorSurface.vue b/static/src/components/chat/VirtualMonitorSurface.vue index 319f05a..b4ef8da 100644 --- a/static/src/components/chat/VirtualMonitorSurface.vue +++ b/static/src/components/chat/VirtualMonitorSurface.vue @@ -188,6 +188,7 @@
+
diff --git a/static/src/stores/resource.ts b/static/src/stores/resource.ts index fec38ca..4339cf4 100644 --- a/static/src/stores/resource.ts +++ b/static/src/stores/resource.ts @@ -75,6 +75,7 @@ export const useResourceStore = defineStore('resource', { down_bps: null, up_bps: null } as ContainerNetRate, + containerVisibilityBound: false, lastContainerSample: null as ContainerSample | null, containerStatsInFlight: false, containerStatsFailCount: 0, @@ -271,6 +272,22 @@ export const useResourceStore = defineStore('resource', { this.pollContainerStats(); }, this.containerStatsIntervalMs); }, + bindContainerVisibilityWatcher() { + if (this.containerVisibilityBound || typeof document === 'undefined') { + return; + } + const handler = () => { + if (document.hidden) { + this.stopContainerStatsPolling(); + } else { + this.containerStatsFailCount = 0; + this.containerStatsIntervalMs = 500; + this.startContainerStatsPolling(); + } + }; + document.addEventListener('visibilitychange', handler); + this.containerVisibilityBound = true; + }, async pollProjectStorage() { if (this.projectStorageInFlight) { return; diff --git a/sub_agent/core/main_terminal.py b/sub_agent/core/main_terminal.py index 1a02f2e..738174c 100644 --- a/sub_agent/core/main_terminal.py +++ b/sub_agent/core/main_terminal.py @@ -1149,7 +1149,7 @@ class MainTerminal: "type": "function", "function": { "name": "terminal_input", - "description": "向活动终端发送命令或输入。禁止启动会占用终端界面的程序(python/node/nano/vim 等);如遇卡死请结合 terminal_snapshot 并使用 terminal_reset 恢复。", + "description": "向活动终端发送命令或输入。禁止启动会占用终端界面的程序(python/node/nano/vim 等);如遇卡死请结合 terminal_snapshot 并使用 terminal_reset 恢复。默认等待输出120秒,最长300秒,超时会尝试中断并返回已捕获输出。", "parameters": { "type": "object", "properties": { @@ -1167,7 +1167,7 @@ class MainTerminal: }, "timeout": { "type": "number", - "description": "等待输出的最长秒数,默认使用配置项 TERMINAL_OUTPUT_WAIT" + "description": "等待输出的最长秒数,默认120,最大300" } }, "required": ["command"] @@ -1292,11 +1292,15 @@ class MainTerminal: "type": "function", "function": { "name": "run_python", - "description": "执行一次性 Python 脚本,可用于处理二进制或非 UTF-8 文件(如 Excel、Word、PDF、图片),或进行数据分析与验证。请在脚本内显式读取文件并输出结果,避免长时间阻塞。", + "description": "执行一次性 Python 脚本,可用于处理二进制或非 UTF-8 文件(如 Excel、Word、PDF、图片),或进行数据分析与验证。默认超时20秒,最长60秒;超时会尝试中断并返回已捕获输出。", "parameters": { "type": "object", "properties": { - "code": {"type": "string", "description": "Python代码"} + "code": {"type": "string", "description": "Python代码"}, + "timeout": { + "type": "number", + "description": "超时时长(秒),默认20,最大60" + } }, "required": ["code"] } @@ -1306,11 +1310,15 @@ class MainTerminal: "type": "function", "function": { "name": "run_command", - "description": "执行一次性终端命令,适合查看文件信息(file/ls/stat/iconv 等)、转换编码或调用 CLI 工具。禁止启动交互式程序;对已聚焦文件仅允许使用 grep -n 等定位命令。输出超过10000字符将被拒绝,可先限制返回体量。", + "description": "执行一次性终端命令,适合查看文件信息(file/ls/stat/iconv 等)、转换编码或调用 CLI 工具。禁止启动交互式程序;对已聚焦文件仅允许使用 grep -n 等定位命令。默认超时10秒,最长30秒,超时会尝试中断并返回已捕获输出;输出超过10000字符将被截断或拒绝。", "parameters": { "type": "object", "properties": { - "command": {"type": "string", "description": "终端命令"} + "command": {"type": "string", "description": "终端命令"}, + "timeout": { + "type": "number", + "description": "超时时长(秒),默认10,最大30" + } }, "required": ["command"] } @@ -1963,7 +1971,7 @@ class MainTerminal: elif tool_name == "run_python": result = await self.terminal_ops.run_python_code(arguments["code"]) - + elif tool_name == "run_command": result = await self.terminal_ops.run_command(arguments["command"]) diff --git a/test/.DS_Store b/test/.DS_Store index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..bd4d1cfe032c868c7c0da690250d397a34554bbd 100644 GIT binary patch literal 6148 zcmeHKu};H44E2Rdq(Y!>FlJ<=3v;N#7j$7Ow5cd4;UZPtGcm!J@F7fm2LHjceJY94 zLMK!qJMz7Y&(8VYMRAUZ+-Q{#i3UUzLm8t!nhnC^tR0Dhg$JEH4}!beaG7j z`^W(AU7zl#z%`-9{td@7Usjs(+ju=kEVNZfz8n9N>aB?y;o)czv;e_I3cGwefCzmQ(YYZ3zZ3YhXcEI)jdi(jm z9b|XLfHCl|7;wF8oQ<%gP+L2T<64_QZ=o#gS1YbV(2-IMUoORGP!ZS@?f}z(wIVDK O`wAjHu~2NHo+1YW5HK<@2yAX-Ze!Uzfmw@rGdl-A2T%b}