QP内容库 Logo
首页
文章
文档
默认分类
关于
登录 →
QP内容库 Logo
首页 文章
文档
默认分类 关于
登录
  1. 首页
  2. 文档
  3. DeepSeek Harness
  4. 子系统
  5. 持久 PTY 会话

持久 PTY 会话

  • 子系统
  • 发布于 2026-09-30
  • 0 次阅读
目录
当前文章没有目录

English | 中文

PTY 后端、ctx.terminals 与面向模型的消费方共享的类型。持久 PTY Agent Note 负责记录决策依据;本页记录来自 packages/terminal/terminal/src/types.ts 的跨包词汇。

标识与就绪

TerminalSessionId 是由服务铸造的branded id。可选名称是拥有者本地的显示元数据;授权比较的是拥有该会话的确切 Agent,而不是名称或猜测的 id。

TerminalWaitReason 说明一次发送为何返回。它与 TerminalSessionStatus 无关:一次发送可能因静默或超时而返回,但顶层 shell 仍然存活;session_exit 表示该 shell 已退出,而不是某个任意的前台子进程已退出。

/** Why one interactive send returned control to its caller. */
type TerminalWaitReason = 'stdin_read' | 'inferred_idle' | 'timeout' | 'session_exit'
/** Top-level PTY process status, independent of a send's wait reason. */
type TerminalSessionStatus =
  | { kind: 'running' }
  | { kind: 'exited'; exitCode: number | null; signal: NodeJS.Signals | null }

后端与活跃会话

后端负责启动某种已注册类型的会话并检测其就绪状态。TerminalSessionService 只在初始化成功后才发布返回的会话,随后负责 id 授权与清理。无法清理部分启动资源时,后端会以 TerminalBackendCleanupError 拒绝启动;这样,资源释放流程既能保留清理失败,也不会用它替换调用方的取消原因。后端会话拥有终端状态,并负责让已捕获的资源完全停稳。

/** Replaceable provider for one PTY session type. */
interface TerminalBackend {
  /** Stable type selected by {@link TerminalSpawnRequest.type}. */
  readonly type: string
  /** Create an unpublished session or reject after cleaning partial resources; cleanup failure uses {@link TerminalBackendCleanupError}. */
  spawn(spec: TerminalBackendSpawnSpec): Promise<TerminalBackendSession>
}
/** Backend-owned live session retained by {@link TerminalSessionService}. */
interface TerminalBackendSession {
  /** Initial bounded terminal output returned from `terminal_open`. */
  readonly motd: string
  /** Top-level process id when one exists. */
  readonly pid?: number
  /** Start one exclusive send operation. */
  startSend(request: TerminalSendRequest): TerminalSendOperation
  /** Read one bounded page from retained scrollback. */
  read(request: TerminalReadRequest): TerminalReadResult
  /** Signal the verified foreground process group. */
  signal(signal: TerminalSignal): Promise<TerminalSignalResult>
  /** Observe top-level process status. */
  status(): TerminalSessionStatus
  /** Idempotently close the captured owned process tree and await quiescence. */
  close(reason: string): Promise<void>
}

发送与保留输出

一个活跃会话同时只接受一个活动发送。该操作向通用后台任务提供读取后即推进的输出游标,并向前台调用方提供最终结果。TerminalReadResult 则为有界的会话 scrollback 单独分页。

/** Live backend-owned send; exactly one may be active per PTY session. */
interface TerminalSendOperation {
  /** Resolves after readiness, timeout, cancellation, or top-level process exit. */
  done: Promise<TerminalSendResult>
  /** Consume output produced since the prior call. */
  readOutput(): TerminalSendRead
  /** Request `SIGINT`; returns false after the operation settled. */
  cancel(): boolean
}
/** Settled result for one foreground or background send. */
interface TerminalSendResult {
  /** Bounded rendered terminal delta remaining at settlement. */
  viewport: string
  /** Why the wait returned; this does not imply arbitrary child-process exit. */
  waitReason: TerminalWaitReason
  /** Top-level session status observed at settlement. */
  sessionStatus: TerminalSessionStatus
  /** Whether output was dropped from the operation or retained scrollback. */
  truncated: boolean
}

归属与持久性

TerminalSessionService 会将一项等待完成的清理附加到确切的拥有者作用域,拒绝其他拥有者的操作,并让会话在后端或工具插件重载期间保持存活。PTY 状态与原始字节仍局限在进程内。模型输入与有界返回输出通过现有 tool/call、tool/result 和任务结果路径持久保存,而不是重复记录 PTY 会话事件。

Cordis API

Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.

ctx.terminals — TerminalSessionService

In-process registry for replaceable PTY backends and exact-Agent sessions.

