feat: add deepseek-harness workbench plugin and console diagnosis API

- console: GET /api/workflows/{id}, /runs/{run_id}, /runs/{run_id}/diagnosis
  (journal trace + sanitized bounded log tails, workflow/run pairing enforced)
- workbench/: dsh 宿主插件(7 个工作流工具、中文系统提示词、失败监控器、
  本机回环桥接服务)+ 侧边栏面板客户端包(sidebar.footer.action 与
  shell.overlay 追加插槽)+ 降级独立面板 + 一键启动脚本
- adapters/browser: 收敛 looks_like_login_url 到共享层,修复
  jd_main_image_collector 对 gyxx_flow.accounts 的越层导入
- tests: 新端点覆盖;replay_policy 断言对齐已迁移的 catalog(repeatable)
This commit is contained in:
wangyunlong committed 2026-09-04 11:10:16 +08:00
1 parent b124d757b0
commit 01218b2907
26 files changed
+4347 -8

No files matched your search

+55
View File
@@ -0,0 +1,55 @@
/** 工作台桥接服务客户端:所有数据经由 gyxx-workbench 宿主插件的本机回环桥接。 */
export function bridgeBase() {
if (typeof window !== 'undefined') {
if (window.__GYXX_WB_BRIDGE__) return window.__GYXX_WB_BRIDGE__
try {
const saved = window.localStorage?.getItem('gyxx.wb.bridge')
if (saved) return saved
} catch {
// localStorage 不可用时使用默认值
}
}
return 'http://127.0.0.1:8790'
}
async function request(method, path, body) {
const response = await fetch(`${bridgeBase()}${path}`, {
method,
headers: {
accept: 'application/json',
...(body !== undefined
? { 'content-type': 'application/json', 'x-gyxx-workbench': '1' }
: {}),
},
body: body === undefined ? undefined : JSON.stringify(body),
})
let payload
try {
payload = await response.json()
} catch {
payload = { ok: false, error: `桥接服务返回了非 JSON 内容(HTTP ${response.status})` }
}
if (!response.ok) {
throw new Error(payload?.error ?? `桥接服务错误(HTTP ${response.status})`)
}
return payload
}
export const api = {
listWorkflows: () => request('GET', '/bridge/workflows'),
workflowDetail: (workflowId) =>
request('GET', `/bridge/workflows/${encodeURIComponent(workflowId)}`),
workflowRuns: (workflowId, limit = 6) =>
request('GET', `/bridge/workflows/${encodeURIComponent(workflowId)}/runs?limit=${limit}`),
diagnosis: (workflowId, runId) =>
request(
'GET',
`/bridge/workflows/${encodeURIComponent(workflowId)}/diagnosis${runId ? `?run_id=${encodeURIComponent(runId)}` : ''}`,
),
alerts: () => request('GET', '/bridge/alerts'),
markAlertSeen: (id) => request('POST', '/bridge/alerts/seen', { id }),
trigger: (payload) => request('POST', '/bridge/trigger', payload),
cancel: (payload) => request('POST', '/bridge/cancel', payload),
ask: (payload) => request('POST', '/bridge/ask', payload),
}