@gajae-code/coding-agent 0.11.11 → 0.12.1
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 +131 -4
- package/dist/types/async/job-manager.d.ts +17 -3
- package/dist/types/cli/read-cli.d.ts +1 -0
- 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-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 +83 -1
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/exa/mcp-client.d.ts +10 -1
- package/dist/types/exec/bash-executor.d.ts +45 -12
- package/dist/types/extensibility/extensions/types.d.ts +38 -4
- package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
- package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
- package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
- package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
- package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
- package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
- package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
- 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/launch-tmux.d.ts +1 -0
- package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +70 -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 +27 -1
- package/dist/types/gjc-runtime/team-store.d.ts +12 -0
- package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +17 -0
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +31 -80
- 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 +10 -19
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/session-observer-overlay.d.ts +22 -0
- package/dist/types/modes/components/settings-selector.d.ts +11 -0
- package/dist/types/modes/components/status-line/gh.d.ts +5 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- 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/reminders/star-reminder.d.ts +3 -13
- package/dist/types/runtime-mcp/manager.d.ts +1 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/adapter.d.ts +3 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +5 -0
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -1
- package/dist/types/sdk/bus/config.d.ts +6 -2
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/index.d.ts +44 -1
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +44 -0
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
- package/dist/types/sdk/bus/reconciliation-store.d.ts +69 -0
- package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
- package/dist/types/sdk/bus/rich-render.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
- package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +11 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
- package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
- package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
- package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
- package/dist/types/sdk/host/control/operations.d.ts +1 -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/host/query/revision-store.d.ts +2 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/prompt-status.d.ts +23 -3
- package/dist/types/sdk/session.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +82 -12
- package/dist/types/session/artifacts.d.ts +8 -0
- package/dist/types/session/blob-store.d.ts +57 -4
- package/dist/types/session/internal/managed-session-storage.d.ts +8 -1
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +48 -19
- package/dist/types/session/session-storage.d.ts +4 -0
- package/dist/types/session/streaming-output.d.ts +96 -12
- package/dist/types/setup/credential-import.d.ts +12 -0
- package/dist/types/skill-state/active-state.d.ts +12 -4
- package/dist/types/skill-state/workflow-hud.d.ts +9 -0
- package/dist/types/task/executor.d.ts +3 -2
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/provider-retry-status.d.ts +8 -0
- package/dist/types/task/receipt.d.ts +7 -1
- package/dist/types/task/types.d.ts +23 -0
- package/dist/types/tools/ask-answer-registry.d.ts +2 -2
- package/dist/types/tools/bash-interactive.d.ts +4 -1
- package/dist/types/tools/bash.d.ts +3 -1
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +17 -1
- package/dist/types/tools/image-gen.d.ts +4 -0
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/output-meta.d.ts +44 -3
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -7
- package/dist/types/tools/resource-gc.d.ts +4 -0
- package/dist/types/tools/review.d.ts +5 -7
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/dist/types/utils/gh.d.ts +13 -0
- package/dist/types/utils/image-resize.d.ts +1 -0
- package/dist/types/web/search/providers/kimi.d.ts +2 -0
- package/dist/types/web/search/providers/searxng.d.ts +7 -0
- package/dist/types/web/search/providers/xai.d.ts +2 -0
- package/package.json +11 -13
- package/scripts/acp-conformance-agent.ts +218 -0
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-gjc-bundle-settings.ts +306 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/generate-sdk-operation-inventory.ts +5 -0
- package/scripts/resident-memory-bench.ts +1341 -0
- package/scripts/run-acp-conformance.ts +285 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/async/job-manager.ts +78 -20
- package/src/capability/index.ts +8 -0
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/plugin-cli.ts +176 -18
- package/src/cli/read-cli.ts +2 -1
- package/src/cli.ts +1 -0
- 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/team.ts +20 -2
- package/src/config/file-lock.ts +11 -2
- 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 +74 -1
- package/src/config/settings.ts +246 -108
- package/src/coordinator-mcp/question-gate-codec.ts +1 -1
- package/src/coordinator-mcp/server.ts +5 -12
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +230 -82
- package/src/defaults/gjc/skills/ralplan/SKILL.md +77 -41
- package/src/defaults/gjc/skills/team/SKILL.md +3 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +62 -39
- package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
- package/src/defaults/gjc-defaults.ts +4 -4
- package/src/eval/py/executor.ts +7 -2
- package/src/exa/mcp-client.ts +12 -3
- package/src/exec/bash-executor.ts +144 -27
- package/src/extensibility/extensions/runner.ts +15 -0
- package/src/extensibility/extensions/types.ts +46 -5
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
- package/src/extensibility/gjc-plugins/index.ts +19 -2
- package/src/extensibility/gjc-plugins/installer.ts +189 -50
- package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
- package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
- package/src/extensibility/gjc-plugins/observability.ts +3 -3
- package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
- package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
- package/src/extensibility/gjc-plugins/schema.ts +84 -12
- package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
- package/src/extensibility/gjc-plugins/types.ts +141 -0
- package/src/extensibility/gjc-plugins/validation.ts +9 -0
- package/src/extensibility/shared-events.ts +5 -0
- package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -82
- 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 -943
- package/src/gjc-runtime/gc-render.ts +1 -0
- package/src/gjc-runtime/gc-runtime.ts +11 -1
- package/src/gjc-runtime/launch-tmux.ts +25 -6
- package/src/gjc-runtime/managed-owner-admission.ts +1 -1
- package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/gjc-runtime/ralplan-runtime.ts +1149 -98
- package/src/gjc-runtime/state-runtime.ts +2 -1
- package/src/gjc-runtime/state-writer.ts +70 -222
- package/src/gjc-runtime/team-launch.ts +42 -5
- package/src/gjc-runtime/team-runtime.ts +1085 -40
- package/src/gjc-runtime/team-store.ts +32 -0
- package/src/gjc-runtime/team-worker-heartbeat.ts +149 -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 +28 -0
- package/src/gjc-runtime/tmux-sessions.ts +58 -13
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +414 -618
- package/src/gjc-runtime/workflow-manifest.generated.json +105 -449
- package/src/gjc-runtime/workflow-manifest.ts +38 -247
- 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 +21 -22
- 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 +98 -0
- package/src/modes/acp/acp-agent.ts +339 -191
- package/src/modes/acp/acp-event-mapper.ts +14 -7
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/gjc-bundle-settings.ts +508 -0
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +61 -4
- package/src/modes/components/notifications-settings-editor.ts +12 -1
- package/src/modes/components/oauth-selector.ts +96 -28
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/session-observer-overlay.ts +457 -83
- package/src/modes/components/settings-selector.ts +116 -23
- package/src/modes/components/status-line/gh.ts +16 -0
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +3 -14
- package/src/modes/components/transcript-viewer-overlay.ts +99 -24
- 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 +26 -2
- package/src/modes/controllers/input-controller.ts +18 -3
- package/src/modes/controllers/selector-controller.ts +127 -36
- package/src/modes/interactive-mode.ts +62 -3
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/runtime-init.ts +22 -2
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +94 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
- package/src/prompts/agents/architect.md +9 -1
- package/src/prompts/agents/critic.md +9 -0
- package/src/prompts/system/eager-todo.md +8 -4
- package/src/prompts/system/system-prompt.md +11 -5
- package/src/prompts/tools/bash.md +5 -5
- package/src/prompts/tools/read.md +4 -2
- package/src/prompts/tools/search-tool-bm25.md +5 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/reminders/star-reminder.ts +4 -42
- package/src/runtime-mcp/manager.ts +19 -4
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/sdk/acp/adapter.ts +22 -6
- package/src/sdk/broker/lifecycle.ts +25 -6
- package/src/sdk/broker/transport.ts +35 -3
- package/src/sdk/bus/attachment-registry.ts +5 -1
- package/src/sdk/bus/chat-daemon-cli.ts +4 -39
- package/src/sdk/bus/chat-daemon-control.ts +6 -3
- package/src/sdk/bus/config.ts +18 -2
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/index.ts +984 -146
- package/src/sdk/bus/kind-aware-reconciliation.ts +317 -0
- package/src/sdk/bus/lifecycle-commands.ts +4 -1
- package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
- package/src/sdk/bus/prompt-reconciliation.ts +2 -1
- package/src/sdk/bus/reconciliation-store.ts +303 -0
- package/src/sdk/bus/rich-draft.ts +1 -1
- package/src/sdk/bus/rich-render.ts +2 -2
- package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
- package/src/sdk/bus/telegram-cli.ts +33 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +11 -4
- package/src/sdk/bus/telegram-daemon.ts +916 -23
- package/src/sdk/bus/telegram-reference.ts +40 -3
- package/src/sdk/bus/threaded-render.ts +48 -3
- package/src/sdk/bus/topic-registry.ts +20 -0
- package/src/sdk/host/control/dispatch.ts +5 -1
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +23 -1
- package/src/sdk/host/query/handlers.ts +55 -0
- package/src/sdk/host/query/revision-store.ts +36 -2
- package/src/sdk/host/reverse-leases.ts +44 -7
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/prompt-status.ts +16 -3
- package/src/sdk/protocol/operation-inventory.generated.json +51 -0
- package/src/sdk/protocol/operation-registry.ts +7 -2
- package/src/sdk/session.ts +101 -10
- package/src/session/agent-session.ts +1286 -220
- package/src/session/artifacts.ts +22 -0
- package/src/session/auth-broker-config.ts +10 -3
- package/src/session/blob-store.ts +915 -24
- package/src/session/internal/managed-session-scope.ts +44 -6
- package/src/session/internal/managed-session-storage.ts +48 -6
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +2364 -438
- package/src/session/session-storage.ts +9 -1
- package/src/session/streaming-output.ts +500 -111
- package/src/setup/credential-import.ts +75 -13
- package/src/setup/provider-onboarding.ts +19 -4
- package/src/skill-state/active-state.ts +32 -10
- package/src/skill-state/workflow-hud.ts +42 -2
- package/src/skill-state/workflow-mutation-guard.ts +560 -8
- package/src/task/executor.ts +122 -39
- package/src/task/index.ts +23 -14
- package/src/task/provider-retry-status.ts +16 -0
- package/src/task/receipt.ts +23 -7
- package/src/task/render.ts +6 -2
- package/src/task/types.ts +108 -0
- package/src/tools/ask-answer-registry.ts +12 -6
- package/src/tools/ask.ts +169 -118
- package/src/tools/ast-edit.ts +1 -0
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash-interactive.ts +8 -3
- package/src/tools/bash.ts +503 -60
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/fetch.ts +114 -23
- package/src/tools/find.ts +1 -0
- package/src/tools/image-gen.ts +29 -5
- package/src/tools/index.ts +4 -0
- package/src/tools/output-meta.ts +281 -20
- package/src/tools/path-utils.ts +8 -3
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1560 -310
- package/src/tools/resource-gc.ts +182 -18
- package/src/tools/review.ts +5 -7
- package/src/tools/search.ts +1 -0
- package/src/tools/subagent-render.ts +6 -2
- package/src/tools/subagent.ts +6 -0
- package/src/tools/telegram-send.ts +6 -3
- package/src/tools/tool-result.ts +14 -1
- package/src/utils/gh.ts +39 -0
- package/src/utils/image-resize.ts +3 -0
- package/src/web/search/providers/anthropic.ts +4 -4
- package/src/web/search/providers/codex.ts +1 -1
- package/src/web/search/providers/kimi.ts +15 -5
- package/src/web/search/providers/searxng.ts +47 -4
- package/src/web/search/providers/xai.ts +7 -2
- 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/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
- package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
- 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
- package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
|
@@ -54,6 +54,34 @@ export type TranscriptViewerOverlayOptions = {
|
|
|
54
54
|
|
|
55
55
|
type RenderedEntry = { lineStart: number; lineCount: number };
|
|
56
56
|
|
|
57
|
+
export const __transcriptViewerPerfCounters = {
|
|
58
|
+
enabled: false,
|
|
59
|
+
layoutCacheHits: 0,
|
|
60
|
+
layoutCacheMisses: 0,
|
|
61
|
+
refreshRuns: 0,
|
|
62
|
+
rebuildRuns: 0,
|
|
63
|
+
snapshot() {
|
|
64
|
+
return {
|
|
65
|
+
layoutCacheHits: this.layoutCacheHits,
|
|
66
|
+
layoutCacheMisses: this.layoutCacheMisses,
|
|
67
|
+
refreshRuns: this.refreshRuns,
|
|
68
|
+
rebuildRuns: this.rebuildRuns,
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
enable(): void {
|
|
72
|
+
this.enabled = true;
|
|
73
|
+
},
|
|
74
|
+
disable(): void {
|
|
75
|
+
this.enabled = false;
|
|
76
|
+
},
|
|
77
|
+
reset(): void {
|
|
78
|
+
this.layoutCacheHits = 0;
|
|
79
|
+
this.layoutCacheMisses = 0;
|
|
80
|
+
this.refreshRuns = 0;
|
|
81
|
+
this.rebuildRuns = 0;
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
57
85
|
/** Message-agnostic, modal transcript browser over resolved projection entries. */
|
|
58
86
|
export class TranscriptViewerOverlay extends Container {
|
|
59
87
|
#options: TranscriptViewerOverlayOptions;
|
|
@@ -73,6 +101,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
73
101
|
#followTailPending = false;
|
|
74
102
|
#skipFollowTailOnce = false;
|
|
75
103
|
#followTailActive = false;
|
|
104
|
+
#layoutCache = new Map<string, Map<string, string[]>>();
|
|
76
105
|
|
|
77
106
|
constructor(options: TranscriptViewerOverlayOptions) {
|
|
78
107
|
super();
|
|
@@ -87,7 +116,11 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
87
116
|
get isFullscreen(): boolean {
|
|
88
117
|
return this.#fullscreen;
|
|
89
118
|
}
|
|
90
|
-
refresh(identityMap?: ReadonlyMap<string, string
|
|
119
|
+
refresh(identityMap?: ReadonlyMap<string, string>, preserveLayoutCache = false): void {
|
|
120
|
+
if (__transcriptViewerPerfCounters.enabled) __transcriptViewerPerfCounters.refreshRuns++;
|
|
121
|
+
// Incremental sources explicitly invalidate same-id payload patches before requesting a
|
|
122
|
+
// preserving refresh. Other source changes conservatively drop all layout variants.
|
|
123
|
+
if (!preserveLayoutCache) this.#layoutCache.clear();
|
|
91
124
|
const previous = this.selectedEntryId;
|
|
92
125
|
const previousPosition = this.#selected;
|
|
93
126
|
const reconciledPrevious = previous ? (identityMap?.get(previous) ?? previous) : undefined;
|
|
@@ -109,9 +142,15 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
109
142
|
this.#initialized = true;
|
|
110
143
|
this.#rebuild();
|
|
111
144
|
}
|
|
145
|
+
invalidateLayoutEntries(entryIds: readonly string[]): void {
|
|
146
|
+
for (const id of entryIds) this.#layoutCache.delete(id);
|
|
147
|
+
}
|
|
112
148
|
override render(width: number): string[] {
|
|
113
|
-
|
|
114
|
-
this
|
|
149
|
+
const nextWidth = Math.max(1, width);
|
|
150
|
+
const widthChanged = nextWidth !== this.#width;
|
|
151
|
+
this.#width = nextWidth;
|
|
152
|
+
if (widthChanged) this.#layoutCache.clear();
|
|
153
|
+
if (widthChanged || getMarkdownTheme() !== this.#mdTheme) this.#rebuild();
|
|
115
154
|
const defaultHeader = this.#fullscreen
|
|
116
155
|
? [theme.fg("accent", "Transcript block")]
|
|
117
156
|
: [theme.fg("accent", sanitizeText(this.#options.title ?? "Transcript"))];
|
|
@@ -179,6 +218,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
179
218
|
if (this.#fullscreen) {
|
|
180
219
|
this.#fullscreen = false;
|
|
181
220
|
this.#scrollOffset = 0;
|
|
221
|
+
this.#rebuild();
|
|
182
222
|
this.#requestRender();
|
|
183
223
|
} else this.#options.onClose();
|
|
184
224
|
return;
|
|
@@ -208,6 +248,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
208
248
|
this.#followTailActive = false;
|
|
209
249
|
this.#followTailPending = false;
|
|
210
250
|
this.#selected = 0;
|
|
251
|
+
this.#rebuild();
|
|
211
252
|
this.#scrollOffset = 0;
|
|
212
253
|
this.#requestRender();
|
|
213
254
|
return;
|
|
@@ -216,6 +257,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
216
257
|
this.#followTailActive = true;
|
|
217
258
|
this.#followTailPending = true;
|
|
218
259
|
this.#selected = Math.max(0, count - 1);
|
|
260
|
+
this.#rebuild();
|
|
219
261
|
this.#scrollOffset = this.#lines.length;
|
|
220
262
|
this.#requestRender();
|
|
221
263
|
return;
|
|
@@ -228,6 +270,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
228
270
|
this.#followTailActive = false;
|
|
229
271
|
this.#fullscreen = true;
|
|
230
272
|
this.#scrollOffset = 0;
|
|
273
|
+
this.#rebuild();
|
|
231
274
|
this.#requestRender();
|
|
232
275
|
return;
|
|
233
276
|
}
|
|
@@ -243,6 +286,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
243
286
|
const entry = this.#entries[this.#selected];
|
|
244
287
|
if (entry?.rawViewable !== false) {
|
|
245
288
|
this.#raw.has(entry.id) ? this.#raw.delete(entry.id) : this.#raw.add(entry.id);
|
|
289
|
+
this.#rebuild();
|
|
246
290
|
this.#requestRender();
|
|
247
291
|
}
|
|
248
292
|
}
|
|
@@ -284,6 +328,7 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
284
328
|
this.#followTailActive = false;
|
|
285
329
|
this.#followTailPending = false;
|
|
286
330
|
this.#selected = Math.max(0, Math.min(this.#selected + direction * 5, this.#entries.length - 1));
|
|
331
|
+
this.#rebuild();
|
|
287
332
|
this.#scrollOffset += direction * PAGE_SIZE;
|
|
288
333
|
this.#requestRender();
|
|
289
334
|
}
|
|
@@ -327,32 +372,58 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
327
372
|
this.#options.requestRender?.();
|
|
328
373
|
}
|
|
329
374
|
#rebuild(): void {
|
|
375
|
+
if (__transcriptViewerPerfCounters.enabled) __transcriptViewerPerfCounters.rebuildRuns++;
|
|
376
|
+
// Theme is tracked by reference outside the variant key; a reference change clears
|
|
377
|
+
// the whole cache so plain and markdown layouts pick up new markdown colors.
|
|
378
|
+
const currentMdTheme = getMarkdownTheme();
|
|
379
|
+
if (currentMdTheme !== this.#mdTheme) {
|
|
380
|
+
this.#mdTheme = currentMdTheme;
|
|
381
|
+
this.#layoutCache.clear();
|
|
382
|
+
}
|
|
330
383
|
const lines: string[] = [];
|
|
331
384
|
this.#renderedEntries = [];
|
|
332
385
|
const display = this.#fullscreen ? this.#entries.slice(this.#selected, this.#selected + 1) : this.#entries;
|
|
333
386
|
const contentWidth = Math.max(1, this.#width - INDENT.length - 1);
|
|
334
387
|
for (const entry of display) {
|
|
335
388
|
const start = lines.length;
|
|
336
|
-
const
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
lines.
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
389
|
+
const entryLines = this.#renderEntryLines(entry, contentWidth);
|
|
390
|
+
lines.push(...entryLines);
|
|
391
|
+
// Cumulative positions are recomputed from cached line lengths on every rebuild
|
|
392
|
+
// so PR2c can later separate virtual coordinates from materialized lines.
|
|
393
|
+
this.#renderedEntries.push({ lineStart: start, lineCount: entryLines.length });
|
|
394
|
+
}
|
|
395
|
+
this.#lines = lines.length ? lines : [theme.fg("dim", "No transcript entries yet.")];
|
|
396
|
+
}
|
|
397
|
+
#renderEntryLines(entry: TranscriptViewerEntry, contentWidth: number): string[] {
|
|
398
|
+
const selected = entry.id === this.selectedEntryId;
|
|
399
|
+
const expanded = this.#fullscreen || this.#expanded.has(entry.id);
|
|
400
|
+
const raw = this.#raw.has(entry.id);
|
|
401
|
+
const variantKey = `${expanded ? 1 : 0}|${raw ? 1 : 0}|${selected ? 1 : 0}|${contentWidth}`;
|
|
402
|
+
let variants = this.#layoutCache.get(entry.id);
|
|
403
|
+
if (variants) {
|
|
404
|
+
const cached = variants.get(variantKey);
|
|
405
|
+
if (cached) {
|
|
406
|
+
if (__transcriptViewerPerfCounters.enabled) __transcriptViewerPerfCounters.layoutCacheHits++;
|
|
407
|
+
return cached;
|
|
355
408
|
}
|
|
409
|
+
}
|
|
410
|
+
if (__transcriptViewerPerfCounters.enabled) __transcriptViewerPerfCounters.layoutCacheMisses++;
|
|
411
|
+
const lines: string[] = [];
|
|
412
|
+
lines.push("");
|
|
413
|
+
lines.push(
|
|
414
|
+
`${selected ? theme.fg("accent", "▶") : " "} ${theme.fg("muted", `[${sanitizeText(entry.label ?? entry.kind)}]`)}`,
|
|
415
|
+
);
|
|
416
|
+
if (
|
|
417
|
+
!raw &&
|
|
418
|
+
expanded &&
|
|
419
|
+
selected &&
|
|
420
|
+
entry.kind === "tool" &&
|
|
421
|
+
entry.richRenderEligible === true &&
|
|
422
|
+
entry.renderDescriptor
|
|
423
|
+
) {
|
|
424
|
+
for (const line of renderToolDisplayLines(entry.renderDescriptor, contentWidth, theme))
|
|
425
|
+
lines.push(`${INDENT}${line}`);
|
|
426
|
+
} else {
|
|
356
427
|
const text = sanitizeText(
|
|
357
428
|
(raw
|
|
358
429
|
? entry.payload.text
|
|
@@ -375,9 +446,13 @@ export class TranscriptViewerOverlay extends Container {
|
|
|
375
446
|
for (const line of preview) lines.push(`${INDENT}${truncateToWidth(line, contentWidth)}`);
|
|
376
447
|
if (text.split("\n").length > PREVIEW_LINES) lines.push(`${INDENT}${theme.fg("dim", "... more (Space)")}`);
|
|
377
448
|
}
|
|
378
|
-
this.#renderedEntries.push({ lineStart: start, lineCount: lines.length - start });
|
|
379
449
|
}
|
|
380
|
-
|
|
450
|
+
if (!variants) {
|
|
451
|
+
variants = new Map();
|
|
452
|
+
this.#layoutCache.set(entry.id, variants);
|
|
453
|
+
}
|
|
454
|
+
variants.set(variantKey, lines);
|
|
455
|
+
return lines;
|
|
381
456
|
}
|
|
382
457
|
#markdown(text: string, width: number): string[] {
|
|
383
458
|
return new Markdown(text, 0, 0, this.#mdTheme).render(width).map(line => `${INDENT}${line.trimEnd()}`);
|
|
@@ -1175,6 +1175,10 @@ export class CommandController {
|
|
|
1175
1175
|
}
|
|
1176
1176
|
this.ctx.showError(`Bash command failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1177
1177
|
}
|
|
1178
|
+
const bashComponent = this.ctx.bashComponent;
|
|
1179
|
+
if (isDeferred && bashComponent && this.ctx.pendingBashComponents.includes(bashComponent)) {
|
|
1180
|
+
this.ctx.pendingMessagesContainer.detachChild(bashComponent);
|
|
1181
|
+
}
|
|
1178
1182
|
|
|
1179
1183
|
this.ctx.bashComponent = undefined;
|
|
1180
1184
|
this.ctx.ui.requestRender();
|
|
@@ -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":
|
|
@@ -399,7 +416,9 @@ export class ExtensionUiController {
|
|
|
399
416
|
const contextActions: ExtensionContextActions = {
|
|
400
417
|
getModel: () => this.ctx.session.model,
|
|
401
418
|
isIdle: () => !this.ctx.session.isStreaming,
|
|
419
|
+
getActivePromptHandle: () => this.ctx.session.activePromptHandle,
|
|
402
420
|
abort: () => this.ctx.session.abort(),
|
|
421
|
+
abortPromptAndWait: (handle, options) => this.ctx.session.abortPromptAndWait(handle, options),
|
|
403
422
|
hasPendingMessages: () => this.ctx.session.queuedMessageCount > 0,
|
|
404
423
|
getPendingMessageCounts: () => this.ctx.session.pendingMessageCounts,
|
|
405
424
|
getTranscript: () => this.ctx.session.getTranscript(),
|
|
@@ -442,7 +461,7 @@ export class ExtensionUiController {
|
|
|
442
461
|
}
|
|
443
462
|
return false;
|
|
444
463
|
},
|
|
445
|
-
invokeSkill: (name, args) => this.ctx.session.invokeSkill(name, args),
|
|
464
|
+
invokeSkill: (name, args, options) => this.ctx.session.invokeSkill(name, args, options),
|
|
446
465
|
setPlanMode: on => this.ctx.session.setSdkPlanMode(on),
|
|
447
466
|
operateGoal: (op, objective) => this.ctx.session.operateGoal(op, objective),
|
|
448
467
|
getSkillState: () =>
|
|
@@ -451,6 +470,7 @@ export class ExtensionUiController {
|
|
|
451
470
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
452
471
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
453
472
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
473
|
+
setSdkClientBridge: bridge => this.ctx.session.setClientBridge(bridge),
|
|
454
474
|
sdkControl: this.#sdkControl,
|
|
455
475
|
};
|
|
456
476
|
const commandActions: ExtensionCommandContextActions = {
|
|
@@ -698,7 +718,9 @@ export class ExtensionUiController {
|
|
|
698
718
|
const contextActions: ExtensionContextActions = {
|
|
699
719
|
getModel: () => this.ctx.session.model,
|
|
700
720
|
isIdle: () => !this.ctx.session.isStreaming,
|
|
721
|
+
getActivePromptHandle: () => this.ctx.session.activePromptHandle,
|
|
701
722
|
abort: () => this.ctx.session.abort(),
|
|
723
|
+
abortPromptAndWait: (handle, options) => this.ctx.session.abortPromptAndWait(handle, options),
|
|
702
724
|
hasPendingMessages: () => this.ctx.session.queuedMessageCount > 0,
|
|
703
725
|
getPendingMessageCounts: () => this.ctx.session.pendingMessageCounts,
|
|
704
726
|
getTranscript: () => this.ctx.session.getTranscript(),
|
|
@@ -747,6 +769,7 @@ export class ExtensionUiController {
|
|
|
747
769
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
748
770
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
749
771
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
772
|
+
setSdkClientBridge: bridge => this.ctx.session.setClientBridge(bridge),
|
|
750
773
|
sdkControl: this.#sdkControl,
|
|
751
774
|
};
|
|
752
775
|
const commandActions: ExtensionCommandContextActions = {
|
|
@@ -918,6 +941,7 @@ export class ExtensionUiController {
|
|
|
918
941
|
sessionManager: createReadonlySessionManager(this.ctx.session.sessionManager),
|
|
919
942
|
modelRegistry: this.ctx.session.modelRegistry,
|
|
920
943
|
model: this.ctx.session.model,
|
|
944
|
+
getActivePromptHandle: () => this.ctx.session.activePromptHandle,
|
|
921
945
|
isIdle: () => !this.ctx.session.isStreaming,
|
|
922
946
|
hasPendingMessages: () => this.ctx.session.queuedMessageCount > 0,
|
|
923
947
|
getPendingMessageCounts: () => this.ctx.session.pendingMessageCounts,
|