Agent Interactive Terminal:给 LLM 智能体一块能共享的 PTY

前言

给智能体跑命令,最常见的做法是调一次 exec,把标准输出拿回来。这条路上有几个绕不开的问题:程序不会进入交互模式,npm run dev、python 这类需要 TTY 的东西跑不起来;长任务只能等结束,看不到过程;一旦遇到密码提示,密码明文进了对话上下文;人和模型也无法同时用同一个 shell。

本文介绍的插件 AyanamiiRei/agent-interactive-terminal 就是把终端做成一个有身份、有屏幕、有相位、有租约的资源。维护者是 AyanamiiRei,版本 0.6.9,MIT 协议,分类为客户端,星标还很少(目录页记为 2)。

这是什么

一句话:在 DeepSeek Harness 里提供有状态的 PTY 终端会话,模型读的是一份离散的屏幕快照,而不是一条字节流。

它打包了八个 terminal_* 工具、一块实时共享的 xterm 面板,以及不经过模型上下文的密码交接。仓库自述 73 个测试在 Linux 的 Node 20/22 上通过,设计细节见 docs/design.zh.md。

它不依赖任何智能体框架,TerminalRegistry、terminal_* 工具都可以单独拿到自己的运行时里用。

核心功能

屏幕快照,而不是字节流

模型读到的是渲染后的文本屏幕,附上相位和状态行。写是动作,等是查询,状态是事实,三者分开。屏幕只有一份,两种投影:给模型的是文本,给浏览器的是序列化 ANSI。

八个工具

工具 作用
terminal_open 打开会话,返回 id、状态行和初始屏幕
terminal_send 写入文本(默认回车提交),并等待结算
terminal_wait 只等待,不写入
terminal_snapshot 读取屏幕或输出尾部,可按版本号取增量
terminal_key 按下具名按键,如 ctrl-c、enter、page-down
terminal_resize 调整终端尺寸
terminal_close 关闭会话并清理进程树
terminal_list 列出会话、相位、尺寸和目录

人和 agent 共用同一块屏幕

桌面端会话标题栏出现终端图标,点开后右侧是 xterm 面板,会话标签按当前顺序编号,中键关闭。键盘归属规则是:人敲键即接管,停手几秒自动交回;agent 的写入在这段时间排队,上边栏显示排队命令和取消按钮,交还后按顺序执行。

访问级别分三档:collaborate(协作)、observe(只读)、sealed(读写都断开,列表里只剩脱敏记录)。只读和断开都会拒绝排队,并返回不同的错误。授权在会话创建时给定,由服务端执行,不是前端丢按键。

密码不经过模型

遇到密码提示时,wait 返回 human_required 并挂起 agent,由人通过 session.write(secret, { origin: 'human' }) 回答,密码不进入模型上下文。仓库已实现密钥注入和审计。

另有工具策略开关:默认交互式优先,也可切换为一次性命令优先或强制交互式(后者会隐藏 agent 的 bash),还有“主动使用交互式终端”开关,让 REPL 任务先进入 python 等交互环境。

平台支持

优先使用 Unix shell(zsh/bash)。Linux 和 macOS 直接使用本机 zsh/bash,macOS 未设置 $SHELL 时默认 /bin/zsh。Windows 自动寻找 wsl.exe,可用时在 WSL 里启动 zsh(没装 zsh 就用 bash),并把生成的 rc 翻译成 WSL 路径;找不到 WSL 时退回 PowerShell 7、Windows PowerShell 或 cmd.exe。手动选 zsh/bash 但没有 WSL 会明确报错。原生 PowerShell/cmd 没有提示符标记,等待会退回屏幕内容和输出静默判断,精度不如 WSL。

主题、字体、光标、快捷键、回滚、响铃、复制粘贴、租约超时都在终端设置里,主题默认跟随 DSH,也可固定成某一套调色板。

安装与启用

需要 Node.js 20+ 和用于编译 node-pty 的 C++ 工具链。

在 DSH 的 Plugins → Discover 里添加市场索引:

https://raw.githubusercontent.com/AyanamiiRei/agent-interactive-terminal/main/plugin-market.json

搜索 agent-interactive-terminal 安装,或在 Add plugin 里直接填 Git 规格。首次安装要批准 node-pty 的构建脚本;升级到新版本后重启一次 DSH。

也可以手动构建:

git clone https://github.com/AyanamiiRei/agent-interactive-terminal.git
cd agent-interactive-terminal
npm install
npm run build

典型用法

仓库自带三个入口,适合先验证行为再接进 DSH。

npm run demo -- "git status"   # 一条命令,看模型拿到的屏幕和状态行
npm run demo                   # 交互循环:/snap、/wait、/key、/resize、/quit
npm run attach                 # 浏览器 attach 示例,打开终端里打印的地址

在代码里直接用 TerminalRegistry:

import { TerminalRegistry } from 'agent-interactive-terminal'

const sessions = new TerminalRegistry({ maxSessions: 2 })
const session = await sessions.open({ name: 'build', cols: 100, rows: 30 })

await session.write('npm run dev')
const result = await session.wait({ match: ['ready in'], timeoutMs: 60_000 })
console.log(result.outcome, result.view.text)

session.takeOver()
await session.write('y', { origin: 'human' })
session.handBack()
await session.close()

也可以把 createTerminalTools(registry) 交给自己的模型运行时,不一定要跑在 DSH 里。

适用场景与注意

适合这几类需求:需要让 agent 驱动交互式程序(REPL、脚手架、交互式安装器);任务时长不确定、需要看过程而不是等结果;需要人和 agent 轮流操作同一个 shell;需要把密码这类敏感输入留在模型上下文之外。

几点要注意:

  1. 插件以当前 DSH 进程的权限运行,能读到什么、能执行什么就等于 DSH 的权限范围,安装前应通读仓库源码和许可证(MIT)。
  2. 首次安装要批准 node-pty 构建脚本,属于原生模块编译,属于正常动作,但要自己确认过。
  3. npm run attach 的浏览器示例只绑定 127.0.0.1、没有鉴权,仅供本地演示,不要暴露到网络上。
  4. 仓库自述尚未实现:审计之外的打码区间、空闲会话回收、fish 集成,细节见 ROADMAP.md。

结尾

这套做法的价值在于把终端从“执行一条命令”升级成“会话级资源”:屏幕可读、按键可控、等待有条件、密码可隔离、人和 agent 能共享。仓库规模还小(目录页记为 2 颗星、版本 0.6.9),但覆盖的路径是完整的,先跑 npm run demo 就能确认是否符合你的流程。

  • 目录页:https://www.skillhub.cn/plugins/AyanamiiRei/agent-interactive-terminal
  • GitHub:https://github.com/AyanamiiRei/agent-interactive-terminal
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