/**
 * Register one backend type for this effect scope.
 * @param backend - provider with a non-empty unique type.
 * @returns disposer that removes exactly this contribution.
 */
registerBackend(backend: TerminalBackend): () => void

/**
 * List registered backend types in registration order.
 * @returns fresh backend type names.
 */
listBackends(): string[]

/**
 * Create and publish one owner-scoped session after backend setup succeeds.
 * @param owner - exact registered Agent that owns access and cleanup.
 * @param request - backend type plus optional owner-local name and cwd.
 * @param signal - cancellation of unpublished setup.
 * @returns published identity, metadata, status, and MOTD.
 */
async spawn(owner: Agent, request: TerminalSpawnRequest, signal?: AbortSignal): Promise<TerminalSpawnResult>

/**
 * Test whether an exact owner has a published session or unpublished spawn.
 * @param owner - exact live owner to inspect.
 * @returns true across the entire spawn-to-close interval, with no publication gap.
 */
hasOwnerActivity(owner: Agent): boolean

/**
 * Start one exclusive interactive send.
 * @param owner - exact session owner.
 * @param id - target PTY identity.
 * @param request - explicit text, submit behavior, and cancellation.
 * @returns live operation handle for foreground await or task registration.
 */
startSend(owner: Agent, id: TerminalSessionId, request: TerminalSendRequest): TerminalSendOperation

/**
 * Read one bounded scrollback page from an owned session.
 * @param owner - exact session owner.
 * @param id - target PTY identity.
 * @param request - optional newest-relative offset and line count.
 * @returns bounded retained text and pagination metadata.
 */
read(owner: Agent, id: TerminalSessionId, request: TerminalReadRequest = {}): TerminalReadResult

/**
 * Deliver an allowed signal through an owned backend session.
 * @param owner - exact session owner.
 * @param id - target PTY identity.
 * @param signal - allowed POSIX signal name.
 * @returns delivered foreground process-group identity.
 */
signal(owner: Agent, id: TerminalSessionId, signal: TerminalSignal): Promise<TerminalSignalResult>

/**
 * Close one owned session and remove it only after quiescent backend cleanup.
 * @param owner - exact session owner.
 * @param id - target PTY identity.
 * @param reason - diagnostic cleanup reason.
 * @returns true for a newly closed session, false when the same close is already in flight.
 */
async kill(owner: Agent, id: TerminalSessionId, reason: string = 'model request'): Promise<boolean>

/**
 * List fresh snapshots for exactly one owner.
 * @param owner - exact owner whose sessions are visible.
 * @returns owner-visible snapshots in publication order.
 */
list(owner: Agent): TerminalSessionSnapshot[]

Types: Agent

Source: packages/terminal/terminal/src/index.ts

相关文章

工作区

English | 中文 工作区(workspace)是用户工作目录的持久记录:一个建立在规范路径之上的稳定 id、一个显示标题,以及归属于它的会话的有序账本。该子系统是单个包(package)(dsh-workspace,ctx.workspaceRegistry)——一项宿主侧可选能力,不属于

工作流

English | 中文 工作流 seam 允许 agent(智能体)运行由模型编写、会启动 subagent 的编排脚本。与 subagent 一样,它是一项可选能力,不属于 agent loop,因此其类型和操作记录在此处,而非 core.md。与 bash 一样,每个上下文只允许一个引擎实现提

Webhook runtime

English | 中文 Webhook 子系统会把已通过身份验证的外部交付转换为可选的普通根 Session。提供方适配器拥有身份验证与通用 JSON 接收;受信任的程序化规则拥有条件与外部调用;ctx.webhookRuntime 拥有回调生命周期以及基于 Workspace 的 Session

Web 访问

English | 中文 Web 访问 seam 是一个能力 seam,在同一个 ctx.web 服务上横跨两项操作(search 与 fetch),并拆分到多个包:Service Definition(dsh-web,ctx.web + 提供方注册表)、Service Provider(dsh-w

HTTP 服务器

English | 中文 dsh-host-webserver 是 GUI Host 的浏览器 HTTP 载体:它是一个提供 ctx.webServer 的 node:http 插件,包含具名路由注册表、可选的 gzip 响应压缩、index.html 转换回调,以及一个可由插件认领的回退处理器。它

Web Client 架构

English | 中文 Web Client 是由独立加载插件组装而成的浏览器侧 Cordis 应用。它有四个可复用底座:Client Modules 加载插件图,API Gateway 提供类型化 Host 通信,Slots 组合 React UI,Conversation 把 Session

目录
当前文章没有目录

星沉月落夜闻香,素手出锋芒。

Copyright © 2026 quping.com All Rights Reserved. Powered by Halo.
鲁ICP备09092435号