internal/repl/repl.go 实现交互式 REPL,对标 TypeScript src/screens/REPL.tsx 的非 UI 逻辑部分。
配置结构
type Config struct {
Client *api.Client
Model string
SystemPrompt string // 覆盖默认 system prompt
MaxTurns int
PermMode string
Printer *output.Printer
InitialPrompt string // 启动时自动执行的初始 prompt
}两种运行方式
Run()(交互模式)
持续读取 stdin,逐行处理,直到 EOF(Ctrl+D)或 Ctrl+C:
printWelcome()
if InitialPrompt != "" → handleInput(InitialPrompt)
loop:
scanner.Scan()
handleInput(line)
维护 r.messages []api.MessageParam 跨轮次对话历史。
RunOnce()(print 模式)
单次执行,用于 --print 参数:
- 添加用户消息到 messages
engine.Run()执行- 打印结果
- 返回
输入分发逻辑
handleInput() 按优先级分发:
| 输入格式 | 处理方式 |
|---|---|
! <cmd> | 直接执行 shell 命令(runBashCommand),不走 LLM |
/help, /exit, /clear 等 | slash 命令(commands.Dispatch) |
| 其他文本 | 追加到 messages,走 LLM 查询 |
特殊 slash 命令返回值
commands.Dispatch 返回特殊字符串触发 REPL 行为:
| 返回值 | 效果 |
|---|---|
\x00CLEAR_HISTORY | 清空对话历史 |
\x00EXIT | 退出 REPL |
\x00COMPACT | 触发 compact(当前返回”未实现”) |
流式输出
在交互模式下,文本通过 OnTextDelta 回调实时打印,thinking 内容用 dim gray 颜色区分(ANSI \033[2m):
OnTextDelta: func(delta string) { fmt.Print(delta) },
OnThinkingDelta: func(delta string) {
fmt.Print("\033[2m" + delta + "\033[0m")
},! 前缀 Shell 执行
任何以 ! 开头的输入直接通过 sh -c(Unix)或 cmd /C(Windows)执行,stdin/stdout/stderr 直传终端,不进入 LLM。
相关页面
- query-engine — LLM 查询执行
- overview — 运行模式对比