@orion-agents/orion-code 0.2.0 → 0.3.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 +75 -0
- package/README.md +73 -14
- package/README.zh-CN.md +63 -13
- package/bin/orion +15 -4
- package/dist/cli.js +51 -172
- package/dist/cli.js.map +1 -1
- package/dist/commands/model-command-handlers.d.ts +2 -2
- package/dist/commands/model-command-handlers.d.ts.map +1 -1
- package/dist/commands/model-command-handlers.js +113 -32
- package/dist/commands/model-command-handlers.js.map +1 -1
- package/dist/commands/session-command-handlers.d.ts +1 -1
- package/dist/commands/session-command-handlers.d.ts.map +1 -1
- package/dist/commands/session-command-handlers.js +121 -16
- package/dist/commands/session-command-handlers.js.map +1 -1
- package/dist/commands/types.d.ts +14 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/runtime/agent-loop.d.ts +2 -0
- package/dist/runtime/agent-loop.d.ts.map +1 -1
- package/dist/runtime/agent-loop.js +4 -3
- package/dist/runtime/agent-loop.js.map +1 -1
- package/dist/runtime/agent-runtime-controller.d.ts +32 -1
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +250 -31
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-runner.d.ts +3 -0
- package/dist/runtime/agent-runtime-runner.d.ts.map +1 -1
- package/dist/runtime/goal-runtime-coordinator.d.ts +6 -0
- package/dist/runtime/goal-runtime-coordinator.d.ts.map +1 -1
- package/dist/runtime/goal-runtime-coordinator.js +5 -0
- package/dist/runtime/goal-runtime-coordinator.js.map +1 -1
- package/dist/runtime/legacy-thread-materializer.d.ts +18 -0
- package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -1
- package/dist/runtime/legacy-thread-materializer.js +27 -12
- package/dist/runtime/legacy-thread-materializer.js.map +1 -1
- package/dist/runtime/orion-runtime-v1.d.ts +3 -0
- package/dist/runtime/orion-runtime-v1.d.ts.map +1 -1
- package/dist/runtime/orion-runtime-v1.js +8 -1
- package/dist/runtime/orion-runtime-v1.js.map +1 -1
- package/dist/runtime/orion-session-runner.d.ts +7 -1
- package/dist/runtime/orion-session-runner.d.ts.map +1 -1
- package/dist/runtime/orion-session-runner.js +35 -3
- package/dist/runtime/orion-session-runner.js.map +1 -1
- package/dist/runtime/product-bootstrap.d.ts +22 -0
- package/dist/runtime/product-bootstrap.d.ts.map +1 -0
- package/dist/runtime/product-bootstrap.js +374 -0
- package/dist/runtime/product-bootstrap.js.map +1 -0
- package/dist/runtime/product-orion-runtime.d.ts +2 -1
- package/dist/runtime/product-orion-runtime.d.ts.map +1 -1
- package/dist/runtime/product-orion-runtime.js +114 -16
- package/dist/runtime/product-orion-runtime.js.map +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.d.ts +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.js +1 -1
- package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -1
- package/dist/runtime/release-receipts.d.ts +63 -2
- package/dist/runtime/release-receipts.d.ts.map +1 -1
- package/dist/runtime/release-receipts.js +298 -7
- package/dist/runtime/release-receipts.js.map +1 -1
- package/dist/runtime/session-history-recovery.d.ts +19 -0
- package/dist/runtime/session-history-recovery.d.ts.map +1 -0
- package/dist/runtime/session-history-recovery.js +45 -0
- package/dist/runtime/session-history-recovery.js.map +1 -0
- package/dist/runtime/step-snapshot.d.ts.map +1 -1
- package/dist/runtime/step-snapshot.js +22 -2
- package/dist/runtime/step-snapshot.js.map +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js +5 -2
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/thread-event-store.d.ts +27 -0
- package/dist/runtime/thread-event-store.d.ts.map +1 -1
- package/dist/runtime/thread-event-store.js +119 -17
- package/dist/runtime/thread-event-store.js.map +1 -1
- package/dist/runtime/thread-projection.d.ts +10 -0
- package/dist/runtime/thread-projection.d.ts.map +1 -1
- package/dist/runtime/thread-projection.js +40 -0
- package/dist/runtime/thread-projection.js.map +1 -1
- package/dist/runtime/thread-runtime.d.ts +3 -1
- package/dist/runtime/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/thread-runtime.js +6 -0
- package/dist/runtime/thread-runtime.js.map +1 -1
- package/dist/runtime/thread-session-view.d.ts +88 -0
- package/dist/runtime/thread-session-view.d.ts.map +1 -0
- package/dist/runtime/thread-session-view.js +327 -0
- package/dist/runtime/thread-session-view.js.map +1 -0
- package/dist/runtime/thread-ui-adapter.d.ts +4 -0
- package/dist/runtime/thread-ui-adapter.d.ts.map +1 -1
- package/dist/runtime/thread-ui-adapter.js +193 -5
- package/dist/runtime/thread-ui-adapter.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +37 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js +1 -0
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/runtime/ui-view-model.d.ts +3 -0
- package/dist/runtime/ui-view-model.d.ts.map +1 -1
- package/dist/runtime/ui-view-model.js +10 -3
- package/dist/runtime/ui-view-model.js.map +1 -1
- package/dist/services/file-lock.d.ts.map +1 -1
- package/dist/services/file-lock.js +42 -17
- package/dist/services/file-lock.js.map +1 -1
- package/dist/services/global-config.d.ts +25 -0
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js +373 -5
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/session-storage.d.ts +67 -0
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +327 -61
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/settings-coordinator.d.ts +174 -0
- package/dist/services/settings-coordinator.d.ts.map +1 -0
- package/dist/services/settings-coordinator.js +605 -0
- package/dist/services/settings-coordinator.js.map +1 -0
- package/dist/services/settings-document-repository.d.ts +138 -0
- package/dist/services/settings-document-repository.d.ts.map +1 -0
- package/dist/services/settings-document-repository.js +551 -0
- package/dist/services/settings-document-repository.js.map +1 -0
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +7 -0
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/tools/web.js +1 -1
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-ui/chrome-view-model.d.ts.map +1 -1
- package/dist/tui-ui/chrome-view-model.js +21 -7
- package/dist/tui-ui/chrome-view-model.js.map +1 -1
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +13 -0
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +7 -0
- package/dist/tui-ui/state.js.map +1 -1
- package/dist/web/event-hub.d.ts +39 -0
- package/dist/web/event-hub.d.ts.map +1 -0
- package/dist/web/event-hub.js +263 -0
- package/dist/web/event-hub.js.map +1 -0
- package/dist/web/index.d.ts +6 -0
- package/dist/web/index.d.ts.map +1 -0
- package/dist/web/index.js +28 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/launch.d.ts +9 -0
- package/dist/web/launch.d.ts.map +1 -0
- package/dist/web/launch.js +64 -0
- package/dist/web/launch.js.map +1 -0
- package/dist/web/protocol.d.ts +346 -0
- package/dist/web/protocol.d.ts.map +1 -0
- package/dist/web/protocol.js +348 -0
- package/dist/web/protocol.js.map +1 -0
- package/dist/web/server.d.ts +20 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +498 -0
- package/dist/web/server.js.map +1 -0
- package/dist/web/workbench-controller.d.ts +63 -0
- package/dist/web/workbench-controller.d.ts.map +1 -0
- package/dist/web/workbench-controller.js +774 -0
- package/dist/web/workbench-controller.js.map +1 -0
- package/dist/web-client/assets/index-BAEO71Gp.css +1 -0
- package/dist/web-client/assets/index-DSkFy7gM.js +13 -0
- package/dist/web-client/index.html +16 -0
- package/docs/architecture/v0.3.0-web-api.yaml +1309 -0
- package/docs/migration/v0.2.2-to-v0.3.0-settings.md +114 -0
- package/docs/migration/v0.2.2-to-v0.3.0.md +55 -0
- package/docs/orion.example.json +9 -2
- package/docs/plan/v0.3.0-node-runtime-compatibility-plan.md +57 -0
- package/docs/plan/v0.3.0-settings-integration-plan.md +740 -0
- package/docs/plan/v0.3.0-web-workbench-plan.md +325 -0
- package/docs/readme.md +12 -1
- package/npm-shrinkwrap.json +1777 -424
- package/package.json +33 -9
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgentMode } from '../commands/types';
|
|
1
2
|
import type { AgentRuntimeEventSink, AgentRuntimeInput, AgentRuntimeInputResult, AgentRuntimeInterruptResult, AgentRuntimeSubmitResult } from './agent-runtime-protocol';
|
|
2
3
|
import type { AgentRuntimeRunnerV1, AgentRuntimeRunInputOptionsV1 } from './agent-runtime-runner';
|
|
3
4
|
import type { OrionCodeUiRuntime, FollowupQueueItem, UiEventSink, UiRendererCapabilities } from './ui-events';
|
|
@@ -13,6 +14,20 @@ export interface AgentRuntimeToolPermissionRequest {
|
|
|
13
14
|
reason?: string;
|
|
14
15
|
abortSignal?: AbortSignal;
|
|
15
16
|
}
|
|
17
|
+
/** Secret-free immutable read model for reconnecting renderer surfaces. */
|
|
18
|
+
export interface AgentRuntimePendingPermissionSnapshot {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly reason?: string;
|
|
22
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
23
|
+
}
|
|
24
|
+
/** Exact agent-mode input used by renderers with a three-state selector. */
|
|
25
|
+
export interface AgentRuntimeSetAgentModeInput {
|
|
26
|
+
readonly type: 'set_agent_mode';
|
|
27
|
+
readonly mode: AgentMode;
|
|
28
|
+
readonly source?: 'picker' | 'command' | 'programmatic';
|
|
29
|
+
}
|
|
30
|
+
export type AgentRuntimeControllerInput = AgentRuntimeInput | AgentRuntimeSetAgentModeInput;
|
|
16
31
|
export interface AgentRuntimeControllerOptions extends TurnControllerOptions {
|
|
17
32
|
runtime: OrionCodeUiRuntime;
|
|
18
33
|
events?: UiEventSink;
|
|
@@ -54,7 +69,11 @@ export declare class AgentRuntimeController {
|
|
|
54
69
|
private readonly agentModeLifecycle;
|
|
55
70
|
private readonly pendingPermissions;
|
|
56
71
|
private activeRun;
|
|
72
|
+
private pendingAgentMode;
|
|
57
73
|
private readonly goalControlRuns;
|
|
74
|
+
private activeGoalRuntimeTransitions;
|
|
75
|
+
private goalRuntimeActive;
|
|
76
|
+
private settingsBoundarySynchronizations;
|
|
58
77
|
private stopping;
|
|
59
78
|
private nextPermissionRequestId;
|
|
60
79
|
private readonly queuedCommands;
|
|
@@ -64,6 +83,11 @@ export declare class AgentRuntimeController {
|
|
|
64
83
|
constructor(options: AgentRuntimeControllerOptions);
|
|
65
84
|
hasActiveTurn(): boolean;
|
|
66
85
|
getFollowupQueue(): readonly FollowupQueueItem[];
|
|
86
|
+
/**
|
|
87
|
+
* Return a detached read model for browser refresh/reconnect recovery.
|
|
88
|
+
* AbortSignal and resolver ownership remain private to the controller.
|
|
89
|
+
*/
|
|
90
|
+
getPendingPermissions(): readonly AgentRuntimePendingPermissionSnapshot[];
|
|
67
91
|
/** Thin /goal control surface; GoalRuntimeCoordinatorV2 owns every mutation. */
|
|
68
92
|
handleTargetInput(rawInput: string): {
|
|
69
93
|
handled: boolean;
|
|
@@ -79,7 +103,9 @@ export declare class AgentRuntimeController {
|
|
|
79
103
|
setVerificationState(state: 'pending' | 'running' | 'passed' | 'failed' | 'gated'): void;
|
|
80
104
|
getVerificationState(): 'pending' | 'running' | 'passed' | 'failed' | 'gated' | undefined;
|
|
81
105
|
clearExitIntent(): void;
|
|
82
|
-
handle(input:
|
|
106
|
+
handle(input: AgentRuntimeControllerInput): AgentRuntimeInputResult;
|
|
107
|
+
/** Set an exact mode immediately while idle, or at the next logical-request boundary. */
|
|
108
|
+
setAgentMode(mode: AgentMode): AgentRuntimeInputResult;
|
|
83
109
|
private queueFollowup;
|
|
84
110
|
private manageFollowupQueue;
|
|
85
111
|
submit(input: string): AgentRuntimeSubmitResult;
|
|
@@ -92,16 +118,21 @@ export declare class AgentRuntimeController {
|
|
|
92
118
|
waitForIdle(): Promise<void>;
|
|
93
119
|
private runTurn;
|
|
94
120
|
private handleRunLoopError;
|
|
121
|
+
private synchronizeSettingsAtLogicalBoundary;
|
|
95
122
|
private emitAppend;
|
|
96
123
|
private emitStatus;
|
|
97
124
|
private emitProcessing;
|
|
98
125
|
private emitFollowupQueue;
|
|
126
|
+
private agentModeSnapshot;
|
|
99
127
|
private emitAgentModeSnapshot;
|
|
100
128
|
private cycleAgentMode;
|
|
129
|
+
private applyPendingAgentMode;
|
|
101
130
|
private requestIsCurrent;
|
|
102
131
|
requestToolPermission(request: AgentRuntimeToolPermissionRequest): Promise<boolean>;
|
|
103
132
|
private startGoalControl;
|
|
104
133
|
private renderGoalControl;
|
|
134
|
+
private observeGoalControlResult;
|
|
135
|
+
private observeGoalRuntimeEvent;
|
|
105
136
|
private recordPermissionDecision;
|
|
106
137
|
private applyPermissionModeChange;
|
|
107
138
|
private rejectPendingPermissions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-runtime-controller.d.ts","sourceRoot":"","sources":["../../src/runtime/agent-runtime-controller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-runtime-controller.d.ts","sourceRoot":"","sources":["../../src/runtime/agent-runtime-controller.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentRuntimeController = void 0;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
4
5
|
const commands_1 = require("../commands");
|
|
5
6
|
const parser_1 = require("../commands/parser");
|
|
6
7
|
const target_command_1 = require("../commands/target-command");
|
|
@@ -8,9 +9,9 @@ const agent_runtime_protocol_1 = require("./agent-runtime-protocol");
|
|
|
8
9
|
const agent_status_1 = require("./agent-status");
|
|
9
10
|
const ui_events_1 = require("./ui-events");
|
|
10
11
|
const turn_controller_1 = require("./turn-controller");
|
|
11
|
-
const global_config_1 = require("../services/global-config");
|
|
12
12
|
const tool_allowlist_1 = require("../services/tool-allowlist");
|
|
13
13
|
const agent_mode_1 = require("../framework/agent-mode");
|
|
14
|
+
const redaction_1 = require("../services/redaction");
|
|
14
15
|
const style_1 = require("../tui-core/style");
|
|
15
16
|
function isExitInput(input) {
|
|
16
17
|
const parsed = (0, parser_1.parseInput)(input.trim());
|
|
@@ -46,7 +47,11 @@ class AgentRuntimeController {
|
|
|
46
47
|
this.options = options;
|
|
47
48
|
this.pendingPermissions = new Map();
|
|
48
49
|
this.activeRun = null;
|
|
50
|
+
this.pendingAgentMode = null;
|
|
49
51
|
this.goalControlRuns = new Set();
|
|
52
|
+
this.activeGoalRuntimeTransitions = 0;
|
|
53
|
+
this.goalRuntimeActive = false;
|
|
54
|
+
this.settingsBoundarySynchronizations = 0;
|
|
50
55
|
this.stopping = false;
|
|
51
56
|
this.nextPermissionRequestId = 1;
|
|
52
57
|
this.queuedCommands = [];
|
|
@@ -60,6 +65,8 @@ class AgentRuntimeController {
|
|
|
60
65
|
const downstream = options.eventSink ?? (0, agent_runtime_protocol_1.createAgentRuntimeEventSinkFromUiEvents)(options.events);
|
|
61
66
|
this.eventSink = {
|
|
62
67
|
emit: event => {
|
|
68
|
+
if (event.type === 'goal_event')
|
|
69
|
+
this.observeGoalRuntimeEvent(event.event);
|
|
63
70
|
const result = downstream.emit(event);
|
|
64
71
|
if (event.type === 'session_restored') {
|
|
65
72
|
if (this.followupQueue.length > 0) {
|
|
@@ -75,11 +82,18 @@ class AgentRuntimeController {
|
|
|
75
82
|
this.agentModeLifecycle.subscribe(snapshot => {
|
|
76
83
|
this.eventSink.emit({ type: 'agent_mode_changed', snapshot });
|
|
77
84
|
});
|
|
85
|
+
options.runtime.bindSettingsRuntimeIdleProbe?.(() => (this.settingsBoundarySynchronizations > 0 || !this.turnController.hasActiveTurn()) &&
|
|
86
|
+
this.activeGoalRuntimeTransitions === 0 &&
|
|
87
|
+
!this.goalRuntimeActive);
|
|
78
88
|
const events = (0, agent_runtime_protocol_1.createUiEventSinkFromAgentRuntimeEvents)(this.eventSink);
|
|
79
89
|
this.runner =
|
|
80
90
|
options.runner ??
|
|
81
91
|
options.runtime.createAgentRunner?.(events, {
|
|
82
92
|
approvalHandler: request => this.requestToolPermission(request),
|
|
93
|
+
// Every renderer restores history from a bounded, cursor-bound surface
|
|
94
|
+
// projection. Replaying the complete durable Thread here couples Runtime
|
|
95
|
+
// recovery to UI history size and makes /resume O(total Thread facts).
|
|
96
|
+
replayHistoryOnRestore: false,
|
|
83
97
|
}) ??
|
|
84
98
|
createUnavailableRunner();
|
|
85
99
|
this.emitAgentModeSnapshot();
|
|
@@ -90,6 +104,13 @@ class AgentRuntimeController {
|
|
|
90
104
|
getFollowupQueue() {
|
|
91
105
|
return this.followupQueue;
|
|
92
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Return a detached read model for browser refresh/reconnect recovery.
|
|
109
|
+
* AbortSignal and resolver ownership remain private to the controller.
|
|
110
|
+
*/
|
|
111
|
+
getPendingPermissions() {
|
|
112
|
+
return Object.freeze([...this.pendingPermissions.values()].map(entry => entry.snapshot));
|
|
113
|
+
}
|
|
93
114
|
/** Thin /goal control surface; GoalRuntimeCoordinatorV2 owns every mutation. */
|
|
94
115
|
handleTargetInput(rawInput) {
|
|
95
116
|
const parsed = (0, target_command_1.parseTargetCommand)(rawInput);
|
|
@@ -162,8 +183,31 @@ class AgentRuntimeController {
|
|
|
162
183
|
return this.applyPermissionModeChange(input.value);
|
|
163
184
|
case 'cycle_agent_mode':
|
|
164
185
|
return this.cycleAgentMode();
|
|
186
|
+
case 'set_agent_mode':
|
|
187
|
+
return this.setAgentMode(input.mode);
|
|
165
188
|
}
|
|
166
189
|
}
|
|
190
|
+
/** Set an exact mode immediately while idle, or at the next logical-request boundary. */
|
|
191
|
+
setAgentMode(mode) {
|
|
192
|
+
const deferred = this.turnController.hasActiveTurn();
|
|
193
|
+
if (!deferred) {
|
|
194
|
+
this.pendingAgentMode = null;
|
|
195
|
+
return {
|
|
196
|
+
type: 'agent_mode_changed',
|
|
197
|
+
snapshot: this.agentModeLifecycle.setMode(mode),
|
|
198
|
+
appliesFrom: 'immediate',
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const baseMode = this.agentModeLifecycle.snapshot().baseMode;
|
|
202
|
+
this.pendingAgentMode = mode === baseMode ? null : mode;
|
|
203
|
+
const snapshot = this.agentModeSnapshot();
|
|
204
|
+
this.emitAgentModeSnapshot(snapshot);
|
|
205
|
+
return {
|
|
206
|
+
type: 'agent_mode_changed',
|
|
207
|
+
snapshot,
|
|
208
|
+
appliesFrom: 'next-logical-request',
|
|
209
|
+
};
|
|
210
|
+
}
|
|
167
211
|
queueFollowup(input) {
|
|
168
212
|
const text = input.trim();
|
|
169
213
|
if (!text)
|
|
@@ -262,7 +306,11 @@ class AgentRuntimeController {
|
|
|
262
306
|
this.turnController.requestRevision(submitted);
|
|
263
307
|
// v0.1.3 (G1): echo the incremental input to the transcript immediately,
|
|
264
308
|
// so the user sees their correction without waiting for the turn to abort.
|
|
265
|
-
this
|
|
309
|
+
// A runtime-owned durable transcript disables this optimistic projection
|
|
310
|
+
// and emits the revision from its authoritative user item instead.
|
|
311
|
+
if (this.options.echoSubmittedInput ?? true) {
|
|
312
|
+
this.emitAppend(submittedEntry(submitted));
|
|
313
|
+
}
|
|
266
314
|
this.emitStatus(this.options.revisionStatus ?? '已接收补充,正在中断当前轮…');
|
|
267
315
|
return { type: 'revision_requested' };
|
|
268
316
|
}
|
|
@@ -307,6 +355,8 @@ class AgentRuntimeController {
|
|
|
307
355
|
this.emitStatus(`/${name} acknowledged; active turn continues.`);
|
|
308
356
|
}
|
|
309
357
|
async runCommand(command, args) {
|
|
358
|
+
if (command.risk !== 'read-only')
|
|
359
|
+
await this.options.runtime.synchronizeSettings?.();
|
|
310
360
|
const renderer = this.options.uiRenderer ?? this.options.runtime.config.ui?.renderer ?? 'terminal';
|
|
311
361
|
if (command.rendererScope && !command.rendererScope.includes(renderer)) {
|
|
312
362
|
this.emitAppend({
|
|
@@ -382,7 +432,13 @@ class AgentRuntimeController {
|
|
|
382
432
|
sessionId: this.options.runtime.getSession()?.id,
|
|
383
433
|
ensureSession: this.options.runtime.ensureSession,
|
|
384
434
|
setSession: session => this.options.runtime.setSession(session),
|
|
435
|
+
restoreSessionRuntime: this.runner.restoreSession
|
|
436
|
+
? activation => this.runner.restoreSession(activation)
|
|
437
|
+
: undefined,
|
|
385
438
|
sessionRestored: event => this.eventSink.emit({ type: 'session_restored', event }),
|
|
439
|
+
...((renderer === 'terminal' || renderer === 'tui') && {
|
|
440
|
+
replaceTranscript: (entries) => this.eventSink.emit({ type: 'transcript_replace', entries: [...entries] }),
|
|
441
|
+
}),
|
|
386
442
|
getSession: this.options.runtime.getSession,
|
|
387
443
|
writeOutput: text => {
|
|
388
444
|
if (text.trim())
|
|
@@ -398,6 +454,9 @@ class AgentRuntimeController {
|
|
|
398
454
|
uiCapabilities: (0, ui_events_1.resolveUiRendererCapabilities)(this.options.uiCapabilities, renderer),
|
|
399
455
|
agentModeLifecycle: this.agentModeLifecycle,
|
|
400
456
|
getHarnessDiagnostics: this.options.runtime.getHarnessDiagnostics,
|
|
457
|
+
settingsCoordinator: this.options.runtime.settingsCoordinator,
|
|
458
|
+
describeSettings: this.options.runtime.describeSettings,
|
|
459
|
+
updateSettings: this.options.runtime.updateSettings,
|
|
401
460
|
compact: this.runner.compact ? input => this.runner.compact(input) : undefined,
|
|
402
461
|
};
|
|
403
462
|
}
|
|
@@ -440,10 +499,7 @@ class AgentRuntimeController {
|
|
|
440
499
|
this.stopping = false;
|
|
441
500
|
}
|
|
442
501
|
async waitForIdle() {
|
|
443
|
-
await Promise.all([
|
|
444
|
-
this.activeRun ?? Promise.resolve(),
|
|
445
|
-
...this.goalControlRuns,
|
|
446
|
-
]);
|
|
502
|
+
await Promise.all([this.activeRun ?? Promise.resolve(), ...this.goalControlRuns]);
|
|
447
503
|
}
|
|
448
504
|
async runTurn(firstRequest) {
|
|
449
505
|
let nextRequest = firstRequest;
|
|
@@ -460,12 +516,15 @@ class AgentRuntimeController {
|
|
|
460
516
|
}
|
|
461
517
|
this.options.beforeTurn?.(nextInput);
|
|
462
518
|
const turn = this.turnController.beginTurn(nextInput);
|
|
463
|
-
this.options.runtime.store.setProcessing(true);
|
|
464
|
-
this.emitProcessing(true);
|
|
465
|
-
const runningStatus = statusText(this.options.runningStatus, nextInput);
|
|
466
|
-
if (runningStatus)
|
|
467
|
-
this.emitStatus(runningStatus);
|
|
468
519
|
try {
|
|
520
|
+
if (this.options.runtime.synchronizeSettings) {
|
|
521
|
+
await this.synchronizeSettingsAtLogicalBoundary();
|
|
522
|
+
}
|
|
523
|
+
this.options.runtime.store.setProcessing(true);
|
|
524
|
+
this.emitProcessing(true);
|
|
525
|
+
const runningStatus = statusText(this.options.runningStatus, nextInput);
|
|
526
|
+
if (runningStatus)
|
|
527
|
+
this.emitStatus(runningStatus);
|
|
469
528
|
if (this.runner.runRequest) {
|
|
470
529
|
await this.runner.runRequest(request, {
|
|
471
530
|
abortSignal: turn.abortSignal,
|
|
@@ -493,9 +552,12 @@ class AgentRuntimeController {
|
|
|
493
552
|
}
|
|
494
553
|
finally {
|
|
495
554
|
const revision = this.turnController.finishTurn(turn.id);
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
555
|
+
// Durable request runners commit and enqueue Plan execution at the Thread boundary.
|
|
556
|
+
// The legacy runInput path still needs the controller-owned compatibility follow-up.
|
|
557
|
+
const completedPlan = this.runner.runRequest
|
|
558
|
+
? undefined
|
|
559
|
+
: (this.agentModeLifecycle.completedPlanSince(planCompletionBeforeRequest) ?? undefined);
|
|
560
|
+
this.applyPendingAgentMode(Boolean(completedPlan));
|
|
499
561
|
if (revision?.trim()) {
|
|
500
562
|
this.emitStatus(this.options.restartingStatus ?? '根据补充调整方向中…');
|
|
501
563
|
nextRequest = {
|
|
@@ -571,6 +633,18 @@ class AgentRuntimeController {
|
|
|
571
633
|
this.emitStatus(readyStatus);
|
|
572
634
|
this.options.afterTurnLoop?.();
|
|
573
635
|
}
|
|
636
|
+
async synchronizeSettingsAtLogicalBoundary() {
|
|
637
|
+
const synchronize = this.options.runtime.synchronizeSettings;
|
|
638
|
+
if (!synchronize)
|
|
639
|
+
return;
|
|
640
|
+
this.settingsBoundarySynchronizations += 1;
|
|
641
|
+
try {
|
|
642
|
+
await synchronize();
|
|
643
|
+
}
|
|
644
|
+
finally {
|
|
645
|
+
this.settingsBoundarySynchronizations -= 1;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
574
648
|
emitAppend(entry) {
|
|
575
649
|
return this.eventSink.emit({ type: 'transcript_append', entry });
|
|
576
650
|
}
|
|
@@ -586,21 +660,49 @@ class AgentRuntimeController {
|
|
|
586
660
|
snapshot: { items: [...this.followupQueue], limit: this.followupQueueLimit },
|
|
587
661
|
});
|
|
588
662
|
}
|
|
589
|
-
|
|
663
|
+
agentModeSnapshot() {
|
|
664
|
+
const snapshot = this.agentModeLifecycle.snapshot();
|
|
665
|
+
return this.pendingAgentMode
|
|
666
|
+
? { ...snapshot, pendingBaseMode: this.pendingAgentMode }
|
|
667
|
+
: snapshot;
|
|
668
|
+
}
|
|
669
|
+
emitAgentModeSnapshot(snapshot = this.agentModeSnapshot()) {
|
|
590
670
|
this.eventSink.emit({
|
|
591
671
|
type: 'agent_mode_changed',
|
|
592
|
-
snapshot
|
|
672
|
+
snapshot,
|
|
593
673
|
});
|
|
594
674
|
}
|
|
595
675
|
cycleAgentMode() {
|
|
596
676
|
const deferred = this.turnController.hasActiveTurn();
|
|
597
|
-
|
|
677
|
+
if (!deferred)
|
|
678
|
+
this.pendingAgentMode = null;
|
|
679
|
+
const lifecycleSnapshot = this.agentModeLifecycle.snapshot();
|
|
680
|
+
const nextMode = (0, agent_mode_1.nextAgentMode)(this.pendingAgentMode ?? lifecycleSnapshot.pendingBaseMode ?? lifecycleSnapshot.baseMode);
|
|
681
|
+
let snapshot;
|
|
682
|
+
if (deferred) {
|
|
683
|
+
this.pendingAgentMode = nextMode === lifecycleSnapshot.baseMode ? null : nextMode;
|
|
684
|
+
snapshot = this.agentModeSnapshot();
|
|
685
|
+
this.emitAgentModeSnapshot(snapshot);
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
snapshot = this.agentModeLifecycle.setMode(nextMode);
|
|
689
|
+
}
|
|
598
690
|
return {
|
|
599
691
|
type: 'agent_mode_changed',
|
|
600
692
|
snapshot,
|
|
601
693
|
appliesFrom: deferred ? 'next-logical-request' : 'immediate',
|
|
602
694
|
};
|
|
603
695
|
}
|
|
696
|
+
applyPendingAgentMode(completedPlan) {
|
|
697
|
+
const pendingMode = this.pendingAgentMode;
|
|
698
|
+
this.pendingAgentMode = null;
|
|
699
|
+
if (pendingMode) {
|
|
700
|
+
this.agentModeLifecycle.setMode(pendingMode);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (!completedPlan)
|
|
704
|
+
this.agentModeLifecycle.applyPending();
|
|
705
|
+
}
|
|
604
706
|
requestIsCurrent(request) {
|
|
605
707
|
const activeSessionId = this.options.runtime.getSession()?.id;
|
|
606
708
|
return !activeSessionId || request.sessionId === activeSessionId;
|
|
@@ -616,6 +718,7 @@ class AgentRuntimeController {
|
|
|
616
718
|
reason: request.reason,
|
|
617
719
|
abortSignal: request.abortSignal,
|
|
618
720
|
};
|
|
721
|
+
const snapshot = createPendingPermissionSnapshot(id, request);
|
|
619
722
|
return new Promise(resolve => {
|
|
620
723
|
const finish = (approved) => {
|
|
621
724
|
this.pendingPermissions.delete(id);
|
|
@@ -623,7 +726,7 @@ class AgentRuntimeController {
|
|
|
623
726
|
resolve(approved);
|
|
624
727
|
};
|
|
625
728
|
const onAbort = () => finish(false);
|
|
626
|
-
this.pendingPermissions.set(id, { request, finish });
|
|
729
|
+
this.pendingPermissions.set(id, { request, snapshot, finish });
|
|
627
730
|
request.abortSignal?.addEventListener('abort', onAbort, { once: true });
|
|
628
731
|
this.emitStatus((0, agent_status_1.permissionPendingStatus)(request.name));
|
|
629
732
|
this.eventSink.emit({ type: 'permission_requested', request: runtimeRequest });
|
|
@@ -637,21 +740,46 @@ class AgentRuntimeController {
|
|
|
637
740
|
this.emitStatus(message);
|
|
638
741
|
return { type: 'command_handled' };
|
|
639
742
|
}
|
|
640
|
-
if ((this.turnController.hasActiveTurn() ||
|
|
743
|
+
if ((this.turnController.hasActiveTurn() ||
|
|
744
|
+
this.goalControlRuns.size > 0 ||
|
|
745
|
+
this.goalRuntimeActive) &&
|
|
641
746
|
(goalControl.action === 'create' || goalControl.action === 'resume')) {
|
|
642
747
|
const message = `/goal ${goalControl.action} is unavailable while Goal work is running; use /goal pause or /goal clear first.`;
|
|
643
748
|
this.emitStatus(message);
|
|
644
749
|
return { type: 'command_ignored' };
|
|
645
750
|
}
|
|
646
|
-
|
|
751
|
+
const stopsGoal = goalControl.action === 'pause' || goalControl.action === 'clear';
|
|
752
|
+
const interruptedRun = stopsGoal ? this.activeRun : null;
|
|
753
|
+
if (stopsGoal) {
|
|
647
754
|
this.turnController.clearExitIntent();
|
|
648
755
|
this.turnController.interruptActiveTurn();
|
|
649
756
|
this.runner.interrupt?.(`goal ${goalControl.action}`);
|
|
650
757
|
this.rejectPendingPermissions();
|
|
651
758
|
}
|
|
652
|
-
const run =
|
|
653
|
-
.
|
|
654
|
-
|
|
759
|
+
const run = Promise.resolve()
|
|
760
|
+
.then(async () => {
|
|
761
|
+
if (interruptedRun)
|
|
762
|
+
await interruptedRun.catch(() => undefined);
|
|
763
|
+
if (!stopsGoal)
|
|
764
|
+
await this.synchronizeSettingsAtLogicalBoundary();
|
|
765
|
+
})
|
|
766
|
+
.then(async () => {
|
|
767
|
+
this.activeGoalRuntimeTransitions += 1;
|
|
768
|
+
try {
|
|
769
|
+
return await this.runner.controlGoal(goalControl);
|
|
770
|
+
}
|
|
771
|
+
finally {
|
|
772
|
+
this.activeGoalRuntimeTransitions -= 1;
|
|
773
|
+
}
|
|
774
|
+
})
|
|
775
|
+
.then(async (result) => {
|
|
776
|
+
this.observeGoalControlResult(result);
|
|
777
|
+
this.renderGoalControl(result);
|
|
778
|
+
// Pause/clear must remain available while Goal work is active. Reconcile
|
|
779
|
+
// pending runtime-sensitive edits only after that work has stopped.
|
|
780
|
+
if (stopsGoal && result.accepted)
|
|
781
|
+
await this.synchronizeSettingsAtLogicalBoundary();
|
|
782
|
+
})
|
|
655
783
|
.catch(error => {
|
|
656
784
|
const message = error instanceof Error ? error.message : String(error);
|
|
657
785
|
this.emitAppend({ role: 'error', title: 'goal', content: message, errorLayer: 'runtime' });
|
|
@@ -673,6 +801,20 @@ class AgentRuntimeController {
|
|
|
673
801
|
});
|
|
674
802
|
this.emitStatus(summary);
|
|
675
803
|
}
|
|
804
|
+
observeGoalControlResult(result) {
|
|
805
|
+
if (!result.accepted)
|
|
806
|
+
return;
|
|
807
|
+
this.goalRuntimeActive =
|
|
808
|
+
(result.action === 'create' || result.action === 'resume') && result.scheduleContinuation;
|
|
809
|
+
}
|
|
810
|
+
observeGoalRuntimeEvent(event) {
|
|
811
|
+
if (event.type === 'goal_updated') {
|
|
812
|
+
this.goalRuntimeActive = event.goal.status === 'active';
|
|
813
|
+
}
|
|
814
|
+
else if (event.type === 'goal_cleared' || event.type === 'goal_completed') {
|
|
815
|
+
this.goalRuntimeActive = false;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
676
818
|
recordPermissionDecision(requestId, approved, scope = 'once') {
|
|
677
819
|
const pending = this.pendingPermissions.get(requestId);
|
|
678
820
|
if (!pending)
|
|
@@ -709,14 +851,38 @@ class AgentRuntimeController {
|
|
|
709
851
|
const allowed = ['allow', 'ask', 'deny'];
|
|
710
852
|
if (!allowed.includes(value))
|
|
711
853
|
return { type: 'permission_mode_invalid' };
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
854
|
+
if (this.activeRun ||
|
|
855
|
+
this.turnController.hasActiveTurn() ||
|
|
856
|
+
this.goalControlRuns.size > 0 ||
|
|
857
|
+
this.goalRuntimeActive) {
|
|
858
|
+
this.emitStatus('Tool confirmation was not changed: the runtime is busy.');
|
|
859
|
+
return { type: 'command_ignored' };
|
|
860
|
+
}
|
|
861
|
+
const describeSettings = this.options.runtime.describeSettings;
|
|
862
|
+
const updateSettings = this.options.runtime.updateSettings;
|
|
863
|
+
if (!describeSettings || !updateSettings) {
|
|
864
|
+
this.emitStatus('Tool confirmation was not changed: Settings are unavailable.');
|
|
865
|
+
return { type: 'command_ignored' };
|
|
866
|
+
}
|
|
867
|
+
const run = (async () => {
|
|
868
|
+
const before = describeSettings();
|
|
869
|
+
await updateSettings({
|
|
870
|
+
requestId: `runtime:permission-mode:${(0, crypto_1.randomUUID)()}`,
|
|
871
|
+
expectedRevision: before.revision,
|
|
872
|
+
operations: [{ op: 'set', key: 'permissions.toolConfirmation', value }],
|
|
873
|
+
});
|
|
874
|
+
this.emitStatus(`Tool confirmation → ${value}`);
|
|
875
|
+
})()
|
|
876
|
+
.catch(error => {
|
|
877
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
878
|
+
this.emitStatus(`Tool confirmation was not changed: ${reason}`);
|
|
879
|
+
})
|
|
880
|
+
.finally(() => {
|
|
881
|
+
if (this.activeRun === run)
|
|
882
|
+
this.activeRun = null;
|
|
883
|
+
});
|
|
884
|
+
this.activeRun = run;
|
|
885
|
+
return { type: 'started' };
|
|
720
886
|
}
|
|
721
887
|
rejectPendingPermissions() {
|
|
722
888
|
const pending = [...this.pendingPermissions.values()];
|
|
@@ -727,6 +893,59 @@ class AgentRuntimeController {
|
|
|
727
893
|
}
|
|
728
894
|
}
|
|
729
895
|
exports.AgentRuntimeController = AgentRuntimeController;
|
|
896
|
+
const PERMISSION_SECRET_ARG_KEY = /(?:^|[_-])(?:api[_-]?key|access[_-]?token|auth[_-]?token|accesstoken|authtoken|password|secret|authorization|cookie|credential)(?:$|[_-])/iu;
|
|
897
|
+
const MAX_PERMISSION_SNAPSHOT_DEPTH = 12;
|
|
898
|
+
function createPendingPermissionSnapshot(id, request) {
|
|
899
|
+
return Object.freeze({
|
|
900
|
+
id,
|
|
901
|
+
name: sanitizePermissionText(request.name),
|
|
902
|
+
...(request.reason === undefined ? {} : { reason: sanitizePermissionText(request.reason) }),
|
|
903
|
+
args: sanitizePermissionArgs(request.args),
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
function sanitizePermissionArgs(args) {
|
|
907
|
+
const value = sanitizePermissionValue(args, undefined, new Set(), 0);
|
|
908
|
+
return isPlainRecord(value) ? value : Object.freeze({});
|
|
909
|
+
}
|
|
910
|
+
function sanitizePermissionValue(value, key, ancestors, depth) {
|
|
911
|
+
if (key && PERMISSION_SECRET_ARG_KEY.test(key))
|
|
912
|
+
return '[REDACTED_SECRET]';
|
|
913
|
+
if (typeof value === 'string')
|
|
914
|
+
return sanitizePermissionText(value);
|
|
915
|
+
if (value === null || typeof value === 'boolean')
|
|
916
|
+
return value;
|
|
917
|
+
if (typeof value === 'number')
|
|
918
|
+
return Number.isFinite(value) ? value : null;
|
|
919
|
+
if (typeof value !== 'object')
|
|
920
|
+
return '[NON_JSON_VALUE]';
|
|
921
|
+
if (depth >= MAX_PERMISSION_SNAPSHOT_DEPTH)
|
|
922
|
+
return '[TRUNCATED]';
|
|
923
|
+
if (ancestors.has(value))
|
|
924
|
+
return '[CIRCULAR]';
|
|
925
|
+
const prototype = Object.getPrototypeOf(value);
|
|
926
|
+
if (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {
|
|
927
|
+
return '[NON_JSON_VALUE]';
|
|
928
|
+
}
|
|
929
|
+
ancestors.add(value);
|
|
930
|
+
try {
|
|
931
|
+
if (Array.isArray(value)) {
|
|
932
|
+
return Object.freeze(value.map(entry => sanitizePermissionValue(entry, undefined, ancestors, depth + 1)));
|
|
933
|
+
}
|
|
934
|
+
return Object.freeze(Object.fromEntries(Object.entries(value).map(([entryKey, entryValue]) => [
|
|
935
|
+
sanitizePermissionText(entryKey),
|
|
936
|
+
sanitizePermissionValue(entryValue, entryKey, ancestors, depth + 1),
|
|
937
|
+
])));
|
|
938
|
+
}
|
|
939
|
+
finally {
|
|
940
|
+
ancestors.delete(value);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
function sanitizePermissionText(value) {
|
|
944
|
+
return (0, style_1.sanitizeTerminalText)((0, redaction_1.redactTraceText)(value));
|
|
945
|
+
}
|
|
946
|
+
function isPlainRecord(value) {
|
|
947
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
948
|
+
}
|
|
730
949
|
function formatGoalRuntimeStatus(result) {
|
|
731
950
|
const state = result.state;
|
|
732
951
|
if (!state)
|