--- title: "Interactive console" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Interactive console} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- gptr logo Call `peter()` without a prompt from an interactive R console to chat. It uses your current environment and the configured model. Choose a route explicitly with `peter(model = "openai/gpt-6-sol")`. [Language models](language-models.html) covers API, CLI and local setup. On a new console with no explicit or configured model, Peter first offers the Codex CLI, the Claude Code CLI and manual API/Ollama setup. Selecting an installed CLI that reports `Signed in` saves its default model in your user settings and opens the console. `Unknown` permits your explicit choice with a notice; `Not signed in` returns to R with terminal sign-in instructions. CLI-reported login does not verify online access or subscription billing; an API-key login can also count as signed in. Context-sharing acknowledgment remains separate. Manual setup prints API and local Ollama commands and returns to R; cancellation (choose Cancel or press Enter), a missing CLI or a non-CLI replacement of a shortcut also returns without saving a default. Configure a model as shown in [Language models](language-models.html), then call `peter()` again. An existing session, an explicit or effective configured model, `.stdin = TRUE` and noninteractive workflows skip setup. Calls with a prompt use their normal model resolution. The saved default applies in future R sessions and projects unless a higher-priority setting overrides it. Use `gptr_config(model = "provider/model", .scope = "user")` to change it; see [Configuration](configuration.html) for precedence and settings locations. ``` r library(gptr) session = peter() # At peter>, enter: Plot mpg against wt in mtcars. # Then enter: /exit ``` The default prompt is `peter> `; other permission modes appear as `peter[plan]> `, `peter[edits]> ` or `peter[auto]> `. Enter `/exit` to return the session invisibly to `session`. Objects created by the agent remain in the environment where the console runs. R tools compute on those in-memory objects across turns; you can inspect or reuse them at the R prompt without exporting and reloading a dataset. Model context is a separate, bounded description of that workspace; see [Execution model](execution-model.html) for copying and storage. For input piped to an R process, `peter(.stdin = TRUE)` explicitly reads standard input using the same syntax; end of input returns the session. The console UI can consume permission answers from that input too. Configure the model, credentials and permissions before unattended work. For programmatic event streams, select `.opts = list(frontend = "jsonl")`. With `.stdin = TRUE`, that frontend treats every input line as a literal model prompt (or a JSON prompt record); `/exit` and `/quit` end the stream. Slash commands and `!` execution use the console frontend. JSONL stdout contains event records, with human-readable notices on stderr. Continue the same session from R: ``` r session |> peter() # At peter>, enter: Explain the pattern in that plot. # Then enter: /exit ``` Piping uses the session's kept workspace. To explore independently, use `gptr_fork(session) |> peter()`; assignments stay in the fork's overlay; in-place edits of reference objects do not. `/clear` resets the conversation while retaining workspace objects, model and mode. ## Enter prompts, objects and your own R Ask in ordinary language. `@x` attaches a visible R object by name, and `@analysis.R` adds the beginning of a text file. A path of letters and digits in any script, `.`, `_`, `-`, `~` and `/` needs no quotes; quote any other path, such as `@"analysis notes.txt"` (Tab leaves the quotes to you). When no file or object has the whole name, a mention reads its leading ASCII letters, digits, `.`, `_`, `-`, `~` and `/`, so `@x` may run into text written without spaces. A mention is a word that starts with `@`, so `me@example.org` stays text. Files take precedence when a mention matches both a file and an object. A file mention sends at most its first 40 lines, and the files of one prompt share about 2,000 tokens; binary files contribute a description rather than their contents. For a larger file, ask the agent to read the relevant section. Under the prompt you send, a dim line says what each mention attached, such as `@ mtcars (data.frame, 32 x 11)` or `@ analysis.R (first 40 lines)`, or that a name was not found and was sent as text. ```text peter> Compare @mtcars columns mpg and wt. peter> Explain the approach in @analysis.R. peter> !head(mtcars[, c("mpg", "wt")]) peter> Now suggest a diagnostic plot. ``` `!code` runs your R code immediately in the console environment, prints its output and adds a compact note of the code and output to the **next** model prompt. It does not send a prompt or spend model tokens by itself. The note is bounded to about 300 estimated tokens, so inspect large results in R and send the part the model needs. `!!code` also runs immediately, but does not add that code/output note. Changes it makes are still part of the workspace that later calls can inspect or describe. Neither prefix passes through the model's permission gate: you are explicitly running your own R code. Do not paste unreviewed code merely because the agent suggested it. Tab completes only after `@` (objects, then files), `@obj$` (its members), `peter$`, a leading `/` (commands) and on a `!` or `!!` line (R code), never in plain text. This holds in terminal R, R in an IDE's Terminal tab, Windows' Rgui and Rterm, and RStudio's console, which completes only what its popup inserts as offered: the commands after `/` and R code after `!`, not words holding `@` or `$`, which it would wrap in backticks. In a terminal Tab completes a draft typed while Peter works the same way. R.app, radian and Positron's console keep their own completion. gptr never changes RStudio's preferences: as you type in its console, RStudio adds closing brackets and quotes unless `insert_matching` is off, and opens completions unless `console_code_completion` is off (Tools > Global Options > Code). ```text peter> !fit = lm(mpg ~ wt, data = mtcars) peter> !coef(fit) peter> Explain the slope I just fitted. peter> !!local_note = "Check the measurement units later" ``` For multiple lines, use a triple-quoted prompt, a trailing backslash to continue a prompt, or a fenced R block. A fence marked `r`, `R`, `{r}` or unmarked behaves like `!code`; any other fence, such as one marked `python`, is sent as prompt text. Incomplete `!`/`!!` R expressions continue at the `+ ` prompt until they parse. Very long single lines can exceed R's console input limit; use an `@file` or a multiline prompt instead. In CRAN's R for macOS in a terminal a pasted block is one input: its lines join the first one and `... ` waits for Enter, where text you type is added. A pasted fence or `"""` block is read up to its closer at once, a block pasted at an approval or a choice is kept in the console history and the question asked again, and one pasted at the pause menu's `? Steer` or `? Follow-up` is the whole text. A last pasted line without a newline waits for Enter at the next prompt, so a two-line paste without a final newline answers a question with its first line. Homebrew or conda R, Linux terminals, RStudio, R.app, Positron and Windows deliver pasted lines one at a time, as typed lines (at a question the first one answers it), so wrap a multi-line paste in `"""` there. Lines typed, pasted or run from a script before a question appears (an approval, a choice) never answer it: while an answer runs they are queued for the agent as `type_ahead` says (a `/command` or `!code` line waits for the next prompt), otherwise they go to the console history. Answer after the prompt. ```text peter> """ ... Fit mpg on wt. ... Explain the units and give one diagnostic. ... """ ``` ```text peter> ```r ... fit = lm(mpg ~ wt, data = mtcars) ... coef(fit) ... ``` ``` These input forms apply inside Peter's chat; at the ordinary R prompt, use normal R syntax. Console inputs may enter R's history (`gptr.history`), and an enabled transcript can record user-run code. `!!` is a control over the next prompt note, not a privacy boundary. ## Commands These are all built-in slash commands. Arguments in brackets are optional. `/help` lists the commands available in the current session, including any supplied by plugins or prompt templates. | Command | Effect | |---|---| | `/help [command]` | List input syntax and commands, or describe one command. | | `/exit`, `/quit`, `/q` | Leave the chat and return its session. | | `/model [provider/model or alias]` | Show the model or switch it from the next request; keeps the conversation. | | `/mode [plan|manual|edits|auto|yolo]` | Show the mode or switch it from the next turn. | | `/plan` | Switch to plan mode for read-only exploration and a proposed plan. | | `/tools` | List direct tools and `peter$` members. | | `/env [text]` | Describe workspace objects whose names contain the text. | | `/compact [focus]` | Compact the conversation now, optionally emphasizing a topic; may make a model request. | | `/cost` | Show this session's tokens and cost. | | `/context` | Show the token ledger of the last request. | | `/status` | Show session, model, mode, document and queued messages. | | `/clear` | Start a new conversation while retaining workspace objects, model and mode. | | `/resume [id]` | List stored sessions or continue the selected session in this console. | | `/fork` | Continue on a new session with an overlay workspace. | | `/doc [path]` | Show the recording document or bind one; binding authorizes writes to it. | | `/skills` | List discoverable skills. | | `/skill: [request]` | Preload a skill and send the request; without a request, ask the agent to use that skill. | | `/mcp` | List MCP servers. | | `/permissions` | Show the permission rules. | | `/permissions allow|ask|deny|remove ` | Change a rule for this R process, for example `/permissions allow r(fn:saveRDS)`. | | `/retry` | Undo the last turn and send its recovered prompt again, with the `!` notes it was sent with when it is the latest message sent; may make a model request. | | `/undo` | Undo the last turn's restorable objects, files and conversation. | | `/redo` | Redo what the last rewind undid. | | `/rewind [k]` | Offer a rewind menu, or retain turns 1 through `k`. | | `/checkpoints [all]` | List current checkpoints, or all branches when `all` is given. | Undo and rewind report partial restores when something cannot be captured or restored. External side effects are not generally reversible. See `?gptr_rewind` and `?gptr_security` before relying on restoration. ## Approve changes In `manual`, known read-only actions run directly and changes ask for approval under the call they gate, unless a permission rule applies (an allow rule never approves a critical action); you type the answer on the row below. The question lists the flagged calls, riskiest first (at most five; `?` shows all), and offers `y` for this action, `a` for a session rule covering them when one can be written (`p` for the same rule in this project), `n` to deny, and `?` for details. `n ` (or `no, `) denies the action and gives the agent your text as its instruction. A sub-agent's question names it (`? sub-agent A: allow r?`); an answer that is none of these is explained, and five such answers refuse the action. `edits` allows project file edits while still asking about R changes unless an allow rule applies; `auto` allows ordinary actions while retaining critical and secret guards. `plan` offers read-only tools and R calls known to be read-only in a scratch environment, where intermediate bindings can change while the user workspace is preserved. Settings and policies are described in [Configuration](configuration.html) and `?gptr_security`. ## Type while Peter works A message you type while Peter works is queued as one of two kinds. A **steer** reaches the agent at its next step boundary: when the response in flight ends, after the results of all its tool calls. The agent reads it on its very next request, and an answer that was about to end gets one more request; a steer never interrupts a request or a tool. A **follow-up** waits for the whole answer and is then sent as the next prompt, its own run. What you type, and the key that pauses Peter, depend on the console: | Console | Typed while Peter works | Pause key | |---|---|---| | Terminal R on macOS or Linux, an IDE's Terminal tab | a draft: Enter steers, Tab sends a follow-up | Ctrl-C | | TERM=dumb, Emacs shell, ESS | each line, as `type_ahead` says | Ctrl-C | | RStudio, R.app | the next prompt, unless a question reads it | Esc | | Positron | R code, run after `peter()` returns | Ctrl-C | | Windows Rterm | the next prompt, unless a question reads it | Ctrl-C | | Windows Rgui, Jupyter | the next input | none: the key stops the answer | In terminal R and an IDE's Terminal tab what you type is a draft on the bottom row, under the transcript, so it never mixes into the answer; a block pasted there is one message where the terminal supports bracketed paste. The row also shows what Peter is doing and how many messages are queued. Enter sends the draft as a steer, and it shows as your own line where the agent reads it. Tab sends it as a follow-up, which appears at the next `peter>` prompt. With `gptr_config(type_ahead = "follow_up", .scope = "user")` the two keys swap. A draft that starts with `/` or `!` is always a follow-up: `/commands` and `!code` run at the next prompt, in the order typed. Up on an empty draft takes back the newest message not yet delivered, to edit and send again; Ctrl-U clears the draft. A recording document keeps what you sent, steers included ([Record, replay and export](script-as-history.html)). A question (an approval, a choice) waits until you stop typing for a second, or three seconds while the draft has text, so a key meant for the draft never answers it. The draft stays through questions, through Ctrl-C and the pause menu, and to the next prompt, where Enter sends it. Keys typed while R code runs in this R process (the `r` tool) show when it returns. A steer the answer did not take (it ended first) is the next prompt. After an abort or an error nothing you queued is sent: the queued text and the draft go to the console history, and Up recalls them. On the CLI routes (`claude-cli`, `codex`) the agent reads a steer after the CLI's answer, which is often the whole run. RStudio, R.app, Positron and Windows consoles hold what you type until R reads again, so gptr cannot read it while Peter works: - In RStudio, R.app and Windows consoles a line typed during an answer is the next prompt, one prompt per line, unless a question comes first: the question reads the line, queues it as `type_ahead` says and asks again. RStudio hides such a line at its next output, and its bottom row says `typed lines run next`. - Positron's console keeps typed text as R code, which runs after `peter()` returns, and clears it at Ctrl-C. - To steer in these consoles, pause and press `s` (Windows' Rgui cannot pause). In RStudio an Esc first closes RStudio's own completion list, if open, then clears a line being typed, so the menu comes at the next Esc. During `peter("...")` at R's prompt, outside the chat, typed lines stay R's next input in every console. ## Pause, continue and leave The pause key opens a pause menu while an answer or tool runs: - `s` **steer** asks for a new instruction and delivers it at the next step boundary. - `f` **follow-up** queues a prompt: in the chat it is the next prompt, sent once the answer ends; in a `peter("...")` call it is sent when the agent would otherwise stop. - `c` **continue** resumes the work as if it had not paused. - `a` **abort** stops it and retains the partial session; what you queued and the draft go to the history, unsent. - `b` **background**, for a foreground call (a chat turn included) when that experimental capability is available, returns to `peter>` while the run goes on. A key typed right after the pause key answers the menu, and pressing the pause key again aborts. After background, what was queued for after the answer and the draft go to the history, unsent, as after an abort. Another prompt steers the running session; `!!gptr::gptr_wait(gptr::gptr_last())` waits for completion without adding a code/output note to the next prompt. Returning to the chat prompt does not guarantee progress while it waits for input. Under Rscript, background runs advance only inside blocking gptr calls. Inline R tools still occupy the same R process while they execute. At the chat prompt, one interrupt prints a hint; two consecutive interrupts leave the chat. Where an interrupt cannot be resumed (Windows' Rgui, Jupyter) the key stops the answer instead. In a terminal the chat reads keys with the echo off and restores it when it returns, on an error, at an interrupt and at `q()`. If R is killed or crashes while Peter works, type `reset` and press Enter to get the terminal back, its echo and its paste mode. The equivalent session verbs work from R: ``` r gptr_steer(session, "Use the existing fit instead of fitting again.") gptr_steer(session, "Summarize the diagnostics at the end.", as = "follow_up") gptr_wait(session) gptr_cancel(session) ``` For persistent conversation storage, initialize a project with `gptr_init(path)` and review its trust decision. `gptr_sessions()` lists stored sessions, and `gptr_resume(id)` recovers one. [Record, replay and export](script-as-history.html) covers document recording, replay and transcripts; [Language models](language-models.html) covers scripted calls that need no interactive console.