@meistrari/remy-cli 1.22.0-rc.1 → 1.22.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -3
- package/dist/remy.js +410 -100
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ In a session, `Esc` dismisses open command/path suggestions or help before it ca
|
|
|
62
62
|
|
|
63
63
|
Every terminal follow-up is appended as an explicit **Steer**, so it targets the work currently in progress. Queuing a message for a later turn (**Next**) is Web-only for now. Remy can replay sessions containing queued-message dispatch, withdrawal, and failure events. Messages withdrawn or failed before reaching Remy show an activity notice; an active submission ends as cancelled or failed instead of waiting for a turn that never started.
|
|
64
64
|
|
|
65
|
-
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. Remy loads the complete retained conversation before showing the session view, then streams new activity as it arrives. Press `s` to search the loaded page by session ID, title, or number; `Enter` keeps the search active and `Esc` clears it. Press `f` to filter sessions by lifecycle status or `a` to filter by author. Both pickers use checkboxes: Up/Down or `j`/`k` moves, `Space` toggles, Right/`l` checks, Left/`h` clears, `G` and `gg` jump to the last and first option, and `Enter` applies every checked value. An empty picker means all values. Press `s` inside either picker to fuzzy-search its options; `Enter` keeps the matching list and `Esc` cancels the search. Press `Esc` outside search to discard staged checkbox changes. Filters apply to the complete remote result set and reset pagination to its first page. After the dashboard list or repository-review list has focus, Vim keys work too: `j`/`k` move, `h`/`l` go to the previous/next dashboard page (or clear/mark a repository), `G` goes to the last row, and `gg` goes to the first row. Press `Shift+L` in the dashboard to start a logout confirmation. In any message composer, plain `Enter` and `Shift+Enter` submit; `Option+Enter` on macOS (`Alt+Enter` elsewhere) inserts a newline. `Ctrl+J` also inserts a newline for terminals that do not report the Option/Alt modifier. The conversation header keeps the numbered session title on its first line and repository, pull request, work state, elapsed time,
|
|
65
|
+
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. Remy loads the complete retained conversation before showing the session view, then streams new activity as it arrives. Press `s` to search the loaded page by session ID, title, or number; `Enter` keeps the search active and `Esc` clears it. Press `f` to filter sessions by lifecycle status or `a` to filter by author. Both pickers use checkboxes: Up/Down or `j`/`k` moves, `Space` toggles, Right/`l` checks, Left/`h` clears, `G` and `gg` jump to the last and first option, and `Enter` applies every checked value. An empty picker means all values. Press `s` inside either picker to fuzzy-search its options; `Enter` keeps the matching list and `Esc` cancels the search. Press `Esc` outside search to discard staged checkbox changes. Filters apply to the complete remote result set and reset pagination to its first page. After the dashboard list or repository-review list has focus, Vim keys work too: `j`/`k` move, `h`/`l` go to the previous/next dashboard page (or clear/mark a repository), `G` goes to the last row, and `gg` goes to the first row. Press `Shift+L` in the dashboard to start a logout confirmation. In any message composer, plain `Enter` and `Shift+Enter` submit; `Option+Enter` on macOS (`Alt+Enter` elsewhere) inserts a newline. `Ctrl+J` also inserts a newline for terminals that do not report the Option/Alt modifier. The conversation header keeps the numbered session title on its first line and repository, pull request, work state, elapsed time, connection state, and the agent's current `Harness · Model · Effort` on its second line. The header also keeps the last provider-reported context observation across reconnects, such as `Context 50% left · 62,000 used`; when the provider does not report a context window, it shows only used tokens. This is an observation, not a live occupancy guarantee or billing total.
|
|
66
66
|
|
|
67
67
|
If a connected session loses its activity stream, Remy retries for up to two minutes and resumes from the last received event. After the live stream stays connected for at least 30 seconds, the next disconnect starts a fresh retry window. Connections that drop sooner share the existing window and backoff. While a submitted message is still awaiting its outcome, retries continue beyond that window.
|
|
68
68
|
|
|
@@ -86,6 +86,8 @@ Terminal previews show up to 50 content blocks and 8,000 characters per block, w
|
|
|
86
86
|
|
|
87
87
|
Command and attachment feedback share progress, success, failure, and attention indicators. Failed stop requests show the reason and `esc` retry; failed complete/cancel requests restore the message prompt and show the retry command. Logout shows a confirmation with `y` to confirm and `Esc` to cancel.
|
|
88
88
|
|
|
89
|
+
**Change the model or effort:** enter `/model` or `/effort` to pick a new model or reasoning effort for your next message. The model list contains only the session's harness (a Claude session offers Claude models, a Codex session Codex models), in the same order and with the same labels as the new-session wizard. Arrows move, `Enter` stages the pick, and `Esc` closes the picker without changing what is already staged. Nothing is sent until you send a message: the change travels with it and stays the session's setting afterward. Because every terminal follow-up is a Steer, a change sent while Remy is working switches the running turn from its next model request; otherwise it applies from the turn your message starts. The header shows the staged change as `→ Sonnet 5 · High (next message)`, then `(switching…)` until the runtime applies it. The timeline then records `Switched to Sonnet 5 · High` right after your message, or `Switched to Sonnet 5 · High (from next turn)` when the running turn could not switch; its details (`Ctrl+O`) then show the provider's reason when one was given. Picking the current value removes it from the staged change.
|
|
90
|
+
|
|
89
91
|
Enter `/compact` to admit a durable main-thread context compaction control without sending a human message. Remy reports request admission immediately and shows the eventual completed, no-op, failed, or unknown provider result in retained activity. Compaction waits for a safe point and does not interrupt active work or jump ahead of an earlier Next message. While admission is pending, you can keep editing or open other commands; repeated `/compact` invocations do not send another request.
|
|
90
92
|
|
|
91
93
|
Drag to select visible text in any Remy view; Remy copies it to the local clipboard and emits OSC 52 for terminal or remote-session clipboard support, then clears the selection highlight. Published file artifacts show their filename and muted, full web preview URL; open the URL in a browser to select that artifact in its session. Tela Page rows retain their canonical Page URL. Downloads are explicit through `/files`; artifact bytes are never printed in the terminal. When the conversation has focus, press `Tab` to return to the composer.
|
|
@@ -96,6 +98,8 @@ Drag to select visible text in any Remy view; Remy copies it to the local clipbo
|
|
|
96
98
|
| `/complete` | Complete an open session after its active turn stops. |
|
|
97
99
|
| `/cancel` | Cancel the current session, including an active turn. |
|
|
98
100
|
| `/compact` | Admit a main-thread context compaction request without sending a message; the provider result appears in retained activity. |
|
|
101
|
+
| `/model` | Pick a model of the session's harness for your next message. |
|
|
102
|
+
| `/effort` | Pick a reasoning effort for your next message. |
|
|
99
103
|
| `/sessions` | Return to the dashboard. |
|
|
100
104
|
| `/new` | Start another new-session flow. |
|
|
101
105
|
| `/logout` | Sign out of Remy after confirmation. |
|
|
@@ -126,7 +130,7 @@ The interactive dashboard is the recommended path. Use these commands when a scr
|
|
|
126
130
|
remy new --repository owner/repository "Add a health check endpoint"
|
|
127
131
|
```
|
|
128
132
|
|
|
129
|
-
Repeat `--repository` to select more repositories from the same GitHub installation. If you do not select a repository, supply `--installation <github-installation-id>`. Repeat `--attach <path>` to upload files or directories; the 20 MiB per-attachment limit is measured directly for a file and across all regular files before compressing a directory. Remy sends each accepted directory as a gzip-compressed tar archive. Direct creation uses `medium` reasoning unless `--reasoning-effort` overrides it; omit `--model` to use the server's Codex `gpt-6-astra` default. `--model` accepts a Codex model (`gpt-6-astra`, `gpt-
|
|
133
|
+
Repeat `--repository` to select more repositories from the same GitHub installation. If you do not select a repository, supply `--installation <github-installation-id>`. Repeat `--attach <path>` to upload files or directories; the 20 MiB per-attachment limit is measured directly for a file and across all regular files before compressing a directory. Remy sends each accepted directory as a gzip-compressed tar archive. Direct creation uses `medium` reasoning unless `--reasoning-effort` overrides it; omit `--model` to use the server's Codex `gpt-6-astra` default. `--model` accepts a Codex model (`gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna`, `gpt-5.5`) or a Claude model (`claude-opus-5-5`, `claude-sonnet-5`, `claude-fable-5-1`); the model chooses the session's harness, which stays fixed for the session. For example, `remy new --model claude-opus-5-5 --repository owner/repository "Add a health check endpoint"` starts a Claude session. In the interactive wizard, press `m` on the confirm step to cycle through every harness's models, shown as `Codex · GPT 6.0 Astra` or `Claude · Opus 5.5`. `remy new` creates the session from the prompt and flags, then opens it when the terminal is interactive.
|
|
130
134
|
|
|
131
135
|
The branch-suggestion flow belongs to the interactive new-session wizard (`remy`, then `n`). Direct `remy new` creation does not analyze continuation references.
|
|
132
136
|
|
|
@@ -144,6 +148,14 @@ remy --session <session-id> "Add regression coverage for that fix"
|
|
|
144
148
|
|
|
145
149
|
Remy sends the prompt as **Steer**, then opens the conversation. Omitting the prompt only attaches. An explicitly empty prompt is rejected. Use `--` before a prompt beginning with `--` to treat it as text.
|
|
146
150
|
|
|
151
|
+
To change the model or reasoning effort, pass `--model <name>`, `--reasoning-effort <low|medium|high|xhigh>`, or both with the prompt:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
remy --session <session-id> --model claude-sonnet-5 --reasoning-effort high "Finish the migration"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
The change travels with that message and stays the session's setting for later messages. A running turn switches from its next model request; otherwise the change applies from the turn the prompt starts. Either flag without a prompt is rejected, because settings only change with a message. The session keeps its harness, so `--model` must name one of that harness's models; Remy checks this against the session before sending and names the harness's models when it does not match. Omit both flags to keep the current settings.
|
|
158
|
+
|
|
147
159
|
### Automate a session
|
|
148
160
|
|
|
149
161
|
`remy new` and `remy --session` use JSON Lines output automatically when standard input or output is not a terminal. Pass `--no-tui` to choose that mode explicitly; `--json` also selects it.
|
|
@@ -201,7 +213,7 @@ remy update
|
|
|
201
213
|
remy --version | -v
|
|
202
214
|
remy dashboard
|
|
203
215
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
204
|
-
remy --session <session-id> [--no-tui
|
|
216
|
+
remy --session <session-id> [--model <name> --reasoning-effort <low|medium|high|xhigh> --no-tui --json] [prompt]
|
|
205
217
|
```
|
|
206
218
|
|
|
207
219
|
Run `remy <command> --help` for flags and command-specific usage. `remy whoami` prints the saved signed-in identity and organization.
|
package/dist/remy.js
CHANGED
|
@@ -32161,6 +32161,51 @@ var agentPromptSchema = zod_default2.object({
|
|
|
32161
32161
|
blocks: zod_default2.array(wireAgentInputBlockSchema).min(1)
|
|
32162
32162
|
});
|
|
32163
32163
|
|
|
32164
|
+
// ../../packages/agents-protocol/src/agent-model.ts
|
|
32165
|
+
var codexModelIds = [
|
|
32166
|
+
"gpt-6-astra",
|
|
32167
|
+
"gpt-6-sol",
|
|
32168
|
+
"gpt-6-luna",
|
|
32169
|
+
"gpt-5.6-sol",
|
|
32170
|
+
"gpt-5.6-terra",
|
|
32171
|
+
"gpt-5.6-luna",
|
|
32172
|
+
"gpt-5.5",
|
|
32173
|
+
"gpt-5.4",
|
|
32174
|
+
"gpt-5.4-mini",
|
|
32175
|
+
"gpt-5.2"
|
|
32176
|
+
];
|
|
32177
|
+
var claudeModelIds = [
|
|
32178
|
+
"claude-opus-5-5",
|
|
32179
|
+
"claude-sonnet-5",
|
|
32180
|
+
"claude-fable-5-1",
|
|
32181
|
+
"claude-opus-5",
|
|
32182
|
+
"claude-fable-5",
|
|
32183
|
+
"sonnet",
|
|
32184
|
+
"claude-opus-4-8",
|
|
32185
|
+
"opus",
|
|
32186
|
+
"haiku",
|
|
32187
|
+
"claude-opus-4-7",
|
|
32188
|
+
"claude-mythos-preview",
|
|
32189
|
+
"claude-opus-4-6",
|
|
32190
|
+
"claude-sonnet-4-6",
|
|
32191
|
+
"claude-haiku-4-5",
|
|
32192
|
+
"claude-haiku-4-5-20251001",
|
|
32193
|
+
"claude-opus-4-5",
|
|
32194
|
+
"claude-opus-4-5-20251101",
|
|
32195
|
+
"claude-sonnet-4-5",
|
|
32196
|
+
"claude-sonnet-4-5-20250929",
|
|
32197
|
+
"claude-opus-4-1",
|
|
32198
|
+
"claude-opus-4-1-20250805",
|
|
32199
|
+
"claude-opus-4-0",
|
|
32200
|
+
"claude-opus-4-20250514",
|
|
32201
|
+
"claude-sonnet-4-0",
|
|
32202
|
+
"claude-sonnet-4-20250514",
|
|
32203
|
+
"claude-3-haiku-20240307"
|
|
32204
|
+
];
|
|
32205
|
+
var codexModelIdSchema = zod_default2.enum(codexModelIds);
|
|
32206
|
+
var claudeModelIdSchema = zod_default2.enum(claudeModelIds);
|
|
32207
|
+
var agentModelIdSchema = zod_default2.union([codexModelIdSchema, claudeModelIdSchema]);
|
|
32208
|
+
|
|
32164
32209
|
// ../../packages/agents-protocol/src/agent-provider.ts
|
|
32165
32210
|
var agentProviderIdSchema = zod_default2.enum(["codex", "claude"]);
|
|
32166
32211
|
|
|
@@ -32346,6 +32391,12 @@ function objectRejectingKeys(shape, rejectedKeys) {
|
|
|
32346
32391
|
// ../../packages/agents-protocol/src/agent-command.ts
|
|
32347
32392
|
var agentReasoningEffortSchema = zod_default2.enum(["low", "medium", "high", "xhigh", "max"]);
|
|
32348
32393
|
var agentPromptModeSchema = zod_default2.enum(["next", "steer"]);
|
|
32394
|
+
var agentSettingsChangeSchema = zod_default2.strictObject({
|
|
32395
|
+
model: agentModelIdSchema.optional(),
|
|
32396
|
+
reasoningEffort: agentReasoningEffortSchema.optional()
|
|
32397
|
+
}).refine((settings) => settings.model !== undefined || settings.reasoningEffort !== undefined, {
|
|
32398
|
+
message: "A settings change needs a model or a reasoning effort."
|
|
32399
|
+
});
|
|
32349
32400
|
var agentAuthorSchema = zod_default2.object({
|
|
32350
32401
|
name: zod_default2.string().min(1),
|
|
32351
32402
|
email: zod_default2.string().min(1).optional(),
|
|
@@ -32363,7 +32414,8 @@ var sendPromptCommandSchema = runningCommandBaseSchema.extend({
|
|
|
32363
32414
|
origin: zod_default2.enum(["user", "supervisor"]).default("user"),
|
|
32364
32415
|
prompt: agentPromptSchema,
|
|
32365
32416
|
commandId: commandIdSchema,
|
|
32366
|
-
author: agentAuthorSchema.optional()
|
|
32417
|
+
author: agentAuthorSchema.optional(),
|
|
32418
|
+
settings: agentSettingsChangeSchema.optional()
|
|
32367
32419
|
});
|
|
32368
32420
|
var agentNotifyCommandSchema = runningCommandBaseSchema.extend({
|
|
32369
32421
|
type: zod_default2.literal("agent.notify"),
|
|
@@ -32413,107 +32465,57 @@ var agentCommandSchema = zod_default2.union([
|
|
|
32413
32465
|
respondUserInputAgentCommandSchema
|
|
32414
32466
|
]);
|
|
32415
32467
|
|
|
32416
|
-
// ../../packages/agents-protocol/src/agent-model.ts
|
|
32417
|
-
var codexModelIds = [
|
|
32418
|
-
"gpt-6-astra",
|
|
32419
|
-
"gpt-5.6-sol",
|
|
32420
|
-
"gpt-5.6-terra",
|
|
32421
|
-
"gpt-5.6-luna",
|
|
32422
|
-
"gpt-5.5",
|
|
32423
|
-
"gpt-5.4",
|
|
32424
|
-
"gpt-5.4-mini",
|
|
32425
|
-
"gpt-5.2"
|
|
32426
|
-
];
|
|
32427
|
-
var claudeModelIds = [
|
|
32428
|
-
"claude-opus-5-5",
|
|
32429
|
-
"claude-sonnet-5",
|
|
32430
|
-
"claude-fable-5-1",
|
|
32431
|
-
"claude-opus-5",
|
|
32432
|
-
"claude-fable-5",
|
|
32433
|
-
"sonnet",
|
|
32434
|
-
"claude-opus-4-8",
|
|
32435
|
-
"opus",
|
|
32436
|
-
"haiku",
|
|
32437
|
-
"claude-opus-4-7",
|
|
32438
|
-
"claude-mythos-preview",
|
|
32439
|
-
"claude-opus-4-6",
|
|
32440
|
-
"claude-sonnet-4-6",
|
|
32441
|
-
"claude-haiku-4-5",
|
|
32442
|
-
"claude-haiku-4-5-20251001",
|
|
32443
|
-
"claude-opus-4-5",
|
|
32444
|
-
"claude-opus-4-5-20251101",
|
|
32445
|
-
"claude-sonnet-4-5",
|
|
32446
|
-
"claude-sonnet-4-5-20250929",
|
|
32447
|
-
"claude-opus-4-1",
|
|
32448
|
-
"claude-opus-4-1-20250805",
|
|
32449
|
-
"claude-opus-4-0",
|
|
32450
|
-
"claude-opus-4-20250514",
|
|
32451
|
-
"claude-sonnet-4-0",
|
|
32452
|
-
"claude-sonnet-4-20250514",
|
|
32453
|
-
"claude-3-haiku-20240307"
|
|
32454
|
-
];
|
|
32455
|
-
var codexModelIdSchema = zod_default2.enum(codexModelIds);
|
|
32456
|
-
var claudeModelIdSchema = zod_default2.enum(claudeModelIds);
|
|
32457
|
-
var agentModelIdSchema = zod_default2.union([codexModelIdSchema, claudeModelIdSchema]);
|
|
32458
|
-
|
|
32459
32468
|
// ../../packages/agents-protocol/src/agent-presentation.ts
|
|
32460
32469
|
var CODEX_CONTEXT_WINDOW = 272000;
|
|
32461
32470
|
var codexModelPresentation = {
|
|
32462
32471
|
"gpt-6-astra": {
|
|
32463
32472
|
label: "GPT 6.0 Astra",
|
|
32464
|
-
description: "
|
|
32473
|
+
description: "Frontier intelligence for the most demanding work.",
|
|
32465
32474
|
relativeCost: 5,
|
|
32466
32475
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32467
32476
|
isMultiModal: true
|
|
32468
32477
|
},
|
|
32478
|
+
"gpt-6-sol": {
|
|
32479
|
+
label: "GPT 6.0 Sol",
|
|
32480
|
+
description: "Workhorse model for coding and everyday work.",
|
|
32481
|
+
relativeCost: 4,
|
|
32482
|
+
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32483
|
+
isMultiModal: true
|
|
32484
|
+
},
|
|
32485
|
+
"gpt-6-luna": {
|
|
32486
|
+
label: "GPT 6.0 Luna",
|
|
32487
|
+
description: "Fast and affordable model for easier tasks.",
|
|
32488
|
+
relativeCost: 2,
|
|
32489
|
+
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32490
|
+
isMultiModal: true
|
|
32491
|
+
},
|
|
32469
32492
|
"gpt-5.6-sol": {
|
|
32470
32493
|
label: "GPT 5.6 Sol",
|
|
32471
|
-
description: "
|
|
32494
|
+
description: "Older coding model for complex work.",
|
|
32472
32495
|
relativeCost: 5,
|
|
32473
32496
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32474
32497
|
isMultiModal: true
|
|
32475
32498
|
},
|
|
32476
32499
|
"gpt-5.6-terra": {
|
|
32477
32500
|
label: "GPT 5.6 Terra",
|
|
32478
|
-
description: "
|
|
32501
|
+
description: "Older balanced model for straightforward work.",
|
|
32479
32502
|
relativeCost: 3,
|
|
32480
32503
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32481
32504
|
isMultiModal: true
|
|
32482
32505
|
},
|
|
32483
32506
|
"gpt-5.6-luna": {
|
|
32484
32507
|
label: "GPT 5.6 Luna",
|
|
32485
|
-
description: "
|
|
32508
|
+
description: "Older fast and efficient model.",
|
|
32486
32509
|
relativeCost: 2,
|
|
32487
32510
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32488
32511
|
isMultiModal: true
|
|
32489
32512
|
},
|
|
32490
32513
|
"gpt-5.5": {
|
|
32491
32514
|
label: "GPT 5.5",
|
|
32492
|
-
description: "
|
|
32515
|
+
description: "Legacy coding model.",
|
|
32493
32516
|
relativeCost: 4,
|
|
32494
32517
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32495
32518
|
isMultiModal: true
|
|
32496
|
-
},
|
|
32497
|
-
"gpt-5.4": {
|
|
32498
|
-
label: "GPT 5.4",
|
|
32499
|
-
description: "Strong model for everyday coding.",
|
|
32500
|
-
relativeCost: 3,
|
|
32501
|
-
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32502
|
-
isMultiModal: true
|
|
32503
|
-
},
|
|
32504
|
-
"gpt-5.4-mini": {
|
|
32505
|
-
label: "GPT 5.4 Mini",
|
|
32506
|
-
description: "Small, fast, and cost-efficient model for simpler coding tasks.",
|
|
32507
|
-
relativeCost: 2,
|
|
32508
|
-
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32509
|
-
isMultiModal: true
|
|
32510
|
-
},
|
|
32511
|
-
"gpt-5.2": {
|
|
32512
|
-
label: "GPT-5.2",
|
|
32513
|
-
description: "Optimized for professional work and long-running agents.",
|
|
32514
|
-
relativeCost: 3,
|
|
32515
|
-
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32516
|
-
isMultiModal: true
|
|
32517
32519
|
}
|
|
32518
32520
|
};
|
|
32519
32521
|
var CLAUDE_CONTEXT_WINDOW = 1e6;
|
|
@@ -32553,7 +32555,15 @@ var agentReasoningEffortPresentation = {
|
|
|
32553
32555
|
var selectableAgentReasoningEfforts = ["low", "medium", "high", "xhigh"];
|
|
32554
32556
|
|
|
32555
32557
|
// ../../packages/agents-protocol/src/agent-catalog.ts
|
|
32556
|
-
var selectableCodexModelIds =
|
|
32558
|
+
var selectableCodexModelIds = [
|
|
32559
|
+
"gpt-6-astra",
|
|
32560
|
+
"gpt-6-sol",
|
|
32561
|
+
"gpt-6-luna",
|
|
32562
|
+
"gpt-5.6-sol",
|
|
32563
|
+
"gpt-5.6-terra",
|
|
32564
|
+
"gpt-5.6-luna",
|
|
32565
|
+
"gpt-5.5"
|
|
32566
|
+
];
|
|
32557
32567
|
var selectableClaudeModelIds = [
|
|
32558
32568
|
"claude-opus-5-5",
|
|
32559
32569
|
"claude-sonnet-5",
|
|
@@ -32901,6 +32911,19 @@ var sessionConfiguredAgentEventSchema = agentSessionEventBaseSchema.extend({
|
|
|
32901
32911
|
environment: zod_default2.record(zod_default2.string().min(1), zod_default2.literal("[REDACTED]"))
|
|
32902
32912
|
})
|
|
32903
32913
|
});
|
|
32914
|
+
var agentSettingsAppliesFromSchema = zod_default2.enum(["current_turn", "next_turn"]);
|
|
32915
|
+
var currentTurnUnavailableReasonMaxLength = 300;
|
|
32916
|
+
var sessionSettingsChangedAgentEventSchema = agentSessionEventBaseSchema.extend({
|
|
32917
|
+
type: zod_default2.literal("session.settings.changed"),
|
|
32918
|
+
payload: zod_default2.object({
|
|
32919
|
+
model: zod_default2.string().min(1),
|
|
32920
|
+
reasoningEffort: zod_default2.string().min(1).optional(),
|
|
32921
|
+
commandId: zod_default2.string().min(1),
|
|
32922
|
+
turnId: zod_default2.string().min(1).optional(),
|
|
32923
|
+
appliesFrom: agentSettingsAppliesFromSchema,
|
|
32924
|
+
currentTurnUnavailableReason: zod_default2.string().min(1).max(currentTurnUnavailableReasonMaxLength).optional()
|
|
32925
|
+
})
|
|
32926
|
+
});
|
|
32904
32927
|
var sessionSkillsUpdatedAgentEventSchema = agentSessionEventBaseSchema.extend({
|
|
32905
32928
|
type: zod_default2.literal("session.skills.updated"),
|
|
32906
32929
|
payload: zod_default2.object({
|
|
@@ -33149,6 +33172,7 @@ var errorAgentEventSchema = agentSessionEventBaseSchema.extend({
|
|
|
33149
33172
|
var agentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
33150
33173
|
sessionStartedAgentEventSchema,
|
|
33151
33174
|
sessionConfiguredAgentEventSchema,
|
|
33175
|
+
sessionSettingsChangedAgentEventSchema,
|
|
33152
33176
|
sessionSkillsUpdatedAgentEventSchema,
|
|
33153
33177
|
sessionStateChangedAgentEventSchema,
|
|
33154
33178
|
sessionEndedAgentEventSchema,
|
|
@@ -33282,12 +33306,17 @@ var createSessionResponseSchema = exports_external2.strictObject({
|
|
|
33282
33306
|
messages: exports_external2.tuple([sessionMessageSchema]),
|
|
33283
33307
|
connections: exports_external2.array(sessionConnectionSchema).max(1)
|
|
33284
33308
|
});
|
|
33309
|
+
var appendSessionMessageAgentInputSchema = exports_external2.strictObject({
|
|
33310
|
+
model: exports_external2.string().min(1).optional(),
|
|
33311
|
+
reasoningEffort: agentReasoningEffortSchema.optional()
|
|
33312
|
+
}).refine((agent) => agent.model !== undefined || agent.reasoningEffort !== undefined, { message: "agent must change the model, the reasoning effort, or both" });
|
|
33285
33313
|
var appendSessionMessageInputSchema = exports_external2.strictObject({
|
|
33286
33314
|
sessionId: exports_external2.string().min(1),
|
|
33287
33315
|
text: exports_external2.string().refine((value) => value.trim().length > 0),
|
|
33288
33316
|
fileIds: exports_external2.array(exports_external2.string().min(1)),
|
|
33289
33317
|
idempotencyKey: exports_external2.string().min(1).max(128),
|
|
33290
|
-
mode: exports_external2.enum(["next", "steer"]).optional()
|
|
33318
|
+
mode: exports_external2.enum(["next", "steer"]).optional(),
|
|
33319
|
+
agent: appendSessionMessageAgentInputSchema.optional()
|
|
33291
33320
|
});
|
|
33292
33321
|
var appendSessionMessageResponseSchema = exports_external2.strictObject({
|
|
33293
33322
|
message: sessionMessageSchema
|
|
@@ -33341,7 +33370,17 @@ var sessionDetailResponseSchema = exports_external2.object({
|
|
|
33341
33370
|
full_name: exports_external2.string()
|
|
33342
33371
|
})),
|
|
33343
33372
|
connections: exports_external2.array(sessionConnectionSchema).max(1),
|
|
33344
|
-
artifacts: exports_external2.array(sessionArtifactSchema)
|
|
33373
|
+
artifacts: exports_external2.array(sessionArtifactSchema),
|
|
33374
|
+
agent: exports_external2.object({
|
|
33375
|
+
provider: exports_external2.string().min(1),
|
|
33376
|
+
model: exports_external2.string(),
|
|
33377
|
+
reasoning: exports_external2.string().nullable()
|
|
33378
|
+
}).nullable().optional(),
|
|
33379
|
+
agent_pending: exports_external2.object({
|
|
33380
|
+
model: exports_external2.string(),
|
|
33381
|
+
reasoning_effort: exports_external2.string().nullable(),
|
|
33382
|
+
message_id: exports_external2.string()
|
|
33383
|
+
}).nullable().optional()
|
|
33345
33384
|
}).passthrough();
|
|
33346
33385
|
var sessionSourceSchema = exports_external2.discriminatedUnion("provider", [
|
|
33347
33386
|
exports_external2.object({
|
|
@@ -33444,7 +33483,13 @@ async function appendSessionMessage({
|
|
|
33444
33483
|
body: JSON.stringify({
|
|
33445
33484
|
text: parsedInput.text,
|
|
33446
33485
|
file_ids: parsedInput.fileIds,
|
|
33447
|
-
...parsedInput.mode === undefined ? {} : { mode: parsedInput.mode }
|
|
33486
|
+
...parsedInput.mode === undefined ? {} : { mode: parsedInput.mode },
|
|
33487
|
+
...parsedInput.agent === undefined ? {} : {
|
|
33488
|
+
agent: {
|
|
33489
|
+
...parsedInput.agent.model === undefined ? {} : { model: parsedInput.agent.model },
|
|
33490
|
+
...parsedInput.agent.reasoningEffort === undefined ? {} : { reasoning_effort: parsedInput.agent.reasoningEffort }
|
|
33491
|
+
}
|
|
33492
|
+
}
|
|
33448
33493
|
})
|
|
33449
33494
|
});
|
|
33450
33495
|
return parseAppendSessionMessageResponse(await parseJson2(response, "Session message append response was not valid JSON."));
|
|
@@ -34351,7 +34396,7 @@ function formatSessionJson({
|
|
|
34351
34396
|
`;
|
|
34352
34397
|
}
|
|
34353
34398
|
// src/version.ts
|
|
34354
|
-
var remyCliVersion = "1.22.0-rc.
|
|
34399
|
+
var remyCliVersion = "1.22.0-rc.2";
|
|
34355
34400
|
|
|
34356
34401
|
// src/self-update.ts
|
|
34357
34402
|
import { spawn } from "child_process";
|
|
@@ -34489,7 +34534,7 @@ async function confirmCliUpdate({ version: version5, signal, interrupt }) {
|
|
|
34489
34534
|
// src/session-agent-options.ts
|
|
34490
34535
|
function newSessionModelLabel(model) {
|
|
34491
34536
|
const provider = newSessionModelHarness(model);
|
|
34492
|
-
return `${agentHarnesses[provider].label} \xB7 ${
|
|
34537
|
+
return `${agentHarnesses[provider].label} \xB7 ${agentModelLabel(model)}`;
|
|
34493
34538
|
}
|
|
34494
34539
|
function newSessionReasoningEffortLabel(effort) {
|
|
34495
34540
|
return agentReasoningEffortPresentation[effort].label;
|
|
@@ -34505,6 +34550,37 @@ var newSessionReasoningEfforts = selectableAgentReasoningEfforts;
|
|
|
34505
34550
|
function parseNewSessionModel(value) {
|
|
34506
34551
|
return newSessionModels.find((model) => model === value);
|
|
34507
34552
|
}
|
|
34553
|
+
function parseNewSessionReasoningEffort(value) {
|
|
34554
|
+
return newSessionReasoningEfforts.find((effort) => effort === value);
|
|
34555
|
+
}
|
|
34556
|
+
function sessionAgentChange({ model, reasoningEffort }) {
|
|
34557
|
+
if (model !== undefined)
|
|
34558
|
+
return { model, ...reasoningEffort === undefined ? {} : { reasoningEffort } };
|
|
34559
|
+
if (reasoningEffort !== undefined)
|
|
34560
|
+
return { reasoningEffort };
|
|
34561
|
+
return;
|
|
34562
|
+
}
|
|
34563
|
+
function sessionHarnessModels(provider) {
|
|
34564
|
+
const parsed = agentProviderIdSchema.safeParse(provider);
|
|
34565
|
+
return parsed.success ? agentHarnesses[parsed.data].models : [];
|
|
34566
|
+
}
|
|
34567
|
+
function agentHarnessLabel(provider) {
|
|
34568
|
+
const parsed = agentProviderIdSchema.safeParse(provider);
|
|
34569
|
+
return parsed.success ? agentHarnesses[parsed.data].label : provider;
|
|
34570
|
+
}
|
|
34571
|
+
function agentModelLabel(model) {
|
|
34572
|
+
return selectableAgentModelPresentation(model)?.label ?? model;
|
|
34573
|
+
}
|
|
34574
|
+
function agentModelDescription(model) {
|
|
34575
|
+
return selectableAgentModelPresentation(model)?.description ?? "";
|
|
34576
|
+
}
|
|
34577
|
+
function agentReasoningEffortLabel(effort) {
|
|
34578
|
+
const parsed = agentReasoningEffortSchema.safeParse(effort);
|
|
34579
|
+
return parsed.success ? agentReasoningEffortPresentation[parsed.data].label : effort;
|
|
34580
|
+
}
|
|
34581
|
+
function agentReasoningEffortDescription(effort) {
|
|
34582
|
+
return agentReasoningEffortPresentation[effort].description;
|
|
34583
|
+
}
|
|
34508
34584
|
var defaultNewSessionAgent = {
|
|
34509
34585
|
model: defaultAgentSelection.model,
|
|
34510
34586
|
reasoningEffort: defaultAgentSelection.reasoningEffort
|
|
@@ -34522,6 +34598,9 @@ var wrappedSessionStartedAgentEventSchema = sessionStartedAgentEventSchema.exten
|
|
|
34522
34598
|
var wrappedSessionConfiguredAgentEventSchema = sessionConfiguredAgentEventSchema.extend({
|
|
34523
34599
|
type: zod_default2.literal("agent.session.configured")
|
|
34524
34600
|
});
|
|
34601
|
+
var wrappedSessionSettingsChangedAgentEventSchema = sessionSettingsChangedAgentEventSchema.extend({
|
|
34602
|
+
type: zod_default2.literal("agent.session.settings.changed")
|
|
34603
|
+
});
|
|
34525
34604
|
var wrappedSessionSkillsUpdatedAgentEventSchema = sessionSkillsUpdatedAgentEventSchema.extend({
|
|
34526
34605
|
type: zod_default2.literal("agent.session.skills.updated")
|
|
34527
34606
|
});
|
|
@@ -34606,6 +34685,7 @@ var wrappedErrorAgentEventSchema = errorAgentEventSchema.extend({
|
|
|
34606
34685
|
var wrappedAgentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
34607
34686
|
wrappedSessionStartedAgentEventSchema,
|
|
34608
34687
|
wrappedSessionConfiguredAgentEventSchema,
|
|
34688
|
+
wrappedSessionSettingsChangedAgentEventSchema,
|
|
34609
34689
|
wrappedSessionSkillsUpdatedAgentEventSchema,
|
|
34610
34690
|
wrappedSessionStateChangedAgentEventSchema,
|
|
34611
34691
|
wrappedSessionEndedAgentEventSchema,
|
|
@@ -34795,6 +34875,8 @@ function createSessionViewState({ detail, activeMessageId }) {
|
|
|
34795
34875
|
...detail.agentStatus === undefined ? {} : { agentStatus: detail.agentStatus },
|
|
34796
34876
|
connectionStatus: "connected",
|
|
34797
34877
|
pullRequest: toSessionPullRequest(detail),
|
|
34878
|
+
agent: toSessionAgentSettings(detail.agent),
|
|
34879
|
+
agentPending: toSessionAgentPendingSettings(detail.agent_pending),
|
|
34798
34880
|
...activeMessageId !== undefined ? { activeMessageId } : {},
|
|
34799
34881
|
seenRetainedEventIds: {},
|
|
34800
34882
|
transcript: [],
|
|
@@ -34802,6 +34884,7 @@ function createSessionViewState({ detail, activeMessageId }) {
|
|
|
34802
34884
|
connectionPreviews: toConnectionPreviews(detail),
|
|
34803
34885
|
previews: { assistantText: "", reasoningText: "" },
|
|
34804
34886
|
commandAuthorLabels: {},
|
|
34887
|
+
commandMessageIds: {},
|
|
34805
34888
|
work: { items: [] },
|
|
34806
34889
|
workTurnBaselines: {},
|
|
34807
34890
|
messageTurns: {},
|
|
@@ -34831,6 +34914,8 @@ function updateSessionDetail({ state, detail }) {
|
|
|
34831
34914
|
aggregateStatus: detail.status,
|
|
34832
34915
|
...detail.agentStatus === undefined ? {} : { agentStatus: detail.agentStatus },
|
|
34833
34916
|
pullRequest: toSessionPullRequest(detail),
|
|
34917
|
+
...detail.agent === undefined ? {} : { agent: toSessionAgentSettings(detail.agent) },
|
|
34918
|
+
...detail.agent_pending === undefined ? {} : { agentPending: toSessionAgentPendingSettings(detail.agent_pending) },
|
|
34834
34919
|
connectionPreviews: toConnectionPreviews(detail)
|
|
34835
34920
|
};
|
|
34836
34921
|
}
|
|
@@ -35035,6 +35120,7 @@ function projectSessionMessageCreated({ state, event, occurredAt }) {
|
|
|
35035
35120
|
return {
|
|
35036
35121
|
...state,
|
|
35037
35122
|
commandAuthorLabels: { ...state.commandAuthorLabels, [event.payload.commandId]: creatorLabel },
|
|
35123
|
+
commandMessageIds: { ...state.commandMessageIds, [event.payload.commandId]: event.payload.messageId },
|
|
35038
35124
|
transcript: [...state.transcript, {
|
|
35039
35125
|
kind: "message",
|
|
35040
35126
|
messageId: event.payload.messageId,
|
|
@@ -35148,6 +35234,12 @@ function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId, e
|
|
|
35148
35234
|
return projectAgentMessageEnded({ state, event: agentEvent, occurredAt, retainedEventId, eventUrl });
|
|
35149
35235
|
if (agentEvent.type === "agent.context.updated")
|
|
35150
35236
|
return state;
|
|
35237
|
+
if (agentEvent.type === "agent.session.configured" || agentEvent.type === "agent.session.settings.changed") {
|
|
35238
|
+
const agent = { provider: agentEvent.provider, model: agentEvent.payload.model, reasoningEffort: agentEvent.payload.reasoningEffort ?? null };
|
|
35239
|
+
const stateWithAgent = { ...state, agent };
|
|
35240
|
+
const card2 = toAgentActivityCard(agentEvent);
|
|
35241
|
+
return agentEvent.type === "agent.session.settings.changed" ? placeActivityAfterCommandMessage({ state: stateWithAgent, commandId: agentEvent.payload.commandId, retainedEventId, occurredAt, card: card2, eventUrl }) : appendActivity({ state: stateWithAgent, retainedEventId, occurredAt, card: card2, eventUrl });
|
|
35242
|
+
}
|
|
35151
35243
|
if (agentEvent.type === "agent.work.observed" && agentEvent.actor.type === "main")
|
|
35152
35244
|
return projectAgentWorkObserved({ state, event: agentEvent, occurredAt });
|
|
35153
35245
|
const stateWithTurnStart = agentEvent.type === "agent.turn.started" && agentEvent.actor.type === "main" ? {
|
|
@@ -35274,8 +35366,21 @@ function projectAgentMessageEnded({ state, event, occurredAt, retainedEventId, e
|
|
|
35274
35366
|
transcript: [...state.transcript, { kind: "message", messageId, occurredAt, author, text: displayedText, attachments: [] }]
|
|
35275
35367
|
};
|
|
35276
35368
|
}
|
|
35277
|
-
function
|
|
35278
|
-
return {
|
|
35369
|
+
function activityItem({ retainedEventId, occurredAt, card, eventUrl }) {
|
|
35370
|
+
return { kind: "activity", activityId: `activity:${retainedEventId}`, occurredAt, card, ...eventUrl === undefined ? {} : { eventUrl } };
|
|
35371
|
+
}
|
|
35372
|
+
function appendActivity({ state, ...activity }) {
|
|
35373
|
+
return { ...state, transcript: [...state.transcript, activityItem(activity)] };
|
|
35374
|
+
}
|
|
35375
|
+
function placeActivityAfterCommandMessage({ state, commandId, ...activity }) {
|
|
35376
|
+
const messageId = state.commandMessageIds[commandId];
|
|
35377
|
+
const messageIndex = messageId === undefined ? -1 : state.transcript.findIndex((item) => item.kind === "message" && item.messageId === messageId);
|
|
35378
|
+
if (messageIndex === -1)
|
|
35379
|
+
return appendActivity({ state, ...activity });
|
|
35380
|
+
return {
|
|
35381
|
+
...state,
|
|
35382
|
+
transcript: [...state.transcript.slice(0, messageIndex + 1), activityItem(activity), ...state.transcript.slice(messageIndex + 1)]
|
|
35383
|
+
};
|
|
35279
35384
|
}
|
|
35280
35385
|
function toAgentActivityCard(event) {
|
|
35281
35386
|
const identity = childActivityIdentity(event);
|
|
@@ -35289,6 +35394,21 @@ function toMainAgentActivityCard(event) {
|
|
|
35289
35394
|
return { kind: "lifecycle", weight: "noise", title: "Remy session started", summary: "Session is ready." };
|
|
35290
35395
|
case "agent.session.configured":
|
|
35291
35396
|
return { kind: "lifecycle", weight: "noise", title: "Remy session configured", summary: `Model ${event.payload.model}.` };
|
|
35397
|
+
case "agent.session.settings.changed": {
|
|
35398
|
+
const settings = [agentModelLabel(event.payload.model), ...event.payload.reasoningEffort === undefined ? [] : [agentReasoningEffortLabel(event.payload.reasoningEffort)]];
|
|
35399
|
+
const switched = `Switched to ${terminalSafeSingleLine(settings.join(" \xB7 "))}`;
|
|
35400
|
+
if (event.payload.appliesFrom === "current_turn")
|
|
35401
|
+
return { kind: "lifecycle", weight: "signal", title: switched, summary: switched };
|
|
35402
|
+
const title = `${switched} (from next turn)`;
|
|
35403
|
+
const reason = event.payload.currentTurnUnavailableReason;
|
|
35404
|
+
return {
|
|
35405
|
+
kind: "lifecycle",
|
|
35406
|
+
weight: "signal",
|
|
35407
|
+
title,
|
|
35408
|
+
summary: title,
|
|
35409
|
+
...reason === undefined ? {} : { detail: `The running turn kept its settings: ${terminalSafeSingleLine(reason)}` }
|
|
35410
|
+
};
|
|
35411
|
+
}
|
|
35292
35412
|
case "agent.session.skills.updated":
|
|
35293
35413
|
return { kind: "lifecycle", weight: "noise", title: "Remy skills updated", summary: "Available skills updated." };
|
|
35294
35414
|
case "agent.session.state.changed":
|
|
@@ -35449,6 +35569,7 @@ Background outcome: ${event.payload.output.success ? "completed" : "failed"}`,
|
|
|
35449
35569
|
return createChildActivityCard({ identity, activityTitle: "Needs input", card: { kind: "approval-question", weight: "signal", summary: providerText(event.payload.prompt, "Subagent needs input."), detail: jsonDetail(event.payload.questions) } });
|
|
35450
35570
|
case "agent.session.started":
|
|
35451
35571
|
case "agent.session.configured":
|
|
35572
|
+
case "agent.session.settings.changed":
|
|
35452
35573
|
case "agent.session.skills.updated":
|
|
35453
35574
|
case "agent.session.state.changed":
|
|
35454
35575
|
case "agent.session.ended":
|
|
@@ -35865,6 +35986,12 @@ function providerText(raw, fallback) {
|
|
|
35865
35986
|
const cleaned = stripAnsi(raw ?? "").trim();
|
|
35866
35987
|
return cleaned.length > 0 ? cleaned : fallback;
|
|
35867
35988
|
}
|
|
35989
|
+
function toSessionAgentSettings(agent) {
|
|
35990
|
+
return agent ? { provider: agent.provider, model: agent.model, reasoningEffort: agent.reasoning } : null;
|
|
35991
|
+
}
|
|
35992
|
+
function toSessionAgentPendingSettings(pending) {
|
|
35993
|
+
return pending ? { model: pending.model, reasoningEffort: pending.reasoning_effort, messageId: pending.message_id } : null;
|
|
35994
|
+
}
|
|
35868
35995
|
function toConnectionPreviews(detail) {
|
|
35869
35996
|
return detail.connections.map((connection) => ({ provider: connection.provider, status: connection.status }));
|
|
35870
35997
|
}
|
|
@@ -36236,7 +36363,7 @@ function createRemoteSessionController(dependencies) {
|
|
|
36236
36363
|
await writeCache();
|
|
36237
36364
|
cachedLastRetainedEventId = projectedState.lastRetainedEventId;
|
|
36238
36365
|
}
|
|
36239
|
-
if (frame.kind === "retained" && frame.data.event.type === "session.title.generated"
|
|
36366
|
+
if (frame.kind === "retained" && !previousState.seenRetainedEventIds[frame.id] && (frame.data.event.type === "session.title.generated" || settlesAgentSettings({ previousState, projectedState, frame }))) {
|
|
36240
36367
|
try {
|
|
36241
36368
|
await refreshDetail();
|
|
36242
36369
|
} catch {}
|
|
@@ -36356,9 +36483,16 @@ function createRemoteSessionController(dependencies) {
|
|
|
36356
36483
|
waitUntilReady,
|
|
36357
36484
|
waitForTurn,
|
|
36358
36485
|
recordActiveMessage,
|
|
36359
|
-
updateDetail
|
|
36486
|
+
updateDetail,
|
|
36487
|
+
refreshDetail
|
|
36360
36488
|
};
|
|
36361
36489
|
}
|
|
36490
|
+
function settlesAgentSettings({ previousState, projectedState, frame }) {
|
|
36491
|
+
if (frame.data.event.type === "agent.session.settings.changed")
|
|
36492
|
+
return true;
|
|
36493
|
+
const pending = previousState.agentPending;
|
|
36494
|
+
return pending !== null && sessionTurnOutcome({ state: previousState, sessionMessageId: pending.messageId }).status !== "ended" && sessionTurnOutcome({ state: projectedState, sessionMessageId: pending.messageId }).status === "ended";
|
|
36495
|
+
}
|
|
36362
36496
|
function resolveSessionCachePath({
|
|
36363
36497
|
environment,
|
|
36364
36498
|
sessionId
|
|
@@ -39254,6 +39388,8 @@ var composerSlashCommands = [
|
|
|
39254
39388
|
{ value: "/complete", description: "Finish this session" },
|
|
39255
39389
|
{ value: "/cancel", description: "Cancel this session" },
|
|
39256
39390
|
{ value: "/compact", description: "Compact main-thread context" },
|
|
39391
|
+
{ value: "/model", description: "Change the model from your next message" },
|
|
39392
|
+
{ value: "/effort", description: "Change reasoning effort from your next message" },
|
|
39257
39393
|
{ value: "/new", description: "Start a new session" },
|
|
39258
39394
|
{ value: "/logout", description: "Sign out of Remy" },
|
|
39259
39395
|
{ value: "/files", description: "Download artifacts and user attachments" },
|
|
@@ -39316,6 +39452,45 @@ async function createSessionTui({
|
|
|
39316
39452
|
const steps = currentTurnActivityCount();
|
|
39317
39453
|
const stepText = steps === 0 ? "" : `${steps} step${steps === 1 ? "" : "s"} \xB7 `;
|
|
39318
39454
|
return renderer.width < 76 ? `${stepText}ctrl+o \xB7 esc stop` : `${stepText}ctrl+o full detail \xB7 esc to stop`;
|
|
39455
|
+
}, openAgentSettingsPicker = function(kind) {
|
|
39456
|
+
const target = agentSettingsTarget({ state: latestState, staged: composerDraft.agent });
|
|
39457
|
+
if (kind === "effort") {
|
|
39458
|
+
agentSettingsPicker = { kind, index: Math.max(0, newSessionReasoningEfforts.findIndex((effort) => effort === target.reasoningEffort)) };
|
|
39459
|
+
} else {
|
|
39460
|
+
const provider = latestState.agent?.provider;
|
|
39461
|
+
const models = provider === undefined ? [] : sessionHarnessModels(provider);
|
|
39462
|
+
if (provider === undefined || models.length === 0) {
|
|
39463
|
+
composerFeedback = {
|
|
39464
|
+
kind: "failure",
|
|
39465
|
+
message: provider === undefined ? "This session has not reported its harness yet, so its model cannot change." : `Remy does not offer model changes for the ${terminalSafeText(agentHarnessLabel(provider))} harness.`
|
|
39466
|
+
};
|
|
39467
|
+
render();
|
|
39468
|
+
return;
|
|
39469
|
+
}
|
|
39470
|
+
agentSettingsPicker = { kind, provider, models, index: Math.max(0, models.findIndex((model) => model === target.model)) };
|
|
39471
|
+
}
|
|
39472
|
+
composerFeedback = undefined;
|
|
39473
|
+
slashCompletions = [];
|
|
39474
|
+
helpVisible = false;
|
|
39475
|
+
pathCompletionMenuOpen = false;
|
|
39476
|
+
render();
|
|
39477
|
+
}, moveAgentSettingsPicker = function(step) {
|
|
39478
|
+
if (!agentSettingsPicker)
|
|
39479
|
+
return;
|
|
39480
|
+
const length = agentSettingsPicker.kind === "model" ? agentSettingsPicker.models.length : newSessionReasoningEfforts.length;
|
|
39481
|
+
agentSettingsPicker = { ...agentSettingsPicker, index: (agentSettingsPicker.index + step + length) % length };
|
|
39482
|
+
render();
|
|
39483
|
+
}, chooseAgentSetting = function() {
|
|
39484
|
+
const picker = agentSettingsPicker;
|
|
39485
|
+
if (!picker)
|
|
39486
|
+
return;
|
|
39487
|
+
agentSettingsPicker = undefined;
|
|
39488
|
+
const pick3 = picker.kind === "model" ? { model: picker.models[picker.index] } : { reasoningEffort: newSessionReasoningEfforts[picker.index] };
|
|
39489
|
+
const agent = stageAgentChange({ state: latestState, staged: composerDraft.agent, pick: pick3 });
|
|
39490
|
+
composerDraft = { text: composerDraft.text, attachments: composerDraft.attachments, ...agent ? { agent } : {} };
|
|
39491
|
+
const target = agentSettingsTarget({ state: latestState, staged: agent });
|
|
39492
|
+
composerFeedback = agent ? { kind: "info", message: `${terminalSafeText(agentSettingsLabel(target))} applies from your next message.` } : { kind: "info", message: "No model or effort change is staged." };
|
|
39493
|
+
render();
|
|
39319
39494
|
}, composerAtVisualEdge = function(direction) {
|
|
39320
39495
|
const cursor = composer.visualCursor;
|
|
39321
39496
|
const visualRow = composer.scrollY + cursor.visualRow;
|
|
@@ -39363,7 +39538,7 @@ async function createSessionTui({
|
|
|
39363
39538
|
const working = isRemyWorking(latestState);
|
|
39364
39539
|
const startedAt = workingTurnStartedAt(latestState);
|
|
39365
39540
|
const elapsedMs = startedAt === undefined ? 0 : Math.max(0, now3() - Date.parse(startedAt));
|
|
39366
|
-
statusBand.content = renderStatusBand({ state: latestState, working, elapsedMs, stopState, lifecycleRequestState, repositoryLabel });
|
|
39541
|
+
statusBand.content = renderStatusBand({ state: latestState, working, elapsedMs, stopState, lifecycleRequestState, repositoryLabel, stagedAgent: composerDraft.agent });
|
|
39367
39542
|
const liveIndicator = lifecycleRequestState.kind === "pending" ? renderWorkingIndicator({ frame: SPINNER_FRAMES[spinnerFrameIndex], elapsedMs: 0, mode: lifecycleRequestState.operation }) : working ? renderWorkingIndicator({
|
|
39368
39543
|
frame: SPINNER_FRAMES[spinnerFrameIndex],
|
|
39369
39544
|
elapsedMs,
|
|
@@ -39381,6 +39556,7 @@ async function createSessionTui({
|
|
|
39381
39556
|
const submissionStatus = renderComposerStatus({ admittedSubmissions, width: renderer.width - 2 });
|
|
39382
39557
|
const completionMenu = pathCompletionMenuOpen ? renderPathCompletionMenu({ completions: pathCompletions, selectedIndex: completionIndex, width: renderer.width - 2, maxRows: completionMenuRows(renderer.height) }) : undefined;
|
|
39383
39558
|
const commandMenu = renderSlashCommandMenu({ commands: slashCompletions, selectedIndex: slashCompletionIndex, width: renderer.width - 2, maxRows: completionMenuRows(renderer.height) });
|
|
39559
|
+
const agentSettingsMenu = agentSettingsPicker && latestState.aggregateStatus === "open" ? renderAgentSettingsPicker({ picker: agentSettingsPicker, width: renderer.width - 2, maxRows: completionMenuRows(renderer.height) }) : undefined;
|
|
39384
39560
|
const composerStatus = [
|
|
39385
39561
|
attachmentFeedback ? renderAttachmentFeedback(attachmentFeedback) : undefined,
|
|
39386
39562
|
composerFeedback ? renderFeedback(composerFeedback) : undefined,
|
|
@@ -39388,6 +39564,7 @@ async function createSessionTui({
|
|
|
39388
39564
|
lifecycleRequestState.kind === "failed" ? renderFeedback({ kind: "failure", message: `Could not ${lifecycleRequestState.operation} the session: ${lifecycleRequestState.message}` }) : undefined,
|
|
39389
39565
|
submissionStatus,
|
|
39390
39566
|
commandMenu,
|
|
39567
|
+
agentSettingsMenu,
|
|
39391
39568
|
completionMenu
|
|
39392
39569
|
].filter((part) => part !== undefined && part.chunks.length > 0);
|
|
39393
39570
|
status.content = logoutConfirmationOpen ? renderFeedback({ kind: "attention", message: "Log out of Remy?" }) : composerStatus.length > 0 ? joinStyled(composerStatus, `
|
|
@@ -39420,6 +39597,7 @@ async function createSessionTui({
|
|
|
39420
39597
|
pathCompletionMenuOpen = false;
|
|
39421
39598
|
slashCompletions = [];
|
|
39422
39599
|
helpVisible = false;
|
|
39600
|
+
agentSettingsPicker = undefined;
|
|
39423
39601
|
composer.blur();
|
|
39424
39602
|
root.visible = false;
|
|
39425
39603
|
resourceRoot.visible = true;
|
|
@@ -39579,6 +39757,7 @@ async function createSessionTui({
|
|
|
39579
39757
|
let pathCompletionMenuOpen = false;
|
|
39580
39758
|
let slashCompletions = [];
|
|
39581
39759
|
let slashCompletionIndex = 0;
|
|
39760
|
+
let agentSettingsPicker;
|
|
39582
39761
|
let composerFeedback = initialFeedback ? { kind: "info", message: initialFeedback } : undefined;
|
|
39583
39762
|
let attachmentFeedback;
|
|
39584
39763
|
const localPromptHistory = [];
|
|
@@ -39677,6 +39856,12 @@ async function createSessionTui({
|
|
|
39677
39856
|
}
|
|
39678
39857
|
return;
|
|
39679
39858
|
}
|
|
39859
|
+
if (agentSettingsPicker && key.name === "escape") {
|
|
39860
|
+
key.preventDefault();
|
|
39861
|
+
agentSettingsPicker = undefined;
|
|
39862
|
+
render();
|
|
39863
|
+
return;
|
|
39864
|
+
}
|
|
39680
39865
|
if (resourceMode) {
|
|
39681
39866
|
key.preventDefault();
|
|
39682
39867
|
const choices = resourceChoices();
|
|
@@ -39788,6 +39973,14 @@ async function createSessionTui({
|
|
|
39788
39973
|
key.preventDefault();
|
|
39789
39974
|
return;
|
|
39790
39975
|
}
|
|
39976
|
+
if (agentSettingsPicker) {
|
|
39977
|
+
key.preventDefault();
|
|
39978
|
+
if (key.name === "up" || key.name === "down")
|
|
39979
|
+
moveAgentSettingsPicker(key.name === "up" ? -1 : 1);
|
|
39980
|
+
else if (key.name === "return" || key.name === "enter")
|
|
39981
|
+
chooseAgentSetting();
|
|
39982
|
+
return;
|
|
39983
|
+
}
|
|
39791
39984
|
if (slashCompletions.length > 0 && (key.name === "up" || key.name === "down")) {
|
|
39792
39985
|
key.preventDefault();
|
|
39793
39986
|
slashCompletionIndex = (slashCompletionIndex + (key.name === "up" ? -1 : 1) + slashCompletions.length) % slashCompletions.length;
|
|
@@ -40007,6 +40200,7 @@ async function createSessionTui({
|
|
|
40007
40200
|
idempotencyKey: crypto.randomUUID(),
|
|
40008
40201
|
text: composerDraft.text,
|
|
40009
40202
|
attachments: [...composerDraft.attachments],
|
|
40203
|
+
...composerDraft.agent ? { agent: composerDraft.agent } : {},
|
|
40010
40204
|
status: "admitting"
|
|
40011
40205
|
};
|
|
40012
40206
|
admittedSubmissions = [...admittedSubmissions, submission];
|
|
@@ -40059,6 +40253,12 @@ async function createSessionTui({
|
|
|
40059
40253
|
handleCompactionRequest();
|
|
40060
40254
|
return true;
|
|
40061
40255
|
}
|
|
40256
|
+
if (command === "/model" || command === "/effort") {
|
|
40257
|
+
composer.setText("");
|
|
40258
|
+
composerDraft = { ...composerDraft, text: "" };
|
|
40259
|
+
openAgentSettingsPicker(command === "/model" ? "model" : "effort");
|
|
40260
|
+
return true;
|
|
40261
|
+
}
|
|
40062
40262
|
if (command === "/logout") {
|
|
40063
40263
|
composer.setText("");
|
|
40064
40264
|
composerDraft = { ...composerDraft, text: "" };
|
|
@@ -40085,18 +40285,19 @@ async function createSessionTui({
|
|
|
40085
40285
|
await submitMessage({
|
|
40086
40286
|
text: submission.text,
|
|
40087
40287
|
attachments: submission.attachments,
|
|
40088
|
-
idempotencyKey: submission.idempotencyKey
|
|
40288
|
+
idempotencyKey: submission.idempotencyKey,
|
|
40289
|
+
...submission.agent ? { agent: submission.agent } : {}
|
|
40089
40290
|
});
|
|
40090
40291
|
if (!viewIsActive())
|
|
40091
40292
|
return;
|
|
40092
40293
|
localPromptHistory.push(submission.text);
|
|
40093
40294
|
const messageId = latestState.activeMessageId;
|
|
40094
|
-
admittedSubmissions = messageId ? admittedSubmissions.map((candidate) => candidate.id === submission.id ? { id: candidate.id, idempotencyKey: candidate.idempotencyKey, text: candidate.text, attachments: candidate.attachments, status: "submitted", messageId } : candidate) : admittedSubmissions.filter((candidate) => candidate.id !== submission.id);
|
|
40295
|
+
admittedSubmissions = messageId ? admittedSubmissions.map((candidate) => candidate.id === submission.id ? { id: candidate.id, idempotencyKey: candidate.idempotencyKey, text: candidate.text, attachments: candidate.attachments, ...candidate.agent ? { agent: candidate.agent } : {}, status: "submitted", messageId } : candidate) : admittedSubmissions.filter((candidate) => candidate.id !== submission.id);
|
|
40095
40296
|
composerFeedback = undefined;
|
|
40096
40297
|
} catch (error93) {
|
|
40097
40298
|
if (!viewIsActive())
|
|
40098
40299
|
return;
|
|
40099
|
-
admittedSubmissions = admittedSubmissions.map((candidate) => candidate.id === submission.id ? { id: candidate.id, idempotencyKey: candidate.idempotencyKey, text: candidate.text, attachments: candidate.attachments, status: "failed", error: error93 instanceof Error ? error93.message : String(error93) } : candidate);
|
|
40300
|
+
admittedSubmissions = admittedSubmissions.map((candidate) => candidate.id === submission.id ? { id: candidate.id, idempotencyKey: candidate.idempotencyKey, text: candidate.text, attachments: candidate.attachments, ...candidate.agent ? { agent: candidate.agent } : {}, status: "failed", error: error93 instanceof Error ? error93.message : String(error93) } : candidate);
|
|
40100
40301
|
}
|
|
40101
40302
|
render();
|
|
40102
40303
|
}
|
|
@@ -40111,6 +40312,7 @@ async function createSessionTui({
|
|
|
40111
40312
|
idempotencyKey: failed.idempotencyKey,
|
|
40112
40313
|
text: failed.text,
|
|
40113
40314
|
attachments: failed.attachments,
|
|
40315
|
+
...failed.agent ? { agent: failed.agent } : {},
|
|
40114
40316
|
status: "admitting"
|
|
40115
40317
|
};
|
|
40116
40318
|
admittedSubmissions = admittedSubmissions.map((submission) => submission.id === failed.id ? retrying : submission);
|
|
@@ -40221,6 +40423,8 @@ async function createSessionTui({
|
|
|
40221
40423
|
}
|
|
40222
40424
|
unsubscribe = controller.subscribe(({ state }) => {
|
|
40223
40425
|
latestState = state;
|
|
40426
|
+
if (latestState.aggregateStatus !== "open")
|
|
40427
|
+
agentSettingsPicker = undefined;
|
|
40224
40428
|
if (!isRemyWorking(latestState) && stopState.kind !== "idle") {
|
|
40225
40429
|
stopState = { kind: "idle" };
|
|
40226
40430
|
if (composerFeedback?.message === "Stop requested.")
|
|
@@ -40297,10 +40501,58 @@ function renderSlashCommandMenu({ commands, selectedIndex, width, maxRows }) {
|
|
|
40297
40501
|
maxRows
|
|
40298
40502
|
});
|
|
40299
40503
|
}
|
|
40504
|
+
function renderAgentSettingsPicker({ picker, width, maxRows }) {
|
|
40505
|
+
const heading = picker.kind === "model" ? `Model for your next message \xB7 ${terminalSafeText(agentHarnessLabel(picker.provider))} harness` : "Reasoning effort for your next message";
|
|
40506
|
+
const items = picker.kind === "model" ? picker.models.map((model) => ({ label: agentModelLabel(model), description: agentModelDescription(model) })) : newSessionReasoningEfforts.map((effort) => ({ label: agentReasoningEffortLabel(effort), description: agentReasoningEffortDescription(effort) }));
|
|
40507
|
+
const menu = renderCompletionMenu({
|
|
40508
|
+
items,
|
|
40509
|
+
selectedIndex: picker.index,
|
|
40510
|
+
hints: [{ key: "\u2191\u2193", action: "select" }, { key: "Enter", action: "use for next message" }, { key: "Esc", action: "keep current" }],
|
|
40511
|
+
width,
|
|
40512
|
+
maxRows: Math.max(1, maxRows - 1)
|
|
40513
|
+
});
|
|
40514
|
+
return menu && joinStyled([new StyledText9([bold5(fg10(PALETTE.remyAccent)(heading))]), menu], `
|
|
40515
|
+
`);
|
|
40516
|
+
}
|
|
40517
|
+
function agentSettingsTarget({ state, staged }) {
|
|
40518
|
+
const requested = state.agentPending ?? state.agent;
|
|
40519
|
+
return {
|
|
40520
|
+
model: staged?.model ?? requested?.model,
|
|
40521
|
+
reasoningEffort: staged?.reasoningEffort ?? requested?.reasoningEffort
|
|
40522
|
+
};
|
|
40523
|
+
}
|
|
40524
|
+
function stageAgentChange({ state, staged, pick: pick3 }) {
|
|
40525
|
+
const current = agentSettingsTarget({ state, staged: undefined });
|
|
40526
|
+
const model = pick3.model ?? staged?.model;
|
|
40527
|
+
const reasoningEffort = pick3.reasoningEffort ?? staged?.reasoningEffort;
|
|
40528
|
+
return sessionAgentChange({
|
|
40529
|
+
model: model === current.model ? undefined : model,
|
|
40530
|
+
reasoningEffort: reasoningEffort === current.reasoningEffort ? undefined : reasoningEffort
|
|
40531
|
+
});
|
|
40532
|
+
}
|
|
40533
|
+
function agentSettingsLabel({ model, reasoningEffort }) {
|
|
40534
|
+
return [
|
|
40535
|
+
...model === undefined ? [] : [agentModelLabel(model)],
|
|
40536
|
+
...reasoningEffort === undefined || reasoningEffort === null ? [] : [agentReasoningEffortLabel(reasoningEffort)]
|
|
40537
|
+
].join(" \xB7 ");
|
|
40538
|
+
}
|
|
40539
|
+
function renderAgentSettingsStatus({ state, stagedAgent }) {
|
|
40540
|
+
const applied = state.agent;
|
|
40541
|
+
if (!applied)
|
|
40542
|
+
return;
|
|
40543
|
+
const appliedLabel = terminalSafeText(`${agentHarnessLabel(applied.provider)} \xB7 ${agentSettingsLabel(applied)}`);
|
|
40544
|
+
const target = agentSettingsTarget({ state, staged: stagedAgent });
|
|
40545
|
+
const phase = stagedAgent ? "next message" : state.agentPending ? "switching\u2026" : undefined;
|
|
40546
|
+
const changes = phase !== undefined && (target.model !== applied.model || (target.reasoningEffort ?? null) !== applied.reasoningEffort);
|
|
40547
|
+
return new StyledText9([
|
|
40548
|
+
fg10(PALETTE.bodyText)(appliedLabel),
|
|
40549
|
+
...changes ? [fg10(PALETTE.approvalQuestion)(` \u2192 ${terminalSafeText(agentSettingsLabel(target))} (${phase})`)] : []
|
|
40550
|
+
]);
|
|
40551
|
+
}
|
|
40300
40552
|
function hasRunningTurn(state) {
|
|
40301
40553
|
return state.aggregateStatus === "open" && Object.values(state.messageTurns).some((turn) => turn.outcome === undefined);
|
|
40302
40554
|
}
|
|
40303
|
-
function renderStatusBand({ state, working, elapsedMs, stopState, lifecycleRequestState, repositoryLabel }) {
|
|
40555
|
+
function renderStatusBand({ state, working, elapsedMs, stopState, lifecycleRequestState, repositoryLabel, stagedAgent }) {
|
|
40304
40556
|
const stopping = stopState?.kind === "stopping";
|
|
40305
40557
|
const pendingOperation = lifecycleRequestState?.kind === "pending" ? lifecycleRequestState.operation : undefined;
|
|
40306
40558
|
const presentation = pendingOperation ? { label: lifecycleOperationPresentParticiple(pendingOperation), color: PALETTE.approvalQuestion } : stopping ? { label: "Stopping", color: PALETTE.approvalQuestion } : sessionViewStatePresentation({ aggregateStatus: state.aggregateStatus, isWorking: working });
|
|
@@ -40309,11 +40561,13 @@ function renderStatusBand({ state, working, elapsedMs, stopState, lifecycleReque
|
|
|
40309
40561
|
const sessionLabel = state.sessionNumber !== undefined ? `#${state.sessionNumber}` : state.sessionId;
|
|
40310
40562
|
const pullRequest = state.pullRequest;
|
|
40311
40563
|
const contextStatus = renderContextStatus(state.context.snapshot);
|
|
40564
|
+
const agentSettings = renderAgentSettingsStatus({ state, stagedAgent: state.aggregateStatus === "open" ? stagedAgent : undefined });
|
|
40312
40565
|
const headerContext = [
|
|
40313
40566
|
...repositoryLabel ? [[dim7(fg10(PALETTE.dimText)(repositoryLabel))]] : [],
|
|
40314
40567
|
...pullRequest ? [[bold5(fg10(statusColor(pullRequest.status))(`PR#${pullRequest.number}`))]] : [],
|
|
40315
40568
|
[bold5(fg10(presentation.color)(`${presentation.label}${elapsed}`))],
|
|
40316
40569
|
connection.chunks,
|
|
40570
|
+
...agentSettings ? [agentSettings.chunks] : [],
|
|
40317
40571
|
...contextStatus ? [[dim7(fg10(PALETTE.dimText)(contextStatus))]] : []
|
|
40318
40572
|
];
|
|
40319
40573
|
return joinStyled([
|
|
@@ -41454,7 +41708,7 @@ async function dispatchCliCommandWithShutdown({
|
|
|
41454
41708
|
});
|
|
41455
41709
|
}
|
|
41456
41710
|
if (command.name === "session")
|
|
41457
|
-
return await attachSession({ dependencies, sessionId: command.sessionId, noTui: command.noTui, json: command.json,
|
|
41711
|
+
return await attachSession({ dependencies, sessionId: command.sessionId, noTui: command.noTui, json: command.json, followUp: command.followUp });
|
|
41458
41712
|
return await createNewSession({ dependencies, command });
|
|
41459
41713
|
}
|
|
41460
41714
|
async function installCliUpdate({ dependencies, version: version5 }) {
|
|
@@ -42368,26 +42622,35 @@ async function attachSession({
|
|
|
42368
42622
|
sessionId,
|
|
42369
42623
|
noTui,
|
|
42370
42624
|
json: json3,
|
|
42371
|
-
|
|
42625
|
+
followUp
|
|
42372
42626
|
}) {
|
|
42373
42627
|
const operations = await createSessionOperations(dependencies);
|
|
42374
42628
|
const detail = await operations.getSession({ client: operations.client, sessionId });
|
|
42629
|
+
if (followUp?.agent?.model !== undefined && detail.agent)
|
|
42630
|
+
assertModelInSessionHarness({ model: followUp.agent.model, provider: detail.agent.provider });
|
|
42375
42631
|
const repositories = detail.repositories.map((repository) => ({ id: repository.id, fullName: repository.full_name }));
|
|
42376
42632
|
const cache = await (dependencies.readSessionCache ?? readSessionCache)(resolveSessionCachePathForCommand({ dependencies, sessionId }));
|
|
42377
42633
|
let activeMessageId = cache?.activeMessageId;
|
|
42378
42634
|
let cacheWarningReported = false;
|
|
42379
|
-
const onCacheError =
|
|
42635
|
+
const onCacheError = followUp === undefined ? undefined : () => {
|
|
42380
42636
|
if (cacheWarningReported)
|
|
42381
42637
|
return;
|
|
42382
42638
|
cacheWarningReported = true;
|
|
42383
42639
|
dependencies.output.writeStderr(`Local session cache is unavailable; continuing to observe the accepted follow-up. Do not resubmit the prompt.
|
|
42384
42640
|
`);
|
|
42385
42641
|
};
|
|
42386
|
-
if (
|
|
42642
|
+
if (followUp !== undefined) {
|
|
42387
42643
|
throwIfAborted2(dependencies.abortSignal);
|
|
42388
42644
|
const appended = await operations.appendSessionMessage({
|
|
42389
42645
|
client: operations.client,
|
|
42390
|
-
input: {
|
|
42646
|
+
input: {
|
|
42647
|
+
sessionId,
|
|
42648
|
+
text: followUp.prompt,
|
|
42649
|
+
fileIds: [],
|
|
42650
|
+
mode: "steer",
|
|
42651
|
+
idempotencyKey: randomUUID5(),
|
|
42652
|
+
...followUp.agent === undefined ? {} : { agent: followUp.agent }
|
|
42653
|
+
}
|
|
42391
42654
|
});
|
|
42392
42655
|
activeMessageId = appended.message.id;
|
|
42393
42656
|
}
|
|
@@ -42419,6 +42682,13 @@ async function attachSession({
|
|
|
42419
42682
|
onCacheError
|
|
42420
42683
|
});
|
|
42421
42684
|
}
|
|
42685
|
+
function assertModelInSessionHarness({ model, provider }) {
|
|
42686
|
+
const models = sessionHarnessModels(provider);
|
|
42687
|
+
if (models.includes(model))
|
|
42688
|
+
return;
|
|
42689
|
+
const offered = models.length === 0 ? "Remy does not offer model changes for that harness." : `Choose one of: ${models.join(", ")}.`;
|
|
42690
|
+
throw new Error(`--model ${model} is not available: this session runs on the ${agentHarnessLabel(provider)} harness, which cannot change mid-session. ${offered}`);
|
|
42691
|
+
}
|
|
42422
42692
|
async function runAttachedSession({
|
|
42423
42693
|
dependencies,
|
|
42424
42694
|
operations,
|
|
@@ -42515,10 +42785,15 @@ async function runAttachedSession({
|
|
|
42515
42785
|
text: submission.text,
|
|
42516
42786
|
fileIds: submission.attachments.map((attachment) => attachment.fileId),
|
|
42517
42787
|
idempotencyKey: submission.idempotencyKey,
|
|
42518
|
-
mode: "steer"
|
|
42788
|
+
mode: "steer",
|
|
42789
|
+
...submission.agent === undefined ? {} : { agent: submission.agent }
|
|
42519
42790
|
}
|
|
42520
42791
|
});
|
|
42521
42792
|
await controller.recordActiveMessage(result.message.id);
|
|
42793
|
+
if (submission.agent !== undefined)
|
|
42794
|
+
controller.refreshDetail().catch(() => {
|
|
42795
|
+
return;
|
|
42796
|
+
});
|
|
42522
42797
|
return { messageId: result.message.id };
|
|
42523
42798
|
},
|
|
42524
42799
|
requestInterrupt: async ({ idempotencyKey }) => {
|
|
@@ -42862,8 +43137,12 @@ Arguments:
|
|
|
42862
43137
|
prompt Submit a follow-up as Steer before attaching
|
|
42863
43138
|
|
|
42864
43139
|
With a prompt, JSON output waits for that message's turn result. Use -- before a prompt beginning with --.
|
|
43140
|
+
--model and --reasoning-effort require a prompt: the change travels with it and stays the session's setting.
|
|
43141
|
+
A running turn switches from its next model request; otherwise the change applies from the turn the prompt starts.
|
|
42865
43142
|
|
|
42866
43143
|
Options:
|
|
43144
|
+
--model <name> Switch to another model of the session's harness
|
|
43145
|
+
--reasoning-effort <low|medium|high|xhigh> Switch agent reasoning effort
|
|
42867
43146
|
--no-tui Do not open the interactive terminal view
|
|
42868
43147
|
--json Write session updates as JSON
|
|
42869
43148
|
--help, -h Show this help
|
|
@@ -42894,7 +43173,7 @@ Usage:
|
|
|
42894
43173
|
Commands:
|
|
42895
43174
|
remy Open interactive dashboard
|
|
42896
43175
|
remy dashboard Open interactive dashboard
|
|
42897
|
-
remy --session <session-id> [--no-tui
|
|
43176
|
+
remy --session <session-id> [--model <name> --reasoning-effort <low|medium|high|xhigh> --no-tui --json] [prompt]
|
|
42898
43177
|
Attach to a session, optionally submitting a follow-up
|
|
42899
43178
|
remy new [--repository <owner/name> ... --installation <id> --model <name> --reasoning-effort <low|medium|high|xhigh> --attach <path> ... --no-tui --json] <prompt>
|
|
42900
43179
|
Create a session
|
|
@@ -42932,8 +43211,11 @@ function parseSessionAttach(argv) {
|
|
|
42932
43211
|
let noTui = false;
|
|
42933
43212
|
let json3 = false;
|
|
42934
43213
|
let prompt;
|
|
43214
|
+
let model;
|
|
43215
|
+
let reasoningEffort;
|
|
42935
43216
|
let positionalOnly = false;
|
|
42936
|
-
for (
|
|
43217
|
+
for (let index = 1;index < argv.length; index += 1) {
|
|
43218
|
+
const token = argv[index];
|
|
42937
43219
|
if (!positionalOnly && token === "--") {
|
|
42938
43220
|
positionalOnly = true;
|
|
42939
43221
|
continue;
|
|
@@ -42946,6 +43228,17 @@ function parseSessionAttach(argv) {
|
|
|
42946
43228
|
json3 = true;
|
|
42947
43229
|
continue;
|
|
42948
43230
|
}
|
|
43231
|
+
if (!positionalOnly && (token === "--model" || token === "--reasoning-effort")) {
|
|
43232
|
+
const value = argv[index + 1];
|
|
43233
|
+
if (!value || value.startsWith("--"))
|
|
43234
|
+
throw new Error(`${token} requires a value.`);
|
|
43235
|
+
index += 1;
|
|
43236
|
+
if (token === "--model")
|
|
43237
|
+
model = parseModelFlag(value);
|
|
43238
|
+
else
|
|
43239
|
+
reasoningEffort = parseReasoningEffortFlag(value);
|
|
43240
|
+
continue;
|
|
43241
|
+
}
|
|
42949
43242
|
if (!positionalOnly && token.startsWith("--"))
|
|
42950
43243
|
throw new Error(`Unknown --session flag ${token}.`);
|
|
42951
43244
|
if (prompt !== undefined)
|
|
@@ -42954,7 +43247,28 @@ function parseSessionAttach(argv) {
|
|
|
42954
43247
|
throw new Error("A follow-up prompt must not be empty.");
|
|
42955
43248
|
prompt = token;
|
|
42956
43249
|
}
|
|
42957
|
-
|
|
43250
|
+
const agent = sessionAgentChange({ model, reasoningEffort });
|
|
43251
|
+
if (agent && prompt === undefined)
|
|
43252
|
+
throw new Error("--model and --reasoning-effort change the session with a follow-up message. Pass a prompt too.");
|
|
43253
|
+
return {
|
|
43254
|
+
name: "session",
|
|
43255
|
+
sessionId,
|
|
43256
|
+
noTui,
|
|
43257
|
+
json: json3,
|
|
43258
|
+
...prompt === undefined ? {} : { followUp: { prompt, ...agent ? { agent } : {} } }
|
|
43259
|
+
};
|
|
43260
|
+
}
|
|
43261
|
+
function parseModelFlag(value) {
|
|
43262
|
+
const model = parseNewSessionModel(value);
|
|
43263
|
+
if (!model)
|
|
43264
|
+
throw new Error(`--model must name a supported model: ${newSessionModels.join(", ")}.`);
|
|
43265
|
+
return model;
|
|
43266
|
+
}
|
|
43267
|
+
function parseReasoningEffortFlag(value) {
|
|
43268
|
+
const reasoningEffort = parseNewSessionReasoningEffort(value);
|
|
43269
|
+
if (!reasoningEffort)
|
|
43270
|
+
throw new Error(`--reasoning-effort must be ${newSessionReasoningEfforts.slice(0, -1).join(", ")}, or ${newSessionReasoningEfforts.at(-1)}.`);
|
|
43271
|
+
return reasoningEffort;
|
|
42958
43272
|
}
|
|
42959
43273
|
function parseNewCommand(argv) {
|
|
42960
43274
|
const repositories = [];
|
|
@@ -42990,15 +43304,11 @@ function parseNewCommand(argv) {
|
|
|
42990
43304
|
} else if (token === "--attach") {
|
|
42991
43305
|
attachments.push(value);
|
|
42992
43306
|
} else if (token === "--model") {
|
|
42993
|
-
model =
|
|
42994
|
-
if (!model)
|
|
42995
|
-
throw new Error(`--model must name a supported model: ${newSessionModels.join(", ")}.`);
|
|
43307
|
+
model = parseModelFlag(value);
|
|
42996
43308
|
} else if (token === "--installation") {
|
|
42997
43309
|
installationId = value;
|
|
42998
43310
|
} else if (token === "--reasoning-effort") {
|
|
42999
|
-
|
|
43000
|
-
throw new Error("--reasoning-effort must be low, medium, high, or xhigh.");
|
|
43001
|
-
reasoningEffort = value;
|
|
43311
|
+
reasoningEffort = parseReasoningEffortFlag(value);
|
|
43002
43312
|
} else {
|
|
43003
43313
|
throw new Error(`Unknown new flag ${token}.`);
|
|
43004
43314
|
}
|