@gajae-code/coding-agent 0.11.10 → 0.12.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/CHANGELOG.md +86 -2
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/cli.d.ts +8 -1
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/config/model-profile-activation.d.ts +1 -0
- package/dist/types/config/model-profile-contract.d.ts +2 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +86 -3
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +43 -2
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
- package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +112 -1
- package/dist/types/gjc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
- package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
- package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
- package/dist/types/gjc-runtime/team-store.d.ts +12 -0
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +7 -0
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +1 -1
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +22 -9
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/welcome.d.ts +1 -0
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +7 -1
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/manager.d.ts +8 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +7 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -1
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/index.d.ts +18 -2
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +6 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +23 -3
- package/dist/types/sdk/host/control/operations.d.ts +2 -1
- package/dist/types/sdk/host/host.d.ts +2 -0
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/startup-capability.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +51 -19
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +27 -0
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +59 -13
- package/dist/types/session/streaming-output.d.ts +60 -5
- package/dist/types/skill-state/active-state.d.ts +0 -4
- package/dist/types/skill-state/workflow-hud.d.ts +3 -0
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/types.d.ts +36 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +17 -1
- package/dist/types/tools/output-meta.d.ts +21 -1
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -1
- package/dist/types/tools/resource-gc.d.ts +23 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/package.json +9 -13
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/generate-sdk-operation-inventory.ts +4 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/capability/index.ts +8 -0
- package/src/cli/args.ts +14 -8
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/read-cli.ts +2 -1
- package/src/cli.ts +49 -2
- package/src/commands/deep-interview.ts +29 -9
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/sdk.ts +91 -7
- package/src/commands/team.ts +1 -1
- package/src/config/model-profile-activation.ts +1 -0
- package/src/config/model-profile-contract.ts +13 -0
- package/src/config/model-profiles.ts +24 -0
- package/src/config/model-registry.ts +21 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +84 -3
- package/src/config/settings.ts +254 -108
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +229 -82
- package/src/defaults/gjc/skills/ralplan/SKILL.md +78 -26
- package/src/defaults/gjc/skills/team/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +26 -16
- package/src/eval/py/executor.ts +7 -2
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +42 -4
- package/src/extensibility/shared-events.ts +5 -0
- package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -68
- package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
- package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
- package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
- package/src/gjc-runtime/deep-interview-state.ts +12 -921
- package/src/gjc-runtime/gc-render.ts +1 -0
- package/src/gjc-runtime/gc-runtime.ts +11 -1
- package/src/gjc-runtime/linux-proc.ts +70 -36
- package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/gjc-runtime/ralplan-runtime.ts +979 -71
- package/src/gjc-runtime/state-runtime.ts +50 -12
- package/src/gjc-runtime/state-writer.ts +70 -222
- package/src/gjc-runtime/team-launch.ts +34 -5
- package/src/gjc-runtime/team-runtime.ts +970 -33
- package/src/gjc-runtime/team-store.ts +32 -0
- package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/gjc-runtime/team-workers.ts +1 -0
- package/src/gjc-runtime/tmux-owner-isolation.ts +18 -0
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +13 -7
- package/src/gjc-runtime/workflow-manifest.generated.json +97 -350
- package/src/gjc-runtime/workflow-manifest.ts +34 -179
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/hooks/skill-state.ts +1 -23
- package/src/internal-urls/docs-index.generated.ts +10 -11
- package/src/internal-urls/local-protocol.ts +23 -4
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/main.ts +9 -5
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +47 -0
- package/src/modes/acp/acp-agent.ts +597 -67
- package/src/modes/acp/acp-event-mapper.ts +106 -12
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +76 -5
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/oauth-selector.ts +42 -12
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/session-observer-overlay.ts +187 -32
- package/src/modes/components/settings-selector.ts +60 -18
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +1 -4
- package/src/modes/components/welcome.ts +18 -3
- package/src/modes/controllers/command-controller.ts +4 -0
- package/src/modes/controllers/event-controller.ts +109 -27
- package/src/modes/controllers/extension-ui-controller.ts +23 -12
- package/src/modes/controllers/input-controller.ts +62 -6
- package/src/modes/controllers/selector-controller.ts +83 -37
- package/src/modes/interactive-mode.ts +127 -29
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/runtime-init.ts +20 -2
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +94 -1
- package/src/prompts/agents/architect.md +9 -1
- package/src/prompts/agents/critic.md +9 -0
- package/src/prompts/agents/executor.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -1
- package/src/prompts/tools/read.md +4 -2
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/manager.ts +26 -6
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/lifecycle.ts +107 -7
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +4 -3
- package/src/sdk/bus/config.ts +1 -1
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/index.ts +503 -60
- package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
- package/src/sdk/bus/prompt-reconciliation.ts +2 -1
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/reconciliation-store.ts +224 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +6 -4
- package/src/sdk/bus/telegram-daemon.ts +531 -53
- package/src/sdk/host/control/dispatch.ts +7 -1
- package/src/sdk/host/control/operations.ts +2 -1
- package/src/sdk/host/host.ts +25 -3
- package/src/sdk/host/query/handlers.ts +55 -0
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/protocol/operation-inventory.generated.json +76 -0
- package/src/sdk/protocol/operation-registry.ts +8 -2
- package/src/sdk/session.ts +25 -2
- package/src/sdk/startup-capability.ts +6 -0
- package/src/session/agent-session.ts +720 -190
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +40 -10
- package/src/session/internal/native-publish-outcome.ts +8 -3
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +1372 -42
- package/src/session/streaming-output.ts +262 -43
- package/src/setup/provider-onboarding.ts +19 -4
- package/src/skill-state/active-state.ts +0 -10
- package/src/skill-state/workflow-hud.ts +25 -2
- package/src/skill-state/workflow-mutation-guard.ts +65 -7
- package/src/task/executor.ts +11 -3
- package/src/task/index.ts +2 -0
- package/src/task/types.ts +22 -11
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/ask.ts +89 -69
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/fetch.ts +114 -23
- package/src/tools/output-meta.ts +176 -9
- package/src/tools/path-utils.ts +5 -1
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1542 -310
- package/src/tools/resource-gc.ts +665 -125
- package/src/tools/tool-result.ts +14 -1
- package/src/web/search/providers/codex.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +4 -1
- package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
- package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
- package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
- package/src/gjc-runtime/deep-interview-draft.ts +0 -843
- package/src/gjc-runtime/deep-interview-payload.ts +0 -262
- package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
readArgsTargetInternalUrl,
|
|
13
13
|
} from "../../modes/components/read-tool-group";
|
|
14
14
|
import { TodoReminderComponent } from "../../modes/components/todo-reminder";
|
|
15
|
-
import { ToolExecutionComponent } from "../../modes/components/tool-execution";
|
|
15
|
+
import { ToolExecutionComponent, type ToolExecutionHandle } from "../../modes/components/tool-execution";
|
|
16
16
|
import { TtsrNotificationComponent } from "../../modes/components/ttsr-notification";
|
|
17
17
|
import { getSymbolTheme, theme } from "../../modes/theme/theme";
|
|
18
18
|
import type { InteractiveModeContext, TodoPhase } from "../../modes/types";
|
|
@@ -23,6 +23,7 @@ import type { AgentSessionEvent } from "../../session/agent-session";
|
|
|
23
23
|
import { type CustomMessage, isSilentAbort, readPendingDisplayTag } from "../../session/messages";
|
|
24
24
|
import { transferSessionMessageIdentity } from "../../session/session-manager";
|
|
25
25
|
import type { ResolveToolDetails } from "../../tools/resolve";
|
|
26
|
+
import { computeIrcSplitWidths, getIrcSidebarSemanticToken } from "../components/irc-sidebar";
|
|
26
27
|
import type { IrcObservationRecord } from "../irc-observation-ledger";
|
|
27
28
|
import { interruptHint } from "../shared";
|
|
28
29
|
import { buildAbortDisplayMessage } from "../utils/abort-message";
|
|
@@ -36,7 +37,14 @@ type AgentSessionEventKind = AgentSessionEvent["type"];
|
|
|
36
37
|
|
|
37
38
|
/** Test-only performance counters for advisory baseline tests. */
|
|
38
39
|
export const __eventControllerPerfCounters = {
|
|
40
|
+
enabled: false,
|
|
39
41
|
messageUpdateContentVisits: 0,
|
|
42
|
+
enable(): void {
|
|
43
|
+
this.enabled = true;
|
|
44
|
+
},
|
|
45
|
+
disable(): void {
|
|
46
|
+
this.enabled = false;
|
|
47
|
+
},
|
|
40
48
|
reset(): void {
|
|
41
49
|
this.messageUpdateContentVisits = 0;
|
|
42
50
|
},
|
|
@@ -118,6 +126,9 @@ export class EventController {
|
|
|
118
126
|
#toolIntentCache = new Map<string, { args: unknown; intent: string | undefined }>();
|
|
119
127
|
#thinkingContentIndices = new Set<number>();
|
|
120
128
|
#handlers: AgentSessionEventHandlers;
|
|
129
|
+
#visibleTranscriptChanged = false;
|
|
130
|
+
#handlingEvent = false;
|
|
131
|
+
#eventQueue: Promise<void> = Promise.resolve();
|
|
121
132
|
|
|
122
133
|
constructor(private ctx: InteractiveModeContext) {
|
|
123
134
|
this.#handlers = {
|
|
@@ -162,6 +173,26 @@ export class EventController {
|
|
|
162
173
|
this.clearIrcExpiryTimers();
|
|
163
174
|
}
|
|
164
175
|
|
|
176
|
+
#recordVisibleTranscriptMutation(): void {
|
|
177
|
+
this.#visibleTranscriptChanged = true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#observeVisibleTranscriptMutation(): void {
|
|
181
|
+
if (this.#handlingEvent) {
|
|
182
|
+
this.#recordVisibleTranscriptMutation();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.ctx.recordVisibleTranscriptMutation?.();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#consumeToolVisibleChange(handle: ToolExecutionHandle): void {
|
|
189
|
+
// Structural third-party renderers may not implement the optional exact-consume
|
|
190
|
+
// capability; preserve revision correctness conservatively until they opt in.
|
|
191
|
+
if (typeof handle.consumeVisibleTranscriptChange !== "function" || handle.consumeVisibleTranscriptChange()) {
|
|
192
|
+
this.#recordVisibleTranscriptMutation();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
165
196
|
#resetReadGroup(): void {
|
|
166
197
|
this.#lastReadGroup = undefined;
|
|
167
198
|
}
|
|
@@ -228,17 +259,26 @@ export class EventController {
|
|
|
228
259
|
});
|
|
229
260
|
}
|
|
230
261
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.ctx.statusLine.invalidate();
|
|
237
|
-
this.ctx.updateEditorTopBorder();
|
|
262
|
+
handleEvent(event: AgentSessionEvent): Promise<void> {
|
|
263
|
+
const dispatch = this.#eventQueue.then(() => this.#dispatchEvent(event));
|
|
264
|
+
this.#eventQueue = dispatch.catch(() => {});
|
|
265
|
+
return dispatch;
|
|
266
|
+
}
|
|
238
267
|
|
|
239
|
-
|
|
240
|
-
await
|
|
241
|
-
|
|
268
|
+
async #dispatchEvent(event: AgentSessionEvent): Promise<void> {
|
|
269
|
+
if (!this.ctx.isInitialized) await this.ctx.init();
|
|
270
|
+
this.#visibleTranscriptChanged = false;
|
|
271
|
+
this.#handlingEvent = true;
|
|
272
|
+
try {
|
|
273
|
+
this.ctx.statusLine.invalidate();
|
|
274
|
+
this.ctx.updateEditorTopBorder();
|
|
275
|
+
const run = this.#handlers[event.type] as (e: AgentSessionEvent) => Promise<void>;
|
|
276
|
+
await run(event);
|
|
277
|
+
if (this.#visibleTranscriptChanged) this.ctx.recordVisibleTranscriptMutation?.();
|
|
278
|
+
if (this.ctx.isTranscriptViewerOpen?.()) this.ctx.refreshTranscriptViewer?.();
|
|
279
|
+
} finally {
|
|
280
|
+
this.#handlingEvent = false;
|
|
281
|
+
}
|
|
242
282
|
}
|
|
243
283
|
|
|
244
284
|
async #handleAgentStart(_event: Extract<AgentSessionEvent, { type: "agent_start" }>): Promise<void> {
|
|
@@ -268,8 +308,12 @@ export class EventController {
|
|
|
268
308
|
const parsed = parseIrcMessage(message);
|
|
269
309
|
if (!parsed) return;
|
|
270
310
|
const arrival = this.ctx.captureIrcArrivalSnapshot();
|
|
311
|
+
const rightWidth = arrival.panelVisible
|
|
312
|
+
? computeIrcSplitWidths(this.ctx.ui.terminal?.columns ?? 0).rightWidth
|
|
313
|
+
: 0;
|
|
314
|
+
const beforeToken = rightWidth > 0 ? getIrcSidebarSemanticToken(this.ctx.ircLedger, rightWidth) : "";
|
|
271
315
|
const record = this.ctx.ircLedger.observe(parsed, arrival.panelVisible);
|
|
272
|
-
this.#
|
|
316
|
+
const evictedInlineRemoved = this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds());
|
|
273
317
|
if (!record) return;
|
|
274
318
|
const signature = `irc:${record.observationId}`;
|
|
275
319
|
if (this.#renderedCustomMessages.has(signature)) return;
|
|
@@ -279,9 +323,13 @@ export class EventController {
|
|
|
279
323
|
this.#renderedIrcComponents.set(record.observationId, components);
|
|
280
324
|
this.#scheduleIrcExpiry(record, components);
|
|
281
325
|
this.ctx.ui.requestRender();
|
|
326
|
+
const afterToken = rightWidth > 0 ? getIrcSidebarSemanticToken(this.ctx.ircLedger, rightWidth) : "";
|
|
327
|
+
if (components.length > 0 || evictedInlineRemoved || (rightWidth > 0 && beforeToken !== afterToken)) {
|
|
328
|
+
this.#recordVisibleTranscriptMutation();
|
|
329
|
+
}
|
|
282
330
|
}
|
|
283
331
|
|
|
284
|
-
#cleanupIrcObservationIds(observationIds: readonly string[]):
|
|
332
|
+
#cleanupIrcObservationIds(observationIds: readonly string[]): boolean {
|
|
285
333
|
const removedComponents = new Set<Component>();
|
|
286
334
|
for (const observationId of observationIds) {
|
|
287
335
|
const timer = this.#ircExpiryTimers.get(observationId);
|
|
@@ -294,23 +342,26 @@ export class EventController {
|
|
|
294
342
|
for (const component of this.ctx.removeRenderedIrcInlineComponents(observationId) ?? []) {
|
|
295
343
|
removedComponents.add(component);
|
|
296
344
|
}
|
|
297
|
-
|
|
298
345
|
this.#renderedCustomMessages.delete(`irc:${observationId}`);
|
|
299
346
|
}
|
|
300
347
|
for (const component of removedComponents) this.ctx.chatContainer.removeChild(component);
|
|
348
|
+
return removedComponents.size > 0;
|
|
301
349
|
}
|
|
302
350
|
|
|
303
351
|
#cleanupEvictedIrcObservations(): void {
|
|
304
|
-
this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds())
|
|
352
|
+
if (this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds())) {
|
|
353
|
+
this.#recordVisibleTranscriptMutation();
|
|
354
|
+
}
|
|
305
355
|
}
|
|
306
356
|
|
|
307
|
-
#cleanupExpiredIrcInlineComponents(observationId: string):
|
|
357
|
+
#cleanupExpiredIrcInlineComponents(observationId: string): boolean {
|
|
308
358
|
const removedComponents = new Set<Component>(this.#renderedIrcComponents.get(observationId));
|
|
309
359
|
this.#renderedIrcComponents.delete(observationId);
|
|
310
360
|
for (const component of this.ctx.removeRenderedIrcInlineComponents(observationId) ?? []) {
|
|
311
361
|
removedComponents.add(component);
|
|
312
362
|
}
|
|
313
363
|
for (const component of removedComponents) this.ctx.chatContainer.removeChild(component);
|
|
364
|
+
return removedComponents.size > 0;
|
|
314
365
|
}
|
|
315
366
|
|
|
316
367
|
async #handleMessageStart(event: Extract<AgentSessionEvent, { type: "message_start" }>): Promise<void> {
|
|
@@ -326,6 +377,7 @@ export class EventController {
|
|
|
326
377
|
this.#renderedCustomMessages.add(signature);
|
|
327
378
|
this.#resetReadGroup();
|
|
328
379
|
this.ctx.addMessageToChat(event.message);
|
|
380
|
+
if (event.message.display) this.#recordVisibleTranscriptMutation();
|
|
329
381
|
// Tag-keyed pending-bar refresh: when AgentSession.#handleAgentEvent
|
|
330
382
|
// spliced this dequeued custom message out of #steeringMessages /
|
|
331
383
|
// #followUpMessages (it ran before this emit), the array state is
|
|
@@ -373,10 +425,12 @@ export class EventController {
|
|
|
373
425
|
this.ctx.updatePendingMessagesDisplay();
|
|
374
426
|
}
|
|
375
427
|
this.ctx.ui.requestRender();
|
|
428
|
+
if (!wasOptimistic) this.#recordVisibleTranscriptMutation();
|
|
376
429
|
} else if (event.message.role === "fileMention") {
|
|
377
430
|
this.#resetReadGroup();
|
|
378
431
|
this.ctx.addMessageToChat(event.message);
|
|
379
432
|
this.ctx.ui.requestRender();
|
|
433
|
+
this.#recordVisibleTranscriptMutation();
|
|
380
434
|
} else if (event.message.role === "assistant") {
|
|
381
435
|
this.#lastThinkingCount = 0;
|
|
382
436
|
this.#resetReadGroup();
|
|
@@ -387,6 +441,7 @@ export class EventController {
|
|
|
387
441
|
this.ctx.hideThinkingBlock,
|
|
388
442
|
() => this.ctx.ui.requestRender(),
|
|
389
443
|
this.ctx.getAssistantViewportAnchorId?.(event.message),
|
|
444
|
+
() => this.#observeVisibleTranscriptMutation(),
|
|
390
445
|
);
|
|
391
446
|
this.ctx.streamingMessage = event.message;
|
|
392
447
|
addChatChild(this.ctx, this.ctx.streamingComponent);
|
|
@@ -429,15 +484,10 @@ export class EventController {
|
|
|
429
484
|
this.#cleanupEvictedIrcObservations();
|
|
430
485
|
const projectedObservationIds = new Set(inlineProjection.map(record => record.observationId));
|
|
431
486
|
for (const [observationId, components] of componentsByObservationId) {
|
|
432
|
-
|
|
433
|
-
if (
|
|
434
|
-
!projectedObservationIds.has(observationId) ||
|
|
435
|
-
(record?.mode === "ephemeral" && record.expiresAt! - now <= 0)
|
|
436
|
-
) {
|
|
487
|
+
if (!projectedObservationIds.has(observationId)) {
|
|
437
488
|
for (const component of components) {
|
|
438
489
|
this.ctx.chatContainer.removeChild(component);
|
|
439
490
|
}
|
|
440
|
-
this.#renderedIrcComponents.delete(observationId);
|
|
441
491
|
componentsByObservationId.delete(observationId);
|
|
442
492
|
}
|
|
443
493
|
}
|
|
@@ -468,12 +518,12 @@ export class EventController {
|
|
|
468
518
|
}
|
|
469
519
|
const remainingMs = record.expiresAt! - Date.now();
|
|
470
520
|
if (remainingMs <= 0) {
|
|
471
|
-
this.#cleanupExpiredIrcInlineComponents(record.observationId);
|
|
521
|
+
if (this.#cleanupExpiredIrcInlineComponents(record.observationId)) this.#observeVisibleTranscriptMutation();
|
|
472
522
|
return false;
|
|
473
523
|
}
|
|
474
524
|
const timer = setTimeout(() => {
|
|
475
525
|
this.#ircExpiryTimers.delete(record.observationId);
|
|
476
|
-
this.#cleanupExpiredIrcInlineComponents(record.observationId);
|
|
526
|
+
if (this.#cleanupExpiredIrcInlineComponents(record.observationId)) this.#observeVisibleTranscriptMutation();
|
|
477
527
|
this.ctx.ui.requestRender();
|
|
478
528
|
}, remainingMs);
|
|
479
529
|
timer.unref?.();
|
|
@@ -496,6 +546,7 @@ export class EventController {
|
|
|
496
546
|
this.#resetReadGroup();
|
|
497
547
|
this.ctx.addMessageToChat(event.message);
|
|
498
548
|
this.ctx.ui.requestRender();
|
|
549
|
+
this.#recordVisibleTranscriptMutation();
|
|
499
550
|
}
|
|
500
551
|
|
|
501
552
|
async #handleModelFallbackSwitched(
|
|
@@ -549,19 +600,24 @@ export class EventController {
|
|
|
549
600
|
}
|
|
550
601
|
|
|
551
602
|
for (const content of contentsToProcess) {
|
|
552
|
-
__eventControllerPerfCounters.messageUpdateContentVisits += 1;
|
|
603
|
+
if (__eventControllerPerfCounters.enabled) __eventControllerPerfCounters.messageUpdateContentVisits += 1;
|
|
553
604
|
if (content.type !== "toolCall") continue;
|
|
554
605
|
if (content.name === "read") {
|
|
555
606
|
if (!readArgsHaveTarget(content.arguments)) continue;
|
|
556
607
|
if (!readArgsTargetInternalUrl(content.arguments)) {
|
|
557
608
|
this.#trackReadToolCall(content.id, content.arguments);
|
|
558
609
|
const component = this.ctx.pendingTools.get(content.id);
|
|
559
|
-
if (component)
|
|
560
|
-
|
|
610
|
+
if (component) {
|
|
611
|
+
component.updateArgs(content.arguments, content.id);
|
|
612
|
+
this.#consumeToolVisibleChange(component);
|
|
613
|
+
} else {
|
|
561
614
|
const group = this.#getReadGroup();
|
|
562
615
|
group.updateArgs(content.arguments, content.id);
|
|
563
616
|
this.ctx.pendingTools.set(content.id, group);
|
|
617
|
+
this.#recordVisibleTranscriptMutation();
|
|
618
|
+
group.consumeVisibleTranscriptChange();
|
|
564
619
|
}
|
|
620
|
+
|
|
565
621
|
continue;
|
|
566
622
|
}
|
|
567
623
|
}
|
|
@@ -582,6 +638,7 @@ export class EventController {
|
|
|
582
638
|
editFuzzyThreshold: settings.get("edit.fuzzyThreshold"),
|
|
583
639
|
editAllowFuzzy: settings.get("edit.fuzzyMatch"),
|
|
584
640
|
hashlineAutoDropPureInsertDuplicates: settings.get("edit.hashlineAutoDropPureInsertDuplicates"),
|
|
641
|
+
onVisibleTranscriptMutation: () => this.#observeVisibleTranscriptMutation(),
|
|
585
642
|
},
|
|
586
643
|
tool,
|
|
587
644
|
this.ctx.ui,
|
|
@@ -591,8 +648,10 @@ export class EventController {
|
|
|
591
648
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
592
649
|
this.ctx.pendingTools.set(content.id, component);
|
|
593
650
|
addChatChild(this.ctx, component);
|
|
651
|
+
this.#recordVisibleTranscriptMutation();
|
|
594
652
|
} else {
|
|
595
653
|
this.ctx.pendingTools.get(content.id)?.updateArgs(renderArgs, content.id);
|
|
654
|
+
this.#consumeToolVisibleChange(this.ctx.pendingTools.get(content.id)!);
|
|
596
655
|
}
|
|
597
656
|
|
|
598
657
|
const args = content.arguments;
|
|
@@ -659,6 +718,7 @@ export class EventController {
|
|
|
659
718
|
if (this.ctx.streamingMessage.stopReason !== "aborted" && this.ctx.streamingMessage.stopReason !== "error") {
|
|
660
719
|
for (const [toolCallId, component] of this.ctx.pendingTools.entries()) {
|
|
661
720
|
component.setArgsComplete(toolCallId);
|
|
721
|
+
this.#consumeToolVisibleChange(component);
|
|
662
722
|
}
|
|
663
723
|
}
|
|
664
724
|
this.#lastAssistantComponent = this.ctx.streamingComponent;
|
|
@@ -685,6 +745,8 @@ export class EventController {
|
|
|
685
745
|
this.ctx.pendingTools.set(event.toolCallId, group);
|
|
686
746
|
}
|
|
687
747
|
this.ctx.ui.requestRender();
|
|
748
|
+
this.#consumeToolVisibleChange(this.ctx.pendingTools.get(event.toolCallId)!);
|
|
749
|
+
|
|
688
750
|
return;
|
|
689
751
|
}
|
|
690
752
|
|
|
@@ -698,6 +760,7 @@ export class EventController {
|
|
|
698
760
|
editFuzzyThreshold: settings.get("edit.fuzzyThreshold"),
|
|
699
761
|
editAllowFuzzy: settings.get("edit.fuzzyMatch"),
|
|
700
762
|
hashlineAutoDropPureInsertDuplicates: settings.get("edit.hashlineAutoDropPureInsertDuplicates"),
|
|
763
|
+
onVisibleTranscriptMutation: () => this.#observeVisibleTranscriptMutation(),
|
|
701
764
|
},
|
|
702
765
|
tool,
|
|
703
766
|
this.ctx.ui,
|
|
@@ -707,6 +770,8 @@ export class EventController {
|
|
|
707
770
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
708
771
|
this.ctx.pendingTools.set(event.toolCallId, component);
|
|
709
772
|
addChatChild(this.ctx, component);
|
|
773
|
+
this.#recordVisibleTranscriptMutation();
|
|
774
|
+
|
|
710
775
|
this.ctx.ui.requestRender();
|
|
711
776
|
}
|
|
712
777
|
}
|
|
@@ -723,6 +788,8 @@ export class EventController {
|
|
|
723
788
|
!isFinalAsyncState,
|
|
724
789
|
event.toolCallId,
|
|
725
790
|
);
|
|
791
|
+
this.#consumeToolVisibleChange(component);
|
|
792
|
+
|
|
726
793
|
if (isFinalAsyncState) {
|
|
727
794
|
this.ctx.pendingTools.delete(event.toolCallId);
|
|
728
795
|
this.#backgroundToolCallIds.delete(event.toolCallId);
|
|
@@ -737,6 +804,8 @@ export class EventController {
|
|
|
737
804
|
const component = this.ctx.pendingTools.get(event.toolCallId);
|
|
738
805
|
if (component) {
|
|
739
806
|
component.updateResult({ ...event.result, isError: event.isError }, false, event.toolCallId);
|
|
807
|
+
this.#consumeToolVisibleChange(component);
|
|
808
|
+
|
|
740
809
|
this.ctx.pendingTools.delete(event.toolCallId);
|
|
741
810
|
}
|
|
742
811
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
@@ -761,6 +830,8 @@ export class EventController {
|
|
|
761
830
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
762
831
|
const isBackgroundRunning = asyncState === "running";
|
|
763
832
|
component.updateResult({ ...event.result, isError: event.isError }, isBackgroundRunning, event.toolCallId);
|
|
833
|
+
this.#consumeToolVisibleChange(component);
|
|
834
|
+
|
|
764
835
|
if (isBackgroundRunning) {
|
|
765
836
|
this.#backgroundToolCallIds.add(event.toolCallId);
|
|
766
837
|
} else {
|
|
@@ -776,6 +847,8 @@ export class EventController {
|
|
|
776
847
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
777
848
|
const isBackgroundRunning = asyncState === "running";
|
|
778
849
|
component.updateResult({ ...event.result, isError: event.isError }, isBackgroundRunning, event.toolCallId);
|
|
850
|
+
this.#consumeToolVisibleChange(component);
|
|
851
|
+
|
|
779
852
|
if (isBackgroundRunning) {
|
|
780
853
|
this.#backgroundToolCallIds.add(event.toolCallId);
|
|
781
854
|
} else {
|
|
@@ -893,6 +966,12 @@ export class EventController {
|
|
|
893
966
|
} else if (event.willRetry && !isHandoffAction) {
|
|
894
967
|
this.ctx.showStatus("Context overflow maintenance completed");
|
|
895
968
|
}
|
|
969
|
+
} else if (
|
|
970
|
+
event.skipped &&
|
|
971
|
+
event.errorMessage?.startsWith("Context overflow recovery skipped: nothing eligible to compact.") &&
|
|
972
|
+
!isHandoffAction
|
|
973
|
+
) {
|
|
974
|
+
this.ctx.showStatus(event.errorMessage);
|
|
896
975
|
} else if (event.errorMessage) {
|
|
897
976
|
this.ctx.showWarning(event.errorMessage);
|
|
898
977
|
} else if (isHandoffAction) {
|
|
@@ -999,12 +1078,15 @@ export class EventController {
|
|
|
999
1078
|
const component = new TtsrNotificationComponent(event.rules);
|
|
1000
1079
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
1001
1080
|
addChatChild(this.ctx, component);
|
|
1081
|
+
this.#recordVisibleTranscriptMutation();
|
|
1082
|
+
|
|
1002
1083
|
this.ctx.ui.requestRender();
|
|
1003
1084
|
}
|
|
1004
1085
|
|
|
1005
1086
|
async #handleTodoReminder(event: Extract<AgentSessionEvent, { type: "todo_reminder" }>): Promise<void> {
|
|
1006
1087
|
const component = new TodoReminderComponent(event.todos, event.attempt, event.maxAttempts);
|
|
1007
1088
|
addChatChild(this.ctx, component);
|
|
1089
|
+
this.#recordVisibleTranscriptMutation();
|
|
1008
1090
|
this.ctx.ui.requestRender();
|
|
1009
1091
|
}
|
|
1010
1092
|
|
|
@@ -281,7 +281,24 @@ export class ExtensionUiController {
|
|
|
281
281
|
const disabled = [...(session.settings.get("disabledExtensions") ?? [])];
|
|
282
282
|
const on = input.on === true;
|
|
283
283
|
const next = on ? disabled.filter(value => value !== id) : [...new Set([...disabled, id])];
|
|
284
|
-
session.settings.
|
|
284
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
285
|
+
throw Object.assign(
|
|
286
|
+
new Error(
|
|
287
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
288
|
+
),
|
|
289
|
+
{ code: "invalid_request" },
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
session.settings.set("disabledExtensions", next);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
296
|
+
throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), {
|
|
297
|
+
code: "invalid_request",
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
285
302
|
return { changed: true, enabled: on };
|
|
286
303
|
}
|
|
287
304
|
case "session.delete":
|
|
@@ -425,6 +442,7 @@ export class ExtensionUiController {
|
|
|
425
442
|
getSystemPrompt: () => this.ctx.session.systemPrompt,
|
|
426
443
|
clearContext: () => this.ctx.session.clearContext(),
|
|
427
444
|
cycleModel: () => this.ctx.session.cycleModel(),
|
|
445
|
+
setModelProfile: name => this.ctx.session.activateModelProfileForControl(name),
|
|
428
446
|
cycleThinkingLevel: () => this.ctx.session.cycleThinkingLevel(),
|
|
429
447
|
setQueueMode: (kind, mode) => {
|
|
430
448
|
if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
|
|
@@ -441,16 +459,12 @@ export class ExtensionUiController {
|
|
|
441
459
|
}
|
|
442
460
|
return false;
|
|
443
461
|
},
|
|
444
|
-
invokeSkill: (name, args) => this.ctx.session.invokeSkill(name, args),
|
|
462
|
+
invokeSkill: (name, args, options) => this.ctx.session.invokeSkill(name, args, options),
|
|
445
463
|
setPlanMode: on => this.ctx.session.setSdkPlanMode(on),
|
|
446
464
|
operateGoal: (op, objective) => this.ctx.session.operateGoal(op, objective),
|
|
447
465
|
getSkillState: () =>
|
|
448
466
|
this.ctx.session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
449
|
-
getConfigItems: () => (
|
|
450
|
-
steeringMode: this.ctx.session.steeringMode,
|
|
451
|
-
followUpMode: this.ctx.session.followUpMode,
|
|
452
|
-
interruptMode: this.ctx.session.interruptMode,
|
|
453
|
-
}),
|
|
467
|
+
getConfigItems: () => this.ctx.session.getSdkConfigItems(),
|
|
454
468
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
455
469
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
456
470
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
@@ -727,6 +741,7 @@ export class ExtensionUiController {
|
|
|
727
741
|
getSystemPrompt: () => this.ctx.session.systemPrompt,
|
|
728
742
|
clearContext: () => this.ctx.session.clearContext(),
|
|
729
743
|
cycleModel: () => this.ctx.session.cycleModel(),
|
|
744
|
+
setModelProfile: name => this.ctx.session.activateModelProfileForControl(name),
|
|
730
745
|
cycleThinkingLevel: () => this.ctx.session.cycleThinkingLevel(),
|
|
731
746
|
setQueueMode: (kind, mode) => {
|
|
732
747
|
if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
|
|
@@ -745,11 +760,7 @@ export class ExtensionUiController {
|
|
|
745
760
|
},
|
|
746
761
|
getSkillState: () =>
|
|
747
762
|
this.ctx.session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
748
|
-
getConfigItems: () => (
|
|
749
|
-
steeringMode: this.ctx.session.steeringMode,
|
|
750
|
-
followUpMode: this.ctx.session.followUpMode,
|
|
751
|
-
interruptMode: this.ctx.session.interruptMode,
|
|
752
|
-
}),
|
|
763
|
+
getConfigItems: () => this.ctx.session.getSdkConfigItems(),
|
|
753
764
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
754
765
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
755
766
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
@@ -33,6 +33,13 @@ import type { PasteTextContext } from "../components/custom-editor";
|
|
|
33
33
|
import { QueuePaneComponent } from "../components/queue-pane";
|
|
34
34
|
import { type QueuedMessageMoveDirection, QueuedMessageSelectorComponent } from "../components/queued-message-selector";
|
|
35
35
|
|
|
36
|
+
const QUEUE_SELECTOR_NAVIGATION_ACTIONS = [
|
|
37
|
+
"tui.select.up",
|
|
38
|
+
"tui.select.down",
|
|
39
|
+
"tui.select.pageUp",
|
|
40
|
+
"tui.select.pageDown",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
36
43
|
interface Expandable {
|
|
37
44
|
setExpanded(expanded: boolean): void;
|
|
38
45
|
setManuallyExpanded?(expanded: boolean): void;
|
|
@@ -151,15 +158,24 @@ export class InputController {
|
|
|
151
158
|
case "app.editor.external":
|
|
152
159
|
return Boolean(getEditorCommand());
|
|
153
160
|
case "app.message.followUp":
|
|
154
|
-
case "app.message.queue":
|
|
155
161
|
return (
|
|
156
162
|
this.ctx.session.isStreaming ||
|
|
157
163
|
this.ctx.session.isCompacting ||
|
|
158
164
|
this.ctx.session.isBashRunning ||
|
|
159
165
|
this.ctx.session.isEvalRunning
|
|
160
166
|
);
|
|
167
|
+
case "app.message.queue":
|
|
168
|
+
return (
|
|
169
|
+
this.ctx.editor.getText().trim().length > 0 &&
|
|
170
|
+
(this.ctx.session.isStreaming ||
|
|
171
|
+
this.ctx.session.isCompacting ||
|
|
172
|
+
this.ctx.session.isBashRunning ||
|
|
173
|
+
this.ctx.session.isEvalRunning)
|
|
174
|
+
);
|
|
161
175
|
case "app.message.dequeue":
|
|
162
|
-
return
|
|
176
|
+
return (
|
|
177
|
+
this.ctx.session.getQueuedMessageEntries().length > 0 || this.ctx.compactionQueuedMessages.length > 0
|
|
178
|
+
);
|
|
163
179
|
case "app.clipboard.copyPrompt":
|
|
164
180
|
return this.ctx.editor.getText().length > 0;
|
|
165
181
|
case "app.session.tree":
|
|
@@ -1037,6 +1053,21 @@ export class InputController {
|
|
|
1037
1053
|
};
|
|
1038
1054
|
const pane = new QueuePaneComponent(entries, {
|
|
1039
1055
|
selectedIndex,
|
|
1056
|
+
formatKeyHint: key => this.ctx.keybindings.formatKeyHint(key),
|
|
1057
|
+
formatSelectAction: action => this.ctx.keybindings.getDisplayString(action),
|
|
1058
|
+
matchesSelectAction: (keyData, action) =>
|
|
1059
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1060
|
+
resolveSelectNavigation: keyData =>
|
|
1061
|
+
QUEUE_SELECTOR_NAVIGATION_ACTIONS.find(action =>
|
|
1062
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1063
|
+
),
|
|
1064
|
+
onSelect: entry => {
|
|
1065
|
+
const restored = this.#restoreQueuedMessageToEditor(entry);
|
|
1066
|
+
close();
|
|
1067
|
+
this.ctx.showStatus(
|
|
1068
|
+
restored === 0 ? "Queued message is no longer available" : "Restored queued message to editor",
|
|
1069
|
+
);
|
|
1070
|
+
},
|
|
1040
1071
|
onDelete: (entry, index) => {
|
|
1041
1072
|
const deleted = this.ctx.session.removeQueuedMessageForEditing(entry.id) !== undefined;
|
|
1042
1073
|
const remaining = this.ctx.session.getQueuedMessageEntries();
|
|
@@ -1209,7 +1240,17 @@ export class InputController {
|
|
|
1209
1240
|
this.#restoreEditorFocus();
|
|
1210
1241
|
this.ctx.ui.requestRender();
|
|
1211
1242
|
},
|
|
1212
|
-
{
|
|
1243
|
+
{
|
|
1244
|
+
selectedIndex,
|
|
1245
|
+
formatKeyHint: key => this.ctx.keybindings.formatKeyHint(key),
|
|
1246
|
+
formatSelectAction: action => this.ctx.keybindings.getDisplayString(action),
|
|
1247
|
+
matchesSelectAction: (keyData, action) =>
|
|
1248
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1249
|
+
resolveSelectNavigation: keyData =>
|
|
1250
|
+
QUEUE_SELECTOR_NAVIGATION_ACTIONS.find(action =>
|
|
1251
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1252
|
+
),
|
|
1253
|
+
},
|
|
1213
1254
|
);
|
|
1214
1255
|
this.ctx.editorContainer.clear();
|
|
1215
1256
|
this.ctx.editorContainer.addChild(selector);
|
|
@@ -2003,9 +2044,24 @@ export class InputController {
|
|
|
2003
2044
|
}
|
|
2004
2045
|
|
|
2005
2046
|
toggleThinkingBlockVisibility(): void {
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2047
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2048
|
+
this.ctx.showError(
|
|
2049
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
2050
|
+
);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
const hideThinkingBlock = !this.ctx.hideThinkingBlock;
|
|
2054
|
+
try {
|
|
2055
|
+
settings.set("hideThinkingBlock", hideThinkingBlock);
|
|
2056
|
+
} catch (error) {
|
|
2057
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2058
|
+
this.ctx.showError(error instanceof Error ? error.message : String(error));
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
throw error;
|
|
2062
|
+
}
|
|
2063
|
+
this.ctx.hideThinkingBlock = hideThinkingBlock;
|
|
2064
|
+
this.ctx.session.setThinkingVisibility(hideThinkingBlock ? "hidden" : "visible");
|
|
2009
2065
|
|
|
2010
2066
|
// Rebuild chat from session messages
|
|
2011
2067
|
// Detach the live streaming component before the disposing clear() so the
|