refactor(tasks): 后台任务改读宿主客户端 jobs 服务,删除自建三条路由
- 新增 src/client/jobs-client.ts:结构探测 ctx.jobs(watchRows / observe / state / kill),引用计数的按会话 roster 订阅、只观测展开的那一行、 跨树去重(无主任务归到承载它的被观测会话,树外 owner 丢弃)。 - 抽屉与输出浮窗改读该服务:行来自推送 roster(状态 / 时长 / owner / 进度), 输出面换 TerminalBlock 显示宿主为观察者流的保留输出(gapBefore → 截断提示、 error → 失败提示),kill 走 jobs.kill(owner, jobId),两击确认不变。 - 自动激活(use-host-feeds)改骑同一条推送 roster;detectNewJob 增加 「观测起点时钟」参数,避免「页面打开时已在跑的任务」被当成新工作。 - 删除 src/jobs-routes.ts(+ tests/jobs-routes.spec.ts)、index.ts 的三条路由、 api.jobsList/jobOutput/jobKill 与 JobOutputResult、context-types 的 SidebarJobsService(换成 SidebarClientJobsService/SidebarJobsSnapshot/ SidebarObservedJob 镜像,SidebarJobView 补 owner/progress)、 页面里的 jobs.list 轮询与 collectTreeJobs。 - 三个 spec 改用假 ctx.jobs 服务(jobs-view 14 例 / 自动激活 12 例 / 页面 20 例):观测只在展开行、切换与关闭释放观测、watch 隐藏时不建立、 卸载时全部释放、无服务时不渲染任务面。 验证:typecheck / lint 通过;pnpm test 1240 passed / 9 skipped;pnpm build + pack 通过。 (cherry picked from commit 7d9b82e73190218f05910433ed520cb90e4d4ab2)
This commit is contained in:
@@ -11,7 +11,6 @@ import type { SidechatLiveEvent, SidechatLogEvent, SidechatThreadInfo } from '..
|
||||
import type {
|
||||
SidebarCreateTeamTaskRequest,
|
||||
SidebarChildLiveView,
|
||||
SidebarJobView,
|
||||
SidebarSessionEvent,
|
||||
SidebarTeamMemberView,
|
||||
SidebarTeamTaskMutationResult,
|
||||
@@ -104,21 +103,6 @@ export interface FsTextResult { kind: 'text'; content: string; truncated: boolea
|
||||
* `head` carries the first bytes (base64) for viewer detect sniffing. */
|
||||
export interface FsBinaryResult { kind: 'binary'; size: number; truncated: boolean; head: string }
|
||||
|
||||
/**
|
||||
* One jobs.output response: the output the MODEL has read so far for the
|
||||
* job (replayed from the owner session's event log — the model's
|
||||
* job_output cursor is never touched, so the pane can never steal the
|
||||
* agent's bytes). `read` is false until the model actually called
|
||||
* job_output for the job.
|
||||
*/
|
||||
export interface JobOutputResult {
|
||||
text: string
|
||||
/** True when the host capped the text at its output limit. */
|
||||
truncated: boolean
|
||||
/** Whether the model has read the job at least once. */
|
||||
read: boolean
|
||||
}
|
||||
|
||||
/** The `subagents.live` response: one row per tree child (and the root). */
|
||||
export type SubagentLiveResult = { live: Record<string, SidebarChildLiveView> }
|
||||
|
||||
@@ -348,30 +332,6 @@ export const api = {
|
||||
/** Cherry-pick one commit onto the current branch. */
|
||||
gitCherryPick: (scope: SessionScope, hash: string, worktree?: string) =>
|
||||
call<{ ok: true }>('git.cherry-pick', gitPayload(scope, worktree, { hash })),
|
||||
/**
|
||||
* The output the model has read so far for one background job (replayed
|
||||
* from the owner session's event log — never the model's job_output
|
||||
* cursor). The scope MUST be the job's OWNER session.
|
||||
*/
|
||||
jobOutput: (scope: SessionScope, id: string, signal?: AbortSignal) =>
|
||||
call<JobOutputResult>('jobs.output', scopePayload(scope, { id }), signal),
|
||||
/**
|
||||
* The background-job list of one session (the Tasks page's jobs section and
|
||||
* the job auto-open trigger). DSH 0.1.7 dropped the client session
|
||||
* snapshot's jobs mirror, so the registry is read through the plugin's own
|
||||
* `jobs.list` route. The registry's access fence admits a job to its OWNER
|
||||
* session (and to unowned jobs) only, so a caller that needs the whole tree
|
||||
* asks once per tree session. A host without the jobs service answers 503:
|
||||
* the rejection is the caller's to degrade from (an empty section).
|
||||
*/
|
||||
jobsList: (sessionId: string, signal?: AbortSignal) =>
|
||||
call<{ jobs: SidebarJobView[] }>('jobs.list', { sessionId }, signal),
|
||||
/** Request cancellation of one background job (live jobs flip to stopping). */
|
||||
jobKill: (scope: SessionScope, id: string, reason?: string) =>
|
||||
call<{ ok: true; outcome: 'requested' | 'already-finished' }>('jobs.kill', scopePayload(scope, {
|
||||
id,
|
||||
...(reason !== undefined ? { reason } : {}),
|
||||
})),
|
||||
/**
|
||||
* One batch live-preview fetch for the whole Subagent tree. The payload is
|
||||
* the already-resolved topology ROOT (not a session scope); the host
|
||||
|
||||
Reference in New Issue
Block a user