@meistrari/remy-cli 1.8.0 → 1.10.0
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 +4 -2
- package/dist/remy.js +294 -55
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ The dashboard is the starting point for all interactive work. It refreshes the v
|
|
|
36
36
|
|
|
37
37
|
### Start work
|
|
38
38
|
|
|
39
|
-
Press `n` in the dashboard. The new-session flow asks what you want done, selects a GitHub installation when needed, suggests repositories based on your request, and lets you review those suggestions. Before creating the session, choose the agent model and reasoning effort.
|
|
39
|
+
Press `n` in the dashboard. The new-session flow asks what you want done, selects a GitHub installation when needed, suggests repositories based on your request, and lets you review those suggestions. Before creating the session, choose the agent model and reasoning effort. The wizard starts with `gpt-6-astra` and `medium` reasoning by default. Remy then opens the session and streams its activity.
|
|
40
40
|
|
|
41
41
|
Use `Tab` while writing the request to complete a local file path. Remy attaches selected paths when you confirm the request. On macOS, `Ctrl+V` adds a PNG from the system clipboard to the request; Remy attaches it on confirmation. Remy uploads files before creating the session.
|
|
42
42
|
|
|
@@ -44,6 +44,8 @@ Use `Tab` while writing the request to complete a local file path. Remy attaches
|
|
|
44
44
|
|
|
45
45
|
Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. 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 a session, type a follow-up and press `Enter` to send it.
|
|
46
46
|
|
|
47
|
+
The **Live reasoning preview** shows the newest main-agent summary as it arrives. It is a short, best-effort preview—not private chain-of-thought. Long previews show **Preview shortened.** Opening or reconnecting partway through a summary may show no preview; the final summary still appears in activity history. Disconnecting or finishing the item clears the live preview.
|
|
48
|
+
|
|
47
49
|
Published files and Tela Pages appear in the timeline. A Tela Page row includes its title and canonical URL so you can open it directly from the terminal.
|
|
48
50
|
|
|
49
51
|
When Remy creates a plan, the session shows its checklist in the timeline and keeps `Plan <done>/<total>` with the current item pinned above the composer. Updates change the same checklist instead of producing repeated rows, and an unfinished plan remains visible after reconnecting or between turns. The collapsed timeline shows up to five plan items; press `Ctrl+O` for the complete checklist and activity detail.
|
|
@@ -74,7 +76,7 @@ The interactive dashboard is the recommended path. Use these commands when a scr
|
|
|
74
76
|
remy new --repository owner/repository "Add a health check endpoint"
|
|
75
77
|
```
|
|
76
78
|
|
|
77
|
-
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. Direct creation uses `
|
|
79
|
+
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. Direct creation uses `medium` reasoning unless `--reasoning-effort` overrides it; omit `--model` to use the server's `gpt-6-astra` default. `remy new` creates the session from the prompt and flags, then opens it when the terminal is interactive.
|
|
78
80
|
|
|
79
81
|
### Open a known session
|
|
80
82
|
|
package/dist/remy.js
CHANGED
|
@@ -32083,11 +32083,13 @@ var agentCommandSchema = zod_default2.union([
|
|
|
32083
32083
|
]);
|
|
32084
32084
|
// ../../packages/agents-protocol/src/agent-model.ts
|
|
32085
32085
|
var codexModelIds = [
|
|
32086
|
+
"gpt-6-astra",
|
|
32086
32087
|
"gpt-5.6-sol",
|
|
32088
|
+
"gpt-5.6-terra",
|
|
32089
|
+
"gpt-5.6-luna",
|
|
32087
32090
|
"gpt-5.5",
|
|
32088
32091
|
"gpt-5.4",
|
|
32089
32092
|
"gpt-5.4-mini",
|
|
32090
|
-
"gpt-5.3-codex",
|
|
32091
32093
|
"gpt-5.2"
|
|
32092
32094
|
];
|
|
32093
32095
|
var claudeModelIds = [
|
|
@@ -32553,41 +32555,55 @@ var agentEventSchema = zod_default2.discriminatedUnion("type", [
|
|
|
32553
32555
|
// ../../packages/agents-protocol/src/agent-presentation.ts
|
|
32554
32556
|
var CODEX_CONTEXT_WINDOW = 272000;
|
|
32555
32557
|
var codexModelPresentation = {
|
|
32558
|
+
"gpt-6-astra": {
|
|
32559
|
+
label: "GPT 6.0 Astra",
|
|
32560
|
+
description: "Our most capable model for complex, demanding work.",
|
|
32561
|
+
relativeCost: 5,
|
|
32562
|
+
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32563
|
+
isMultiModal: true
|
|
32564
|
+
},
|
|
32556
32565
|
"gpt-5.6-sol": {
|
|
32557
|
-
label: "GPT
|
|
32558
|
-
description: "
|
|
32566
|
+
label: "GPT 5.6 Sol",
|
|
32567
|
+
description: "Reliable agentic workhorse for everyday tasks.",
|
|
32559
32568
|
relativeCost: 5,
|
|
32560
32569
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32561
32570
|
isMultiModal: true
|
|
32562
32571
|
},
|
|
32572
|
+
"gpt-5.6-terra": {
|
|
32573
|
+
label: "GPT 5.6 Terra",
|
|
32574
|
+
description: "Balanced agentic coding model for everyday work.",
|
|
32575
|
+
relativeCost: 3,
|
|
32576
|
+
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32577
|
+
isMultiModal: true
|
|
32578
|
+
},
|
|
32579
|
+
"gpt-5.6-luna": {
|
|
32580
|
+
label: "GPT 5.6 Luna",
|
|
32581
|
+
description: "Fast and affordable agentic coding model.",
|
|
32582
|
+
relativeCost: 2,
|
|
32583
|
+
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32584
|
+
isMultiModal: true
|
|
32585
|
+
},
|
|
32563
32586
|
"gpt-5.5": {
|
|
32564
|
-
label: "GPT
|
|
32565
|
-
description: "
|
|
32587
|
+
label: "GPT 5.5",
|
|
32588
|
+
description: "Proven previous-generation model for coding and general work.",
|
|
32566
32589
|
relativeCost: 4,
|
|
32567
32590
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32568
32591
|
isMultiModal: true
|
|
32569
32592
|
},
|
|
32570
32593
|
"gpt-5.4": {
|
|
32571
|
-
label: "GPT
|
|
32594
|
+
label: "GPT 5.4",
|
|
32572
32595
|
description: "Strong model for everyday coding.",
|
|
32573
32596
|
relativeCost: 3,
|
|
32574
32597
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32575
32598
|
isMultiModal: true
|
|
32576
32599
|
},
|
|
32577
32600
|
"gpt-5.4-mini": {
|
|
32578
|
-
label: "GPT
|
|
32601
|
+
label: "GPT 5.4 Mini",
|
|
32579
32602
|
description: "Small, fast, and cost-efficient model for simpler coding tasks.",
|
|
32580
32603
|
relativeCost: 2,
|
|
32581
32604
|
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32582
32605
|
isMultiModal: true
|
|
32583
32606
|
},
|
|
32584
|
-
"gpt-5.3-codex": {
|
|
32585
|
-
label: "GPT-5.3-Codex",
|
|
32586
|
-
description: "Code-tuned model for focused engineering tasks.",
|
|
32587
|
-
relativeCost: 3,
|
|
32588
|
-
maxInputTokens: CODEX_CONTEXT_WINDOW,
|
|
32589
|
-
isMultiModal: true
|
|
32590
|
-
},
|
|
32591
32607
|
"gpt-5.2": {
|
|
32592
32608
|
label: "GPT-5.2",
|
|
32593
32609
|
description: "Optimized for professional work and long-running agents.",
|
|
@@ -32991,7 +33007,8 @@ async function* streamSessionEvents({
|
|
|
32991
33007
|
sessionId,
|
|
32992
33008
|
lastRetainedEventId,
|
|
32993
33009
|
maxReconnects = 0,
|
|
32994
|
-
signal
|
|
33010
|
+
signal,
|
|
33011
|
+
onSynchronized
|
|
32995
33012
|
}) {
|
|
32996
33013
|
let retainedCursor = lastRetainedEventId;
|
|
32997
33014
|
let reconnects = 0;
|
|
@@ -33005,7 +33022,7 @@ async function* streamSessionEvents({
|
|
|
33005
33022
|
});
|
|
33006
33023
|
if (!response.body)
|
|
33007
33024
|
throw new CodingAgentProtocolError("Session event stream response did not include a readable body.");
|
|
33008
|
-
for await (const frame of parseSessionEventStream(response.body)) {
|
|
33025
|
+
for await (const frame of parseSessionEventStream(response.body, { onSynchronized })) {
|
|
33009
33026
|
if (frame.kind === "retained")
|
|
33010
33027
|
retainedCursor = frame.id;
|
|
33011
33028
|
yield frame;
|
|
@@ -33015,21 +33032,33 @@ async function* streamSessionEvents({
|
|
|
33015
33032
|
reconnects += 1;
|
|
33016
33033
|
}
|
|
33017
33034
|
}
|
|
33018
|
-
async function* parseSessionEventStream(stream) {
|
|
33019
|
-
for await (const message of parseServerSentEvents(stream)) {
|
|
33035
|
+
async function* parseSessionEventStream(stream, { onSynchronized } = {}) {
|
|
33036
|
+
for await (const message of parseServerSentEvents(stream, { onSynchronized })) {
|
|
33020
33037
|
if (message.event !== undefined && message.event !== "session-event")
|
|
33021
33038
|
continue;
|
|
33022
33039
|
yield parseSessionEventMessage(message);
|
|
33023
33040
|
}
|
|
33024
33041
|
}
|
|
33025
|
-
async function* parseServerSentEvents(stream) {
|
|
33042
|
+
async function* parseServerSentEvents(stream, { onSynchronized }) {
|
|
33026
33043
|
const decoder2 = new TextDecoder;
|
|
33027
33044
|
const reader = stream.getReader();
|
|
33028
33045
|
let buffer = "";
|
|
33029
33046
|
let messageId;
|
|
33030
33047
|
let eventName;
|
|
33031
33048
|
let dataLines = [];
|
|
33032
|
-
|
|
33049
|
+
let frameLineCount = 0;
|
|
33050
|
+
let hasSynchronizationComment = false;
|
|
33051
|
+
let synchronized = false;
|
|
33052
|
+
function dispatch(completeFrame) {
|
|
33053
|
+
const isSynchronizationFrame = completeFrame && frameLineCount === 1 && hasSynchronizationComment;
|
|
33054
|
+
frameLineCount = 0;
|
|
33055
|
+
hasSynchronizationComment = false;
|
|
33056
|
+
if (isSynchronizationFrame) {
|
|
33057
|
+
if (synchronized)
|
|
33058
|
+
throw new CodingAgentProtocolError("Session event stream contained more than one synchronization marker.");
|
|
33059
|
+
synchronized = true;
|
|
33060
|
+
onSynchronized?.();
|
|
33061
|
+
}
|
|
33033
33062
|
if (dataLines.length === 0) {
|
|
33034
33063
|
messageId = undefined;
|
|
33035
33064
|
eventName = undefined;
|
|
@@ -33048,7 +33077,10 @@ async function* parseServerSentEvents(stream) {
|
|
|
33048
33077
|
}
|
|
33049
33078
|
function applyLine(line) {
|
|
33050
33079
|
if (line === "")
|
|
33051
|
-
return dispatch();
|
|
33080
|
+
return dispatch(true);
|
|
33081
|
+
frameLineCount += 1;
|
|
33082
|
+
if (line === ": synchronized")
|
|
33083
|
+
hasSynchronizationComment = true;
|
|
33052
33084
|
if (line.startsWith(":"))
|
|
33053
33085
|
return null;
|
|
33054
33086
|
const separatorIndex = line.indexOf(":");
|
|
@@ -33086,7 +33118,7 @@ async function* parseServerSentEvents(stream) {
|
|
|
33086
33118
|
if (message)
|
|
33087
33119
|
yield message;
|
|
33088
33120
|
}
|
|
33089
|
-
const finalMessage = dispatch();
|
|
33121
|
+
const finalMessage = dispatch(false);
|
|
33090
33122
|
if (finalMessage)
|
|
33091
33123
|
yield finalMessage;
|
|
33092
33124
|
} finally {
|
|
@@ -33696,8 +33728,8 @@ function newSessionReasoningEffortLabel(effort) {
|
|
|
33696
33728
|
var newSessionModels = codexModelIds;
|
|
33697
33729
|
var newSessionReasoningEfforts = selectableAgentReasoningEfforts;
|
|
33698
33730
|
var defaultNewSessionAgent = {
|
|
33699
|
-
model:
|
|
33700
|
-
reasoningEffort: "
|
|
33731
|
+
model: "gpt-6-astra",
|
|
33732
|
+
reasoningEffort: "medium"
|
|
33701
33733
|
};
|
|
33702
33734
|
|
|
33703
33735
|
// src/sessions/session-controller.ts
|
|
@@ -33860,10 +33892,6 @@ var agentMessageDeltaEventSchema = exports_external2.object({
|
|
|
33860
33892
|
type: exports_external2.literal("agent.message.delta"),
|
|
33861
33893
|
payload: exports_external2.object({ role: exports_external2.string(), delta: exports_external2.string() }).passthrough()
|
|
33862
33894
|
}).passthrough();
|
|
33863
|
-
var agentReasoningSummaryDeltaEventSchema = exports_external2.object({
|
|
33864
|
-
type: exports_external2.literal("agent.reasoning.summary.delta"),
|
|
33865
|
-
payload: exports_external2.object({ text: exports_external2.string() }).passthrough()
|
|
33866
|
-
}).passthrough();
|
|
33867
33895
|
var publicMessageContentSegmentSchema = exports_external2.discriminatedUnion("type", [
|
|
33868
33896
|
exports_external2.strictObject({ type: exports_external2.literal("text"), text: exports_external2.string() }),
|
|
33869
33897
|
exports_external2.strictObject({
|
|
@@ -33966,13 +33994,6 @@ function projectEphemeralEvent({ state, event }) {
|
|
|
33966
33994
|
previews: { ...state.previews, assistantText: state.previews.assistantText + messageDelta.data.payload.delta }
|
|
33967
33995
|
};
|
|
33968
33996
|
}
|
|
33969
|
-
const reasoningDelta = agentReasoningSummaryDeltaEventSchema.safeParse(event);
|
|
33970
|
-
if (reasoningDelta.success) {
|
|
33971
|
-
return {
|
|
33972
|
-
...state,
|
|
33973
|
-
previews: { ...state.previews, reasoningText: state.previews.reasoningText + reasoningDelta.data.payload.text }
|
|
33974
|
-
};
|
|
33975
|
-
}
|
|
33976
33997
|
return state;
|
|
33977
33998
|
}
|
|
33978
33999
|
function projectRetainedEvent({
|
|
@@ -34120,8 +34141,7 @@ function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId })
|
|
|
34120
34141
|
retainedTurnStarts: { ...state.retainedTurnStarts, [agentEvent.turnId]: { actorType: agentEvent.actor.type, startedAt: occurredAt } },
|
|
34121
34142
|
messageTurns: Object.fromEntries(Object.entries(state.messageTurns).map(([messageId, turn]) => [messageId, turn.turnId === agentEvent.turnId ? { ...turn, startedAt: occurredAt } : turn]))
|
|
34122
34143
|
} : state;
|
|
34123
|
-
|
|
34124
|
-
return appendActivity({ state: stateWithCompletedReasoning, retainedEventId, occurredAt, card: toAgentActivityCard(agentEvent) });
|
|
34144
|
+
return appendActivity({ state: stateWithTurnStart, retainedEventId, occurredAt, card: toAgentActivityCard(agentEvent) });
|
|
34125
34145
|
}
|
|
34126
34146
|
function projectAgentWorkObserved({
|
|
34127
34147
|
state,
|
|
@@ -34311,6 +34331,16 @@ var terminalControlPattern = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g;
|
|
|
34311
34331
|
function stripAnsi(value) {
|
|
34312
34332
|
return value.replace(ansiEscapePattern, "").replace(terminalControlPattern, "");
|
|
34313
34333
|
}
|
|
34334
|
+
function formatReasoningPreview(item) {
|
|
34335
|
+
if (item.status === "absent")
|
|
34336
|
+
return "";
|
|
34337
|
+
const preview = stripAnsi(item.text).trim();
|
|
34338
|
+
if (!item.truncated)
|
|
34339
|
+
return preview;
|
|
34340
|
+
return preview.length > 0 ? `${preview}
|
|
34341
|
+
|
|
34342
|
+
Preview shortened.` : "Preview shortened.";
|
|
34343
|
+
}
|
|
34314
34344
|
function providerText(raw, fallback) {
|
|
34315
34345
|
const cleaned = stripAnsi(raw ?? "").trim();
|
|
34316
34346
|
return cleaned.length > 0 ? cleaned : fallback;
|
|
@@ -34328,6 +34358,127 @@ function toSessionPullRequest(detail) {
|
|
|
34328
34358
|
return pullRequest ? { number: pullRequest.number, status: pullRequest.status, draft: pullRequest.draft } : null;
|
|
34329
34359
|
}
|
|
34330
34360
|
|
|
34361
|
+
// src/sessions/reasoning-preview.ts
|
|
34362
|
+
var maximumPrefixLength = 2000;
|
|
34363
|
+
var absentItem = { status: "absent" };
|
|
34364
|
+
function initialReasoningPreviewState() {
|
|
34365
|
+
return {
|
|
34366
|
+
synchronized: false,
|
|
34367
|
+
sequenceFloor: -1,
|
|
34368
|
+
runtime: "active",
|
|
34369
|
+
lastSessionStartedEventId: null,
|
|
34370
|
+
item: absentItem
|
|
34371
|
+
};
|
|
34372
|
+
}
|
|
34373
|
+
function reduceReasoningPreview(state, input) {
|
|
34374
|
+
if (input.type === "synchronized")
|
|
34375
|
+
return state.synchronized ? state : { ...state, synchronized: true };
|
|
34376
|
+
const event = input.event;
|
|
34377
|
+
if (event.type === "agent.session.started") {
|
|
34378
|
+
if (event.eventId === state.lastSessionStartedEventId)
|
|
34379
|
+
return state;
|
|
34380
|
+
return {
|
|
34381
|
+
...state,
|
|
34382
|
+
sequenceFloor: event.sequence,
|
|
34383
|
+
runtime: "active",
|
|
34384
|
+
lastSessionStartedEventId: event.eventId,
|
|
34385
|
+
item: absentItem
|
|
34386
|
+
};
|
|
34387
|
+
}
|
|
34388
|
+
if (event.type === "agent.session.ended") {
|
|
34389
|
+
return {
|
|
34390
|
+
...state,
|
|
34391
|
+
sequenceFloor: Math.max(state.sequenceFloor, event.sequence),
|
|
34392
|
+
runtime: "ended",
|
|
34393
|
+
item: absentItem
|
|
34394
|
+
};
|
|
34395
|
+
}
|
|
34396
|
+
if (!isMainReasoningOrTurnEvent(event) || state.runtime === "ended")
|
|
34397
|
+
return state;
|
|
34398
|
+
const matchingRetainedEnd = state.item.status === "active" && state.item.turnId === event.turnId && (event.type === "agent.turn.ended" || event.type === "agent.reasoning.ended" && state.item.reasoningId === event.payload.reasoningId);
|
|
34399
|
+
if (event.sequence <= state.sequenceFloor && !matchingRetainedEnd)
|
|
34400
|
+
return state;
|
|
34401
|
+
const advancedState = { ...state, sequenceFloor: Math.max(state.sequenceFloor, event.sequence) };
|
|
34402
|
+
switch (event.type) {
|
|
34403
|
+
case "agent.reasoning.started": {
|
|
34404
|
+
if (!state.synchronized)
|
|
34405
|
+
return advancedState;
|
|
34406
|
+
if (state.item.status === "active" && sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
|
|
34407
|
+
return advancedState;
|
|
34408
|
+
}
|
|
34409
|
+
return {
|
|
34410
|
+
...advancedState,
|
|
34411
|
+
item: {
|
|
34412
|
+
status: "active",
|
|
34413
|
+
turnId: event.turnId,
|
|
34414
|
+
reasoningId: event.payload.reasoningId,
|
|
34415
|
+
text: "",
|
|
34416
|
+
truncated: false
|
|
34417
|
+
}
|
|
34418
|
+
};
|
|
34419
|
+
}
|
|
34420
|
+
case "agent.reasoning.summary.delta": {
|
|
34421
|
+
if (state.item.status !== "active" || !sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
|
|
34422
|
+
return advancedState;
|
|
34423
|
+
}
|
|
34424
|
+
return {
|
|
34425
|
+
...advancedState,
|
|
34426
|
+
item: appendBoundedPrefix(state.item, event.payload.text)
|
|
34427
|
+
};
|
|
34428
|
+
}
|
|
34429
|
+
case "agent.reasoning.ended": {
|
|
34430
|
+
if (state.item.status !== "active" || !sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
|
|
34431
|
+
return advancedState;
|
|
34432
|
+
}
|
|
34433
|
+
return { ...advancedState, item: absentItem };
|
|
34434
|
+
}
|
|
34435
|
+
case "agent.turn.started": {
|
|
34436
|
+
if (state.item.status === "active" && state.item.turnId !== event.turnId)
|
|
34437
|
+
return { ...advancedState, item: absentItem };
|
|
34438
|
+
return advancedState;
|
|
34439
|
+
}
|
|
34440
|
+
case "agent.turn.ended": {
|
|
34441
|
+
if (state.item.status === "active" && state.item.turnId === event.turnId)
|
|
34442
|
+
return { ...advancedState, item: absentItem };
|
|
34443
|
+
return advancedState;
|
|
34444
|
+
}
|
|
34445
|
+
}
|
|
34446
|
+
}
|
|
34447
|
+
function isMainReasoningOrTurnEvent(event) {
|
|
34448
|
+
if (event.type !== "agent.reasoning.started" && event.type !== "agent.reasoning.summary.delta" && event.type !== "agent.reasoning.ended" && event.type !== "agent.turn.started" && event.type !== "agent.turn.ended") {
|
|
34449
|
+
return false;
|
|
34450
|
+
}
|
|
34451
|
+
return event.actor.type === "main";
|
|
34452
|
+
}
|
|
34453
|
+
function sameReasoningItem({
|
|
34454
|
+
item,
|
|
34455
|
+
turnId,
|
|
34456
|
+
reasoningId
|
|
34457
|
+
}) {
|
|
34458
|
+
return item.turnId === turnId && item.reasoningId === reasoningId;
|
|
34459
|
+
}
|
|
34460
|
+
function appendBoundedPrefix(item, text) {
|
|
34461
|
+
if (item.truncated)
|
|
34462
|
+
return item;
|
|
34463
|
+
const availableLength = maximumPrefixLength - item.text.length;
|
|
34464
|
+
let retainedLength = Math.min(availableLength, text.length);
|
|
34465
|
+
const reachesSizeBound = item.text.length + retainedLength === maximumPrefixLength;
|
|
34466
|
+
if (reachesSizeBound && retainedLength > 0 && isHighSurrogate(text.charCodeAt(retainedLength - 1)))
|
|
34467
|
+
retainedLength -= 1;
|
|
34468
|
+
const discardedInput = retainedLength < text.length;
|
|
34469
|
+
if (retainedLength === 0) {
|
|
34470
|
+
return discardedInput && !item.truncated ? { ...item, truncated: true } : item;
|
|
34471
|
+
}
|
|
34472
|
+
return {
|
|
34473
|
+
...item,
|
|
34474
|
+
text: item.text + text.slice(0, retainedLength),
|
|
34475
|
+
truncated: item.truncated || discardedInput
|
|
34476
|
+
};
|
|
34477
|
+
}
|
|
34478
|
+
function isHighSurrogate(codeUnit) {
|
|
34479
|
+
return codeUnit >= 55296 && codeUnit <= 56319;
|
|
34480
|
+
}
|
|
34481
|
+
|
|
34331
34482
|
// src/sessions/session-controller.ts
|
|
34332
34483
|
var remoteSessionReconnectPolicy = {
|
|
34333
34484
|
initialBackoffMs: 1000,
|
|
@@ -34366,6 +34517,9 @@ function createRemoteSessionController(dependencies) {
|
|
|
34366
34517
|
let stopped = false;
|
|
34367
34518
|
let state;
|
|
34368
34519
|
let cachedLastRetainedEventId;
|
|
34520
|
+
let reasoningPreviewState = initialReasoningPreviewState();
|
|
34521
|
+
let reasoningConnectionGeneration = 0;
|
|
34522
|
+
let reasoningHistorySequenceFloor = -1;
|
|
34369
34523
|
async function start(input) {
|
|
34370
34524
|
stopped = false;
|
|
34371
34525
|
ready = new Promise((resolve) => {
|
|
@@ -34379,14 +34533,17 @@ function createRemoteSessionController(dependencies) {
|
|
|
34379
34533
|
});
|
|
34380
34534
|
resolveReady();
|
|
34381
34535
|
publishState();
|
|
34382
|
-
if (input.mode === "cold-resume")
|
|
34383
|
-
|
|
34536
|
+
if (input.mode === "cold-resume") {
|
|
34537
|
+
const hydrationGeneration = beginReasoningAttempt();
|
|
34538
|
+
await hydrateRetainedHistoryFromBeginning(hydrationGeneration);
|
|
34539
|
+
}
|
|
34384
34540
|
await streamWithControllerReconnects();
|
|
34385
34541
|
}
|
|
34386
34542
|
function stop() {
|
|
34387
34543
|
if (stopped)
|
|
34388
34544
|
return;
|
|
34389
34545
|
stopped = true;
|
|
34546
|
+
invalidateReasoningAttempt({ publish: true });
|
|
34390
34547
|
abortController.abort(new Error("Remote session controller stopped."));
|
|
34391
34548
|
}
|
|
34392
34549
|
function subscribe(listener) {
|
|
@@ -34421,10 +34578,14 @@ function createRemoteSessionController(dependencies) {
|
|
|
34421
34578
|
publishState();
|
|
34422
34579
|
}
|
|
34423
34580
|
function updateDetail(detail) {
|
|
34581
|
+
if (detail.status !== "open")
|
|
34582
|
+
invalidateReasoningAttempt({ publish: false });
|
|
34424
34583
|
state = updateSessionDetail({ state: getState(), detail });
|
|
34584
|
+
if (detail.status !== "open")
|
|
34585
|
+
state = withoutReasoningPreview(state);
|
|
34425
34586
|
publishState();
|
|
34426
34587
|
}
|
|
34427
|
-
async function hydrateRetainedHistoryFromBeginning() {
|
|
34588
|
+
async function hydrateRetainedHistoryFromBeginning(generation) {
|
|
34428
34589
|
let after;
|
|
34429
34590
|
while (true) {
|
|
34430
34591
|
if (stopped)
|
|
@@ -34436,10 +34597,13 @@ function createRemoteSessionController(dependencies) {
|
|
|
34436
34597
|
});
|
|
34437
34598
|
for (const item of page.data) {
|
|
34438
34599
|
await reduceFrameAndPersist({
|
|
34439
|
-
|
|
34440
|
-
|
|
34441
|
-
|
|
34442
|
-
|
|
34600
|
+
frame: {
|
|
34601
|
+
kind: "retained",
|
|
34602
|
+
id: String(item.history_sequence),
|
|
34603
|
+
event: "session-event",
|
|
34604
|
+
data: item
|
|
34605
|
+
},
|
|
34606
|
+
generation
|
|
34443
34607
|
});
|
|
34444
34608
|
}
|
|
34445
34609
|
if (!page.has_more || !page.next_cursor)
|
|
@@ -34453,27 +34617,33 @@ function createRemoteSessionController(dependencies) {
|
|
|
34453
34617
|
while (true) {
|
|
34454
34618
|
if (stopped)
|
|
34455
34619
|
return;
|
|
34620
|
+
const generation = beginReasoningAttempt();
|
|
34456
34621
|
state = markSessionConnected(getState());
|
|
34457
34622
|
publishState();
|
|
34458
34623
|
try {
|
|
34459
34624
|
const stream = await dependencies.openEventStream({
|
|
34460
34625
|
sessionId: dependencies.sessionId,
|
|
34461
34626
|
lastRetainedEventId: cachedLastRetainedEventId,
|
|
34462
|
-
signal: abortController.signal
|
|
34627
|
+
signal: abortController.signal,
|
|
34628
|
+
onSynchronized: () => synchronizeReasoningAttempt(generation)
|
|
34463
34629
|
});
|
|
34464
34630
|
for await (const frame of stream) {
|
|
34465
34631
|
if (stopped)
|
|
34466
34632
|
return;
|
|
34467
|
-
await reduceFrameAndPersist(frame);
|
|
34633
|
+
await reduceFrameAndPersist({ frame, generation });
|
|
34468
34634
|
}
|
|
34635
|
+
endReasoningAttempt(generation);
|
|
34469
34636
|
} catch (error93) {
|
|
34637
|
+
endReasoningAttempt(generation);
|
|
34470
34638
|
if (stopped)
|
|
34471
34639
|
return;
|
|
34472
34640
|
if (error93 instanceof Error && error93.name === "SessionProjectionProtocolError")
|
|
34473
34641
|
throw error93;
|
|
34642
|
+
const refreshGeneration = reasoningConnectionGeneration;
|
|
34474
34643
|
const detail = await dependencies.getSession({ sessionId: dependencies.sessionId });
|
|
34475
|
-
|
|
34476
|
-
|
|
34644
|
+
if (stopped || refreshGeneration !== reasoningConnectionGeneration)
|
|
34645
|
+
return;
|
|
34646
|
+
updateDetail(detail);
|
|
34477
34647
|
}
|
|
34478
34648
|
if (stopped)
|
|
34479
34649
|
return;
|
|
@@ -34499,17 +34669,86 @@ function createRemoteSessionController(dependencies) {
|
|
|
34499
34669
|
backoffMs = Math.min(backoffMs * 2, reconnectPolicy.maxBackoffMs);
|
|
34500
34670
|
}
|
|
34501
34671
|
}
|
|
34502
|
-
async function reduceFrameAndPersist(frame) {
|
|
34503
|
-
const
|
|
34672
|
+
async function reduceFrameAndPersist({ frame, generation }) {
|
|
34673
|
+
const previousState = getState();
|
|
34674
|
+
const projectedState = projectRemoteSessionEvent({ state: previousState, frame });
|
|
34675
|
+
state = projectReasoningPreview({ previousState, projectedState, frame, generation });
|
|
34504
34676
|
if (frame.kind === "retained") {
|
|
34505
|
-
state = nextState;
|
|
34506
34677
|
await writeCache();
|
|
34507
|
-
cachedLastRetainedEventId =
|
|
34678
|
+
cachedLastRetainedEventId = projectedState.lastRetainedEventId;
|
|
34508
34679
|
}
|
|
34509
|
-
state = nextState;
|
|
34510
34680
|
resolveCompletedWaiters();
|
|
34681
|
+
if (stopped)
|
|
34682
|
+
return;
|
|
34511
34683
|
publishState(frame);
|
|
34512
34684
|
}
|
|
34685
|
+
function projectReasoningPreview({
|
|
34686
|
+
previousState,
|
|
34687
|
+
projectedState,
|
|
34688
|
+
frame,
|
|
34689
|
+
generation
|
|
34690
|
+
}) {
|
|
34691
|
+
if (generation !== reasoningConnectionGeneration || projectedState.aggregateStatus !== "open")
|
|
34692
|
+
return withoutReasoningPreview(projectedState);
|
|
34693
|
+
if (frame.kind === "retained") {
|
|
34694
|
+
if (previousState.seenRetainedEventIds[frame.id])
|
|
34695
|
+
return projectedState;
|
|
34696
|
+
if (frame.data.history_sequence <= reasoningHistorySequenceFloor)
|
|
34697
|
+
return projectedState;
|
|
34698
|
+
reasoningHistorySequenceFloor = frame.data.history_sequence;
|
|
34699
|
+
} else if (frame.data.event.type !== "agent.reasoning.summary.delta") {
|
|
34700
|
+
return projectedState;
|
|
34701
|
+
}
|
|
34702
|
+
if (frame.data.event.type === "agent.message.ended")
|
|
34703
|
+
return projectedState;
|
|
34704
|
+
const parsed = wrappedAgentEventSchema.safeParse(frame.data.event);
|
|
34705
|
+
if (!parsed.success)
|
|
34706
|
+
return projectedState;
|
|
34707
|
+
reasoningPreviewState = reduceReasoningPreview(reasoningPreviewState, { type: "event", event: parsed.data });
|
|
34708
|
+
return {
|
|
34709
|
+
...projectedState,
|
|
34710
|
+
previews: {
|
|
34711
|
+
...projectedState.previews,
|
|
34712
|
+
reasoningText: formatReasoningPreview(reasoningPreviewState.item)
|
|
34713
|
+
}
|
|
34714
|
+
};
|
|
34715
|
+
}
|
|
34716
|
+
function beginReasoningAttempt() {
|
|
34717
|
+
reasoningConnectionGeneration += 1;
|
|
34718
|
+
reasoningPreviewState = initialReasoningPreviewState();
|
|
34719
|
+
reasoningHistorySequenceFloor = -1;
|
|
34720
|
+
if (state)
|
|
34721
|
+
state = withoutReasoningPreview(state);
|
|
34722
|
+
return reasoningConnectionGeneration;
|
|
34723
|
+
}
|
|
34724
|
+
function synchronizeReasoningAttempt(generation) {
|
|
34725
|
+
if (stopped || generation !== reasoningConnectionGeneration || getState().aggregateStatus !== "open")
|
|
34726
|
+
return;
|
|
34727
|
+
reasoningPreviewState = reduceReasoningPreview(reasoningPreviewState, { type: "synchronized" });
|
|
34728
|
+
}
|
|
34729
|
+
function endReasoningAttempt(generation) {
|
|
34730
|
+
if (generation !== reasoningConnectionGeneration)
|
|
34731
|
+
return;
|
|
34732
|
+
invalidateReasoningAttempt({ publish: true });
|
|
34733
|
+
}
|
|
34734
|
+
function invalidateReasoningAttempt({ publish }) {
|
|
34735
|
+
reasoningConnectionGeneration += 1;
|
|
34736
|
+
reasoningPreviewState = initialReasoningPreviewState();
|
|
34737
|
+
reasoningHistorySequenceFloor = -1;
|
|
34738
|
+
if (!state || state.previews.reasoningText.length === 0)
|
|
34739
|
+
return;
|
|
34740
|
+
state = withoutReasoningPreview(state);
|
|
34741
|
+
if (publish)
|
|
34742
|
+
publishState();
|
|
34743
|
+
}
|
|
34744
|
+
function withoutReasoningPreview(currentState) {
|
|
34745
|
+
if (currentState.previews.reasoningText.length === 0)
|
|
34746
|
+
return currentState;
|
|
34747
|
+
return {
|
|
34748
|
+
...currentState,
|
|
34749
|
+
previews: { ...currentState.previews, reasoningText: "" }
|
|
34750
|
+
};
|
|
34751
|
+
}
|
|
34513
34752
|
async function writeCache() {
|
|
34514
34753
|
const currentState = getState();
|
|
34515
34754
|
const cache = {
|
|
@@ -37545,7 +37784,7 @@ var compactMarkRows = 9;
|
|
|
37545
37784
|
var compactMinWidth = 48;
|
|
37546
37785
|
var compactMinHeight = 20;
|
|
37547
37786
|
var markBrightnessGain = 4.2;
|
|
37548
|
-
var remyCliVersion = "1.
|
|
37787
|
+
var remyCliVersion = "1.10.0";
|
|
37549
37788
|
async function showRemySplash({
|
|
37550
37789
|
createRenderer = createRemyRenderer,
|
|
37551
37790
|
durationMs = splashDurationMs,
|
|
@@ -38798,7 +39037,7 @@ async function runAttachedSession({
|
|
|
38798
39037
|
environment: dependencies.environment,
|
|
38799
39038
|
getSession: async ({ sessionId: id }) => await operations.getSession({ client: operations.client, sessionId: id }),
|
|
38800
39039
|
listSessionEvents: async ({ sessionId: id, limit, after }) => await operations.listSessionEvents({ client: operations.client, sessionId: id, limit, after }),
|
|
38801
|
-
openEventStream: ({ sessionId: id, lastRetainedEventId, signal }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal })
|
|
39040
|
+
openEventStream: ({ sessionId: id, lastRetainedEventId, signal, onSynchronized }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal, onSynchronized })
|
|
38802
39041
|
});
|
|
38803
39042
|
const interactive = !noTui && !json3 && isInteractiveTerminal(dependencies);
|
|
38804
39043
|
const shouldPrintJson = !interactive || json3;
|