diff --git a/wwwroot/api/work_env.dspy b/wwwroot/api/work_env.dspy
index 138a536..b6a63bc 100644
--- a/wwwroot/api/work_env.dspy
+++ b/wwwroot/api/work_env.dspy
@@ -140,12 +140,15 @@ elif action == 'init_remote_env':
return json.dumps({'ok': False, 'error': str(e)}, ensure_ascii=False)
elif action == 'init_remote_env_status':
- # 轮询依赖安装后台任务结果(init_remote_env 返回的 deps_task)。
- from pipeline_service.remote_env_init import get_deps_install_status
- _task = (params_kw or {}).get('task', '')
- if not _task:
- return json.dumps({'ok': False, 'error': '缺少 task 参数'}, ensure_ascii=False)
- return json.dumps(get_deps_install_status(_task), ensure_ascii=False)
+ # 轮询远程依赖安装进度(无状态:读远程进度文件,服务重启后可继续查)。
+ from pipeline_service.remote_env_init import get_deps_install_status as _deps_status
+ _ot = (params_kw or {}).get('owner_type', 'org')
+ try:
+ async with get_sor_context(request._run_ns, 'pipeline') as sor:
+ _r = await _deps_status(sor, _ot, user_id if _ot == 'user' else org_id)
+ return json.dumps(_r, ensure_ascii=False)
+ except Exception as e:
+ return json.dumps({'ok': False, 'error': str(e)}, ensure_ascii=False)
elif action == 'get_org_pubkey':
# 获取机构 public key(供 admin 复制到远程主机 authorized_keys)。仅超管。
diff --git a/wwwroot/sd_org_remote/index.ui b/wwwroot/sd_org_remote/index.ui
index 5c5a4e2..a226ed5 100644
--- a/wwwroot/sd_org_remote/index.ui
+++ b/wwwroot/sd_org_remote/index.ui
@@ -162,7 +162,7 @@
"event": "click",
"actiontype": "script",
"target": "self",
- "script": "var f=bricks.getWidgetById('remote_form',bricks.app);var v=f?f._getValue():{};if(!v.remote_host||!v.remote_dir){bricks.show_error({title:'缺少配置',message:'请先填写远程主机与远程目录并保存'});return;}var btn=this;btn.disabled=true;var body=new URLSearchParams();body.append('action','init_remote_env');body.append('remote_host',v.remote_host);body.append('remote_port',v.remote_port||'22');body.append('remote_user',v.remote_user||'');body.append('remote_dir',v.remote_dir);fetch('/pipeline-sdlc/api/work_env.dspy',{method:'POST',body:body}).then(function(r){return r.json()}).then(function(d){if(!d.ok){btn.disabled=false;bricks.show_error({title:'初始化失败',message:d.error||'未知错误'});return;}var st=d.steps||{};var sk=st.skills||{};var dp=st.deps_found||{};var msg='bwrap: '+((st.bwrap&&st.bwrap.ok)?'✓':'✓')+'
技能同步: '+(sk.synced?sk.synced.join(', '):'✗')+'
待装依赖: '+(dp.specs?dp.specs.length:0)+' 个包(重量级已跳过 '+(dp.heavy_skipped?dp.heavy_skipped.length:0)+' 个)
依赖安装进行中…';bricks.show_message({title:'远程环境初始化',message:msg});var task=d.deps_task;var tries=0;function poll(){if(tries++>60){btn.disabled=false;bricks.show_error({title:'依赖安装超时',message:'超过10分钟未返回结果,请稍后重新点击初始化查询'});return;}fetch('/pipeline-sdlc/api/work_env.dspy?action=init_remote_env_status&task='+encodeURIComponent(task)).then(function(r){return r.json()}).then(function(s){if(s.status==='running'){setTimeout(poll,10000);return;}btn.disabled=false;if(s.ok){bricks.show_message({title:'远程环境初始化完成',message:'依赖安装成功: '+(s.installed?s.installed.length:0)+' 个包
venv: '+(s.venv||'')});}else{bricks.show_error({title:'依赖安装失败',message:(s.error||'')+'
失败包: '+((s.failed||[]).join('; ')||'无')+((s.tail)?'
日志末尾:
'+s.tail.slice(-300):'')});}}).catch(function(e){btn.disabled=false;bricks.show_error({title:'查询失败',message:String(e)});});}setTimeout(poll,8000);}).catch(function(e){btn.disabled=false;bricks.show_error({title:'请求失败',message:String(e)});});"
+ "script": "var f=bricks.getWidgetById('remote_form',bricks.app);var v=f?f._getValue():{};if(!v.remote_host||!v.remote_dir){bricks.show_error({title:'缺少配置',message:'请先填写远程主机与远程目录并保存'});return;}var btn=this;btn.disabled=true;var body=new URLSearchParams();body.append('action','init_remote_env');body.append('remote_host',v.remote_host);body.append('remote_port',v.remote_port||'22');body.append('remote_user',v.remote_user||'');body.append('remote_dir',v.remote_dir);fetch('/pipeline-sdlc/api/work_env.dspy',{method:'POST',body:body}).then(function(r){return r.json()}).then(function(d){if(!d.ok){btn.disabled=false;bricks.show_error({title:'初始化失败',message:d.error||'未知错误'});return;}var st=d.steps||{};var sk=st.skills||{};var dp=st.deps_found||{};var dl=st.deps_launch||{};var msg='bwrap: '+((st.bwrap&&st.bwrap.ok)?'✓':'✓')+'
技能同步: '+(sk.synced?sk.synced.join(', '):'✗')+'
待装依赖: '+(dp.specs?dp.specs.length:0)+' 个包(重量级已跳过 '+(dp.heavy_skipped?dp.heavy_skipped.length:0)+' 个)
依赖安装进行中…';bricks.show_message({title:'远程环境初始化',message:msg});var tries=0;function poll(){if(tries++>60){btn.disabled=false;bricks.show_error({title:'依赖安装超时',message:'超过10分钟未返回结果,请稍后重新点击初始化查询'});return;}fetch('/pipeline-sdlc/api/work_env.dspy?action=init_remote_env_status&owner_type=org').then(function(r){return r.json()}).then(function(s){if(s.status==='running'){setTimeout(poll,10000);return;}btn.disabled=false;if(s.ok){bricks.show_message({title:'远程环境初始化完成',message:'依赖安装成功: '+(s.installed?s.installed.length:0)+' 个包
venv: '+(s.venv||'')});}else{bricks.show_error({title:'依赖安装失败',message:(s.error||'')+'
失败包: '+((s.failed||[]).join('; ')||'无')+((s.tail)?'
日志末尾:
'+s.tail.slice(-300):'')});}}).catch(function(e){btn.disabled=false;bricks.show_error({title:'查询失败',message:String(e)});});}setTimeout(poll,8000);}).catch(function(e){btn.disabled=false;bricks.show_error({title:'请求失败',message:String(e)});});"
}
]
}