@myagentroam/node 0.11.35 → 0.11.37
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/dist/application/execution-lifecycle.js +54 -0
- package/dist/application/node-lifecycle.js +104 -0
- package/dist/application/node-operation-admission.js +51 -0
- package/dist/application/node-operation-contracts.js +1 -0
- package/dist/application/runner-composition.js +22 -0
- package/dist/application/session-projection-composition.js +26 -0
- package/dist/application/workspace-application.js +61 -0
- package/dist/application/workspace-composition.js +21 -0
- package/dist/capabilities.js +2 -2
- package/dist/codex-app-server.js +1 -471
- package/dist/connection/authorization.js +26 -0
- package/dist/{service → connection}/direct-transfer-service.js +1 -1
- package/dist/connection/endpoints.js +32 -0
- package/dist/connector.js +144 -252
- package/dist/database.js +34 -14
- package/dist/git-askpass.js +1 -1
- package/dist/git-execution-helper.js +1 -1
- package/dist/hosting/hosted-conversation-file-identity.js +27 -0
- package/dist/hosting/hosted-conversation-file-operations.js +44 -0
- package/dist/hosting/hosted-conversation-node-service.js +974 -0
- package/dist/hosting/hosted-conversation-runs.js +599 -0
- package/dist/hosting/hosted-conversation-templates.js +280 -0
- package/dist/hosting/hosted-conversation-uploads.js +344 -0
- package/dist/hosting/hosted-conversation-watch.js +194 -0
- package/dist/hosting/runtime-contracts.js +1 -0
- package/dist/marctl-guidance.js +1 -1
- package/dist/runner/abstract-runner.js +4 -13
- package/dist/{claude-agent-sdk.js → runner/claude/claude-agent-sdk.js} +2 -2
- package/dist/runner/claude/conversation-parser.js +2 -1
- package/dist/runner/claude/managed-run-controller.js +6 -7
- package/dist/runner/claude/message-parsers.js +2 -1
- package/dist/runner/claude/native-transcript.js +2 -1
- package/dist/runner/claude/tool-normalizer.js +1 -1
- package/dist/runner/claude-code-runner.js +2 -2
- package/dist/runner/codex/codex-app-server.js +471 -0
- package/dist/runner/codex/conversation-parser.js +4 -2
- package/dist/runner/codex/managed-run-controller.js +7 -9
- package/dist/runner/codex/native-transcript.js +1 -1
- package/dist/runner/codex/tool-normalizer.js +1 -1
- package/dist/runner/codex-runner.js +9 -27
- package/dist/runner/contracts.js +1 -0
- package/dist/runner/mar-agent/conversation-normalizer.js +2 -2
- package/dist/runner/mar-agent/history-projection.js +1 -1
- package/dist/runner/mar-agent/hosted-conversation-runtime.js +6 -10
- package/dist/runner/mar-agent/managed-run-controller.js +85 -61
- package/dist/runner/mar-agent-runner.js +1 -1
- package/dist/runner/normalization.js +42 -0
- package/dist/runner/opencode/conversation-parser.js +1 -1
- package/dist/runner/opencode/managed-run-controller.js +6 -7
- package/dist/{opencode-server.js → runner/opencode/opencode-server.js} +2 -2
- package/dist/runner/opencode/tool-normalizer.js +1 -1
- package/dist/runner/opencode-runner.js +4 -5
- package/dist/runner/runner-registry.js +4 -1
- package/dist/runtime-state.js +48 -372
- package/dist/service/computer-use-enablement-service.js +1 -1
- package/dist/service/continuous-run-coordinator.js +52 -7
- package/dist/service/conversation-history-service.js +4 -4
- package/dist/service/conversation-hosting-capability-service.js +1 -1
- package/dist/service/conversation-hosting-enablement-service.js +1 -1
- package/dist/service/conversation-hosting-lifecycle-service.js +3 -3
- package/dist/service/conversation-hosting-maintenance-service.js +1 -1
- package/dist/service/conversation-observation.js +1 -1
- package/dist/service/conversation-segment-service.js +1 -1
- package/dist/service/external-session-resume-service.js +47 -27
- package/dist/service/fake-managed-run-service.js +3 -7
- package/dist/service/git-operation-service.js +1 -1
- package/dist/service/goal-continuation-coordinator.js +14 -7
- package/dist/service/mar-agent-model-transport-test-service.js +1 -1
- package/dist/service/native-session-watch-service.js +1 -1
- package/dist/service/node-control-channel.js +1 -5
- package/dist/service/node-request-service.js +1 -1
- package/dist/service/node-terminal-channel.js +2 -1
- package/dist/service/node-workspace-coordinator.js +3 -2
- package/dist/service/notification-mcp-bridge.js +6 -2
- package/dist/service/recent-run-projection-service.js +1 -1
- package/dist/service/restart-session-restorer.js +1 -1
- package/dist/service/run-event-service.js +49 -42
- package/dist/service/run-workbench-service.js +3 -3
- package/dist/service/runner-interaction-service.js +6 -5
- package/dist/service/runner-service.js +1 -1
- package/dist/service/session-recent-activity.js +2 -1
- package/dist/service/skill-directory-service.js +1 -1
- package/dist/service/skill-install-service.js +2 -2
- package/dist/service/terminal-service.js +1 -1
- package/dist/service/workbench-event-projection.js +3 -2
- package/dist/service/workbench-event-service.js +1 -1
- package/dist/service/workspace-service.js +3 -2
- package/dist/session/attachments.js +110 -0
- package/dist/session/contracts.js +1 -0
- package/dist/{util → session}/conversation-identity.js +1 -1
- package/dist/session/input-validation.js +15 -0
- package/dist/{service → session}/native-session-projection-service.js +40 -11
- package/dist/session/pagination.js +77 -0
- package/dist/{util → session}/runner-native-session-parsers.js +2 -1
- package/dist/session/runtime/approvals.js +90 -0
- package/dist/session/runtime/conversation-projection.js +310 -0
- package/dist/session/runtime/type-guards.js +19 -0
- package/dist/{service → session}/session-catalog-service.js +5 -4
- package/dist/{service → session}/session-command-service.js +3 -3
- package/dist/{service → session}/session-identity-service.js +1 -1
- package/dist/{service → session}/session-lifecycle-service.js +18 -7
- package/dist/{service → session}/session-message-service.js +6 -5
- package/dist/{service → session}/session-presentation-service.js +1 -1
- package/dist/{service → session}/session-query-service.js +2 -2
- package/dist/{service → session}/session-schedule-service.js +2 -2
- package/dist/util/records.js +3 -0
- package/dist/workspace/contracts.js +1 -0
- package/dist/workspace/file-index.js +534 -0
- package/dist/workspace/files.js +466 -0
- package/dist/workspace/git.js +991 -0
- package/dist/workspace/path-access.js +184 -0
- package/dist/workspace/utf8.js +12 -0
- package/dist/{service → workspace}/workspace-change-service.js +45 -21
- package/dist/{service → workspace}/workspace-code-navigation-service.js +6 -6
- package/dist/{service → workspace}/workspace-file-manager-service.js +1 -1
- package/dist/{service → workspace}/workspace-file-service.js +16 -16
- package/dist/{service → workspace}/workspace-git-exclude-service.js +1 -1
- package/dist/{service → workspace}/workspace-queue-workbench-service.js +3 -2
- package/dist/{service → workspace}/workspace-session-service.js +45 -40
- package/dist/{service → workspace}/workspace-upload-service.js +28 -28
- package/dist/{service → workspace}/workspace-watch-service.js +29 -28
- package/dist/{service → workspace}/workspace-workbench-service.js +4 -3
- package/package.json +4 -4
- package/dist/service/hosted-conversation-node-service.js +0 -2252
- package/dist/service/run-domain-state.js +0 -4
- package/dist/service/session-domain-state.js +0 -9
- package/dist/service/workspace-domain-state.js +0 -41
- package/dist/util/node-operation-parsers.js +0 -320
- package/dist/workspace.js +0 -2168
- /package/dist/{connector → application}/node-connector-options.js +0 -0
- /package/dist/{util → connection}/node-operation-data.js +0 -0
- /package/dist/{connector → connection}/node-operation-router.js +0 -0
- /package/dist/{service → hosting}/hosted-conversation-sandbox-profile.js +0 -0
- /package/dist/{service → hosting}/hosted-conversation-store.js +0 -0
- /package/dist/{util → mcp}/secret-environment.js +0 -0
- /package/dist/{claude-channel.js → runner/claude/claude-channel.js} +0 -0
- /package/dist/{util → runner}/personal-instructions.js +0 -0
- /package/dist/{util → runner}/runner-error.js +0 -0
- /package/dist/{service/conversation-work-process.js → session/runtime/work-process.js} +0 -0
- /package/dist/{service → session}/session-context-service.js +0 -0
- /package/dist/{util → workspace}/git-credential-client.js +0 -0
- /package/dist/{service → workspace}/workspace-content-search-service.js +0 -0
- /package/dist/{service → workspace}/workspace-watch-snapshot-service.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isPlainRecord } from '../util/
|
|
1
|
+
import { isPlainRecord } from '../util/records.js';
|
|
2
2
|
import { composeConversationRuntimePage, convergeConversationWatchPage } from './conversation-history-service.js';
|
|
3
3
|
const INITIAL_TURN_LIMIT = 30;
|
|
4
4
|
const EMITTED_TURN_LIMIT = 10;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { projectConversationWorkProcesses } from '
|
|
1
|
+
import { projectConversationWorkProcesses } from '../session/runtime/work-process.js';
|
|
2
2
|
const MAX_INITIAL_TURN_PAGE_SIZE = 30;
|
|
3
3
|
function conversationSegmentPrefix(turn) {
|
|
4
4
|
const user = turn.items.find((item) => item.kind === 'user_message');
|
|
@@ -1,25 +1,45 @@
|
|
|
1
1
|
const RESUME_FAILURE_TTL_MS = 30 * 60_000;
|
|
2
2
|
export class ExternalSessionResumeService {
|
|
3
3
|
options;
|
|
4
|
+
externalActivity = new Map();
|
|
5
|
+
resumedByDirectId = new Map();
|
|
6
|
+
resumeFailures = new Map();
|
|
7
|
+
messageResumeFailures = new Map();
|
|
8
|
+
resumeFailureDetails = new Map();
|
|
9
|
+
failureTimers = new Map();
|
|
10
|
+
activity(sessionId) {
|
|
11
|
+
return this.externalActivity.get(sessionId);
|
|
12
|
+
}
|
|
4
13
|
transitions = new Set();
|
|
5
14
|
resumeTasks = new Map();
|
|
6
15
|
constructor(options) {
|
|
7
16
|
this.options = options;
|
|
8
17
|
}
|
|
18
|
+
async close() {
|
|
19
|
+
await Promise.allSettled([...this.resumeTasks.values()]);
|
|
20
|
+
for (const timer of this.failureTimers.values())
|
|
21
|
+
clearTimeout(timer);
|
|
22
|
+
this.failureTimers.clear();
|
|
23
|
+
this.externalActivity.clear();
|
|
24
|
+
this.resumedByDirectId.clear();
|
|
25
|
+
this.resumeFailures.clear();
|
|
26
|
+
this.messageResumeFailures.clear();
|
|
27
|
+
this.resumeFailureDetails.clear();
|
|
28
|
+
}
|
|
9
29
|
setActivity(sessionId, activity) {
|
|
10
|
-
this.
|
|
30
|
+
this.externalActivity.set(sessionId, activity);
|
|
11
31
|
}
|
|
12
32
|
forgetSessions(directIds, projectionIds) {
|
|
13
33
|
for (const directId of directIds) {
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
34
|
+
this.externalActivity.delete(directId);
|
|
35
|
+
this.resumedByDirectId.delete(directId);
|
|
16
36
|
this.clearFailure(directId);
|
|
17
37
|
}
|
|
18
|
-
for (const [directId, resumedId] of this.
|
|
38
|
+
for (const [directId, resumedId] of this.resumedByDirectId)
|
|
19
39
|
if (projectionIds.has(resumedId))
|
|
20
|
-
this.
|
|
40
|
+
this.resumedByDirectId.delete(directId);
|
|
21
41
|
for (const projectionId of projectionIds)
|
|
22
|
-
this.
|
|
42
|
+
this.externalActivity.delete(projectionId);
|
|
23
43
|
}
|
|
24
44
|
transitioning(sessionId) {
|
|
25
45
|
return this.transitions.has(sessionId);
|
|
@@ -40,13 +60,13 @@ export class ExternalSessionResumeService {
|
|
|
40
60
|
}
|
|
41
61
|
async performResume(external) {
|
|
42
62
|
this.clearFailure(external.id);
|
|
43
|
-
const priorId = this.
|
|
63
|
+
const priorId = this.resumedByDirectId.get(external.id);
|
|
44
64
|
const prior = priorId === undefined ? undefined : this.options.runtime.getAgentSession(priorId);
|
|
45
65
|
if (prior !== undefined)
|
|
46
66
|
return this.options.ensureConfiguration(prior);
|
|
47
67
|
const runner = this.options.runners.product(external.runner);
|
|
48
68
|
if (runner === undefined) {
|
|
49
|
-
this.
|
|
69
|
+
this.externalActivity.set(external.id, 'IDLE');
|
|
50
70
|
this.setFailure(external.id, 'RUNNER_UNAVAILABLE');
|
|
51
71
|
return undefined;
|
|
52
72
|
}
|
|
@@ -64,7 +84,7 @@ export class ExternalSessionResumeService {
|
|
|
64
84
|
projectionFor: this.options.projectionFor,
|
|
65
85
|
managedAliasFor: this.options.managedAliasFor,
|
|
66
86
|
currentResumed: (sessionId) => {
|
|
67
|
-
const resumedId = this.
|
|
87
|
+
const resumedId = this.resumedByDirectId.get(sessionId);
|
|
68
88
|
return resumedId === undefined
|
|
69
89
|
? undefined
|
|
70
90
|
: this.options.runtime.getAgentSession(resumedId);
|
|
@@ -104,24 +124,24 @@ export class ExternalSessionResumeService {
|
|
|
104
124
|
releaseMutation();
|
|
105
125
|
}
|
|
106
126
|
if (result.activity !== undefined)
|
|
107
|
-
this.
|
|
127
|
+
this.externalActivity.set(external.id, result.activity);
|
|
108
128
|
else if (result.failureCode === 'RUNNER_UNAVAILABLE')
|
|
109
|
-
this.
|
|
129
|
+
this.externalActivity.set(external.id, 'IDLE');
|
|
110
130
|
if (result.session !== undefined) {
|
|
111
|
-
this.
|
|
131
|
+
this.resumedByDirectId.set(external.id, result.session.id);
|
|
112
132
|
return result.session;
|
|
113
133
|
}
|
|
114
134
|
this.setFailure(external.id, result.failureCode ?? 'SESSION_RESUME_REJECTED', result.failureDetail);
|
|
115
|
-
this.
|
|
135
|
+
this.messageResumeFailures.set(external.id, result.messageFailureCode ?? result.failureCode ?? 'SESSION_RESUME_REJECTED');
|
|
116
136
|
return undefined;
|
|
117
137
|
}
|
|
118
138
|
failure(sessionId) {
|
|
119
|
-
const code = this.
|
|
120
|
-
const detail = this.
|
|
139
|
+
const code = this.resumeFailures.get(sessionId) ?? 'SESSION_RESUME_REJECTED';
|
|
140
|
+
const detail = this.resumeFailureDetails.get(sessionId);
|
|
121
141
|
return detail === undefined ? { code } : { code, detail };
|
|
122
142
|
}
|
|
123
143
|
async resolveForMessage(sessionId) {
|
|
124
|
-
const resumedId = this.
|
|
144
|
+
const resumedId = this.resumedByDirectId.get(sessionId);
|
|
125
145
|
const current = this.options.runtime.getAgentSession(resumedId ?? sessionId) ??
|
|
126
146
|
(await this.options.resolve(sessionId));
|
|
127
147
|
if (current === undefined)
|
|
@@ -131,31 +151,31 @@ export class ExternalSessionResumeService {
|
|
|
131
151
|
const resumed = await this.resume(current);
|
|
132
152
|
if (resumed !== undefined)
|
|
133
153
|
return resumed;
|
|
134
|
-
if (this.
|
|
154
|
+
if (this.externalActivity.get(current.id) === 'BUSY')
|
|
135
155
|
throw new Error('EXTERNAL_SESSION_ACTIVE');
|
|
136
|
-
throw new Error(this.
|
|
156
|
+
throw new Error(this.messageResumeFailures.get(current.id) ?? this.failure(current.id).code);
|
|
137
157
|
}
|
|
138
158
|
async acceptForMessage(sessionId) {
|
|
139
159
|
return { session: await this.resolveForMessage(sessionId) };
|
|
140
160
|
}
|
|
141
161
|
clearFailure(sessionId) {
|
|
142
|
-
const timer = this.
|
|
162
|
+
const timer = this.failureTimers.get(sessionId);
|
|
143
163
|
if (timer !== undefined)
|
|
144
164
|
clearTimeout(timer);
|
|
145
|
-
this.
|
|
146
|
-
this.
|
|
147
|
-
this.
|
|
148
|
-
this.
|
|
165
|
+
this.failureTimers.delete(sessionId);
|
|
166
|
+
this.resumeFailures.delete(sessionId);
|
|
167
|
+
this.resumeFailureDetails.delete(sessionId);
|
|
168
|
+
this.messageResumeFailures.delete(sessionId);
|
|
149
169
|
}
|
|
150
170
|
setFailure(sessionId, code, detail) {
|
|
151
171
|
this.clearFailure(sessionId);
|
|
152
|
-
this.
|
|
172
|
+
this.resumeFailures.set(sessionId, code);
|
|
153
173
|
if (detail === undefined)
|
|
154
|
-
this.
|
|
174
|
+
this.resumeFailureDetails.delete(sessionId);
|
|
155
175
|
else
|
|
156
|
-
this.
|
|
176
|
+
this.resumeFailureDetails.set(sessionId, detail);
|
|
157
177
|
const timer = setTimeout(() => this.clearFailure(sessionId), RESUME_FAILURE_TTL_MS);
|
|
158
178
|
timer.unref();
|
|
159
|
-
this.
|
|
179
|
+
this.failureTimers.set(sessionId, timer);
|
|
160
180
|
}
|
|
161
181
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isTerminalRunStatus } from '../util/node-operation-parsers.js';
|
|
2
1
|
/** Test-only managed Run adapter; production Runner paths never depend on it. */
|
|
3
2
|
export class FakeManagedRunService {
|
|
4
3
|
options;
|
|
@@ -7,7 +6,7 @@ export class FakeManagedRunService {
|
|
|
7
6
|
}
|
|
8
7
|
start(envelope) {
|
|
9
8
|
const payload = envelope.payload;
|
|
10
|
-
if (typeof payload.runId !== 'string' || this.options.
|
|
9
|
+
if (typeof payload.runId !== 'string' || this.options.runtime.isExecutionActive(payload.runId))
|
|
11
10
|
return;
|
|
12
11
|
const runId = payload.runId;
|
|
13
12
|
const cwd = typeof payload.cwd === 'string' ? payload.cwd : undefined;
|
|
@@ -25,14 +24,11 @@ export class FakeManagedRunService {
|
|
|
25
24
|
cwd
|
|
26
25
|
});
|
|
27
26
|
}
|
|
28
|
-
this.options.
|
|
27
|
+
this.options.runtime.executionAccepted(runId);
|
|
29
28
|
void this.options.runner
|
|
30
29
|
.start(runId, this.options.script(payload.input, runId), {
|
|
31
30
|
event: (eventType, eventPayload, status) => {
|
|
32
31
|
this.options.emitRun(runId, eventType, eventPayload, status);
|
|
33
|
-
if (status !== undefined && isTerminalRunStatus(status)) {
|
|
34
|
-
this.options.state.active.delete(runId);
|
|
35
|
-
}
|
|
36
32
|
},
|
|
37
33
|
approval: (approvalId, approvalPayload, expiresAt) => {
|
|
38
34
|
try {
|
|
@@ -55,6 +51,6 @@ export class FakeManagedRunService {
|
|
|
55
51
|
},
|
|
56
52
|
disconnect: this.options.disconnect
|
|
57
53
|
})
|
|
58
|
-
.finally(() => this.options.
|
|
54
|
+
.finally(() => this.options.runtime.executionReleased(runId));
|
|
59
55
|
}
|
|
60
56
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
2
|
import { personalGitRuntimeSchema } from '@myagentroam/protocol';
|
|
3
|
-
import { parseSecretEnvironment } from '../
|
|
3
|
+
import { parseSecretEnvironment } from '../mcp/secret-environment.js';
|
|
4
4
|
export const gitOperationEnvironment = new AsyncLocalStorage();
|
|
5
5
|
/** Binds authenticated operations to the same lease mechanism as Runner queues. */
|
|
6
6
|
export class GitOperationService {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { composerVisibleText } from '@myagentroam/protocol';
|
|
2
2
|
import { nodeLog } from '../operational.js';
|
|
3
|
-
import { isPlainRecord } from '../util/
|
|
3
|
+
import { isPlainRecord } from '../util/records.js';
|
|
4
4
|
import { safeErrorCode } from '../util/safe-error.js';
|
|
5
5
|
import { NODE_MCP } from '../mcp/naming.js';
|
|
6
6
|
import { composerResourceInputTags } from './composer-message-input.js';
|
|
@@ -77,8 +77,10 @@ export class GoalContinuationCoordinator {
|
|
|
77
77
|
return;
|
|
78
78
|
if (permissionStop !== undefined) {
|
|
79
79
|
this.retireGoalContinuation(pending.sessionId);
|
|
80
|
-
this.options
|
|
81
|
-
|
|
80
|
+
const changed = this.options
|
|
81
|
+
.queue()
|
|
82
|
+
.removeGoalQueue(pending.sessionId, undefined, undefined, false);
|
|
83
|
+
return changed ? { queueChangedSessionId: pending.sessionId } : undefined;
|
|
82
84
|
}
|
|
83
85
|
const disposition = this.options.goals.recordExecutionResult(pending.sessionId, {
|
|
84
86
|
failed: status === 'FAILED',
|
|
@@ -87,12 +89,17 @@ export class GoalContinuationCoordinator {
|
|
|
87
89
|
if (disposition === 'blocked' || disposition === 'completed') {
|
|
88
90
|
this.nativeGoalBindings.delete(pending.goal.id);
|
|
89
91
|
this.retireGoalContinuation(pending.sessionId);
|
|
90
|
-
this.options
|
|
92
|
+
const changed = this.options
|
|
93
|
+
.queue()
|
|
94
|
+
.removeGoalQueue(pending.sessionId, undefined, undefined, false);
|
|
91
95
|
const terminalGoal = this.options.goals.get(pending.sessionId);
|
|
92
96
|
const session = this.options.runtime.getAgentSession(pending.sessionId);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
return {
|
|
98
|
+
...(terminalGoal !== undefined && session !== undefined
|
|
99
|
+
? { goalUpdate: { session, goal: terminalGoal } }
|
|
100
|
+
: {}),
|
|
101
|
+
...(changed ? { queueChangedSessionId: pending.sessionId } : {})
|
|
102
|
+
};
|
|
96
103
|
}
|
|
97
104
|
if (status !== 'FAILED' || started)
|
|
98
105
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { testAgentModelTransport } from '@myagentroam/agent';
|
|
2
2
|
import { marAgentModelTransportTestInputSchema, marAgentModelTransportTestResultSchema } from '@myagentroam/protocol';
|
|
3
|
-
import { runnerErrorProjection } from '../
|
|
3
|
+
import { runnerErrorProjection } from '../runner/runner-error.js';
|
|
4
4
|
export class MarAgentModelTransportTestService {
|
|
5
5
|
options;
|
|
6
6
|
#timeoutMs;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isPlainRecord } from '../util/
|
|
1
|
+
import { isPlainRecord } from '../util/records.js';
|
|
2
2
|
import { ConversationObservation } from './conversation-observation.js';
|
|
3
3
|
import { safeErrorCode } from '../util/safe-error.js';
|
|
4
4
|
import { SessionWatchSlotCoordinator } from './session-watch-slot-coordinator.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
2
|
import { createEnvelope } from '@myagentroam/protocol';
|
|
3
3
|
import { ControlOutboundScheduler } from '../control-outbound-scheduler.js';
|
|
4
|
-
import { nodeConnectEndpoint } from '../
|
|
4
|
+
import { nodeConnectEndpoint } from '../connection/endpoints.js';
|
|
5
5
|
export class NodeControlChannel {
|
|
6
6
|
options;
|
|
7
7
|
socket;
|
|
@@ -50,10 +50,6 @@ export class NodeControlChannel {
|
|
|
50
50
|
connected() {
|
|
51
51
|
return this.socket?.readyState === WebSocket.OPEN;
|
|
52
52
|
}
|
|
53
|
-
/** Keeps transport injection at the transport boundary for contract tests. */
|
|
54
|
-
replaceSocketForTesting(socket) {
|
|
55
|
-
this.socket = socket;
|
|
56
|
-
}
|
|
57
53
|
close(code, reason) {
|
|
58
54
|
this.socket?.close(code, reason);
|
|
59
55
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { nodeLog } from '../operational.js';
|
|
2
|
-
import { validUserAuthorization } from '../
|
|
2
|
+
import { validUserAuthorization } from '../connection/authorization.js';
|
|
3
3
|
import { safePublicError } from '../util/safe-error.js';
|
|
4
4
|
/** Validates and executes the closed Admin-facing Node operation envelope. */
|
|
5
5
|
export class NodeRequestService {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import WebSocket from 'ws';
|
|
2
2
|
import { terminalDataFrameSchema } from '@myagentroam/protocol';
|
|
3
|
-
import { nodeTerminalConnectEndpoint
|
|
3
|
+
import { nodeTerminalConnectEndpoint } from '../connection/endpoints.js';
|
|
4
|
+
import { isPlainRecord } from '../util/records.js';
|
|
4
5
|
import { TerminalRelayState } from './terminal-relay-state.js';
|
|
5
6
|
import { TerminalRelaySender } from '@myagentroam/marctl/src/terminal-relay-sender.mjs';
|
|
6
7
|
export class NodeTerminalChannel {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { realpath } from 'node:fs/promises';
|
|
2
2
|
import { nodeLog } from '../operational.js';
|
|
3
|
-
import { inspectWorkspace
|
|
4
|
-
import {
|
|
3
|
+
import { inspectWorkspace } from '../workspace/git.js';
|
|
4
|
+
import { normalizeWorkspacePath } from '../workspace/path-access.js';
|
|
5
|
+
import { ensureWorkspaceGitExclude } from '../workspace/workspace-git-exclude-service.js';
|
|
5
6
|
/** Coordinates Workspace invalidation, inspection and persisted Terminal summaries. */
|
|
6
7
|
export class NodeWorkspaceCoordinator {
|
|
7
8
|
options;
|
|
@@ -7,7 +7,7 @@ import { tmpdir } from 'node:os';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { notificationInputSchema, notificationChannelsRequestSchema, mailNotificationRequestSchema } from '@myagentroam/protocol';
|
|
10
|
-
import { sessionGroup } from '
|
|
10
|
+
import { sessionGroup } from '../session/session-presentation-service.js';
|
|
11
11
|
export class NotificationMcpBridge {
|
|
12
12
|
resolve;
|
|
13
13
|
send;
|
|
@@ -146,7 +146,11 @@ export class NotificationMcpBridge {
|
|
|
146
146
|
typeof callId !== 'string')
|
|
147
147
|
throw new Error('MAIL_INPUT_INVALID');
|
|
148
148
|
const parsed = mailNotificationRequestSchema.safeParse({
|
|
149
|
-
|
|
149
|
+
executionId: current.executionId,
|
|
150
|
+
sessionId: current.sessionId,
|
|
151
|
+
workspaceId: current.workspaceId,
|
|
152
|
+
userId: current.userId,
|
|
153
|
+
source: current.source,
|
|
150
154
|
templateId: templateId ?? '',
|
|
151
155
|
...(title === undefined ? {} : { title }),
|
|
152
156
|
...(recipientEmail === undefined ? {} : { recipientEmail }),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sessionGroup } from '
|
|
1
|
+
import { sessionGroup } from '../session/session-presentation-service.js';
|
|
2
2
|
import { composerVisibleText } from '@myagentroam/protocol';
|
|
3
3
|
const TERMINAL_TTL_MS = 12 * 60 * 60_000;
|
|
4
4
|
const CLEANUP_INTERVAL_MS = 5 * 60_000;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseComposerTags, serializeComposerTag } from '@myagentroam/protocol';
|
|
2
|
-
import { parseMessageAttachments } from '../
|
|
2
|
+
import { parseMessageAttachments } from '../session/attachments.js';
|
|
3
3
|
import { RUNNER_EXECUTION_CONTEXT } from '../runner/execution-context.js';
|
|
4
4
|
import { RESTART_NOTICE } from './planned-restart-handoff.js';
|
|
5
5
|
/** Rebuild inputs through the existing preparation and FIFO boundary. */
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { sessionGroup } from '
|
|
1
|
+
import { sessionGroup } from '../session/session-presentation-service.js';
|
|
2
2
|
import { permissionStopSchema, runPerformanceSchema } from '@myagentroam/protocol';
|
|
3
3
|
import { nodeLog } from '../operational.js';
|
|
4
|
-
import { isPlainRecord
|
|
4
|
+
import { isPlainRecord } from '../util/records.js';
|
|
5
|
+
import { isTerminalRunStatus } from '../session/runtime/type-guards.js';
|
|
5
6
|
const COALESCE_MS = 200;
|
|
6
7
|
const MAX_BATCH_CHARS = 16_384;
|
|
7
8
|
export class RunEventService {
|
|
@@ -18,7 +19,7 @@ export class RunEventService {
|
|
|
18
19
|
const parsed = runPerformanceSchema.safeParse({ ...payload, runId: run.id });
|
|
19
20
|
if (parsed.success && this.options.runtime.updateRunPerformance(runId, parsed.data)) {
|
|
20
21
|
this.flushText(runId);
|
|
21
|
-
this.
|
|
22
|
+
this.emitWorkbench('conversation', {
|
|
22
23
|
sessionId: run.sessionId,
|
|
23
24
|
performance: parsed.data
|
|
24
25
|
});
|
|
@@ -35,6 +36,13 @@ export class RunEventService {
|
|
|
35
36
|
this.flushText(runId);
|
|
36
37
|
this.emitNow(runId, eventType, payload, status);
|
|
37
38
|
}
|
|
39
|
+
emitWorkbench(category, payload) {
|
|
40
|
+
if (category === 'conversation' && isPlainRecord(payload) && 'turn' in payload) {
|
|
41
|
+
this.options.emitWorkbench(category, { turn: payload.turn });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.options.emitWorkbench(category, payload);
|
|
45
|
+
}
|
|
38
46
|
clear() {
|
|
39
47
|
for (const pending of this.pendingText.values())
|
|
40
48
|
clearTimeout(pending.timer);
|
|
@@ -104,59 +112,58 @@ export class RunEventService {
|
|
|
104
112
|
if (status === 'FAILED')
|
|
105
113
|
this.options.metrics.runnerFailed();
|
|
106
114
|
let recorded = undefined;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
115
|
+
let finalStatus;
|
|
116
|
+
let manuallyInterrupted = false;
|
|
117
|
+
if (terminalExecution) {
|
|
118
|
+
const parsedStop = isPlainRecord(payload)
|
|
119
|
+
? permissionStopSchema.safeParse(payload.permissionStop)
|
|
120
|
+
: undefined;
|
|
121
|
+
const result = this.options.acceptExecutionTerminal({
|
|
122
|
+
executionId,
|
|
110
123
|
sequence: event.sequence,
|
|
111
124
|
eventType,
|
|
112
125
|
payload,
|
|
113
|
-
|
|
126
|
+
status: status,
|
|
127
|
+
...(parsedStop?.success ? { permissionStop: parsedStop.data } : {})
|
|
114
128
|
});
|
|
129
|
+
recorded = result.recorded;
|
|
130
|
+
if (recorded === undefined)
|
|
131
|
+
return;
|
|
132
|
+
finalStatus = result.finalStatus;
|
|
133
|
+
manuallyInterrupted = result.manuallyInterrupted;
|
|
134
|
+
if (result.queueChangedSessionId !== undefined)
|
|
135
|
+
this.options.publishQueueChange(result.queueChangedSessionId);
|
|
136
|
+
if (result.goalUpdate !== undefined)
|
|
137
|
+
this.options.publishGoalUpdate(result.goalUpdate);
|
|
115
138
|
}
|
|
116
|
-
|
|
117
|
-
|
|
139
|
+
else {
|
|
140
|
+
try {
|
|
141
|
+
recorded = this.options.runtime.appendRunEvent({
|
|
142
|
+
runId: executionId,
|
|
143
|
+
sequence: event.sequence,
|
|
144
|
+
eventType,
|
|
145
|
+
payload,
|
|
146
|
+
...(status === undefined ? {} : { status })
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* A stale Runner callback may race process-local Run cleanup. */
|
|
151
|
+
}
|
|
118
152
|
}
|
|
119
153
|
if (eventType === 'run.started' || eventType === 'run.running')
|
|
120
154
|
this.options.executionStarted?.(executionId);
|
|
121
155
|
if (!terminalExecution)
|
|
122
156
|
this.options.refreshAttachments?.(run.sessionId);
|
|
123
|
-
let finalStatus;
|
|
124
|
-
let manuallyInterrupted = false;
|
|
125
|
-
if (terminalCurrentExecution) {
|
|
126
|
-
const parsedStop = isPlainRecord(payload)
|
|
127
|
-
? permissionStopSchema.safeParse(payload.permissionStop)
|
|
128
|
-
: undefined;
|
|
129
|
-
const permissionStop = parsedStop?.success ? parsedStop.data : undefined;
|
|
130
|
-
if (permissionStop !== undefined)
|
|
131
|
-
this.options.runtime.pauseSessionQueue(run.sessionId);
|
|
132
|
-
this.options.executionTerminating?.(executionId, status, permissionStop);
|
|
133
|
-
this.options.state.active.delete(executionId);
|
|
134
|
-
const interrupted = this.options.state.interruptRequested.delete(executionId);
|
|
135
|
-
manuallyInterrupted = interrupted;
|
|
136
|
-
const queue = this.options.runtime.sessionQueue(run.sessionId);
|
|
137
|
-
const continues = run.status !== 'CANCELLING' &&
|
|
138
|
-
permissionStop === undefined &&
|
|
139
|
-
((!queue.paused && queue.itemIds.length > 0) ||
|
|
140
|
-
this.options.keepRunActive?.(run.sessionId) === true);
|
|
141
|
-
if (!continues) {
|
|
142
|
-
finalStatus =
|
|
143
|
-
status === 'CANCELLED' || interrupted ? 'INTERRUPTED' : status;
|
|
144
|
-
if (finalStatus === 'SUCCEEDED' ||
|
|
145
|
-
finalStatus === 'FAILED' ||
|
|
146
|
-
finalStatus === 'INTERRUPTED')
|
|
147
|
-
this.options.runtime.finishRun(runId, finalStatus);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
157
|
const publicStatus = terminalExecution ? finalStatus : status;
|
|
151
158
|
const notificationPayload = this.notificationPayload(runId, eventType, payload, publicStatus, manuallyInterrupted || !targetsCurrentTurn);
|
|
152
159
|
if (publicStatus !== undefined) {
|
|
153
160
|
const currentRun = this.options.runtime.getRun(runId);
|
|
154
|
-
this.
|
|
161
|
+
this.emitWorkbench('run', { run: currentRun });
|
|
155
162
|
const session = currentRun === undefined
|
|
156
163
|
? undefined
|
|
157
164
|
: this.options.runtime.getAgentSession(currentRun.sessionId);
|
|
158
165
|
if (session !== undefined)
|
|
159
|
-
this.
|
|
166
|
+
this.emitWorkbench('session', { session: this.options.presentSession(session) });
|
|
160
167
|
}
|
|
161
168
|
const createdTurn = targetsCurrentTurn && targetTurn === undefined && currentTurn === undefined
|
|
162
169
|
? this.options.runtime.conversationTurnForRun(runId)
|
|
@@ -169,7 +176,7 @@ export class RunEventService {
|
|
|
169
176
|
(previousGroups.get(item.id)?.id !== item.processGroup?.id ||
|
|
170
177
|
previousGroups.get(item.id)?.isStart !== item.processGroup?.isStart));
|
|
171
178
|
if (targetsCurrentTurn)
|
|
172
|
-
this.
|
|
179
|
+
this.emitWorkbench('conversation', createdTurn === undefined && !correctedGroups
|
|
173
180
|
? {
|
|
174
181
|
event: {
|
|
175
182
|
...event,
|
|
@@ -181,7 +188,7 @@ export class RunEventService {
|
|
|
181
188
|
else {
|
|
182
189
|
const projectedTurn = this.options.runtime.conversationTurnForExecution(executionId);
|
|
183
190
|
if (projectedTurn !== undefined)
|
|
184
|
-
this.
|
|
191
|
+
this.emitWorkbench('conversation', { turn: projectedTurn });
|
|
185
192
|
}
|
|
186
193
|
const occurredAt = recorded?.createdAt ?? Date.now();
|
|
187
194
|
const terminalNotification = notificationPayload !== undefined && terminalCurrentExecution && finalStatus !== undefined;
|
|
@@ -198,7 +205,7 @@ export class RunEventService {
|
|
|
198
205
|
targetTurn?.items.some((item) => item.status === 'PENDING' || item.status === 'IN_PROGRESS'))) {
|
|
199
206
|
const turn = this.options.runtime.conversationTurnForRun(runId);
|
|
200
207
|
if (turn !== undefined)
|
|
201
|
-
this.
|
|
208
|
+
this.emitWorkbench('conversation', { turn });
|
|
202
209
|
}
|
|
203
210
|
this.options.cleanupAttachments(executionId);
|
|
204
211
|
this.options.expireImages(executionId);
|
|
@@ -225,7 +232,7 @@ export class RunEventService {
|
|
|
225
232
|
}
|
|
226
233
|
emitNotification(runId, event, payload, occurredAt) {
|
|
227
234
|
nodeLog('run.event', { runId, eventType: 'notification' });
|
|
228
|
-
this.
|
|
235
|
+
this.emitWorkbench('conversation', {
|
|
229
236
|
event: {
|
|
230
237
|
runId,
|
|
231
238
|
sequence: event.sequence,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { modelResourceReadInputSchema, runImageReadInputSchema } from '@myagentroam/protocol';
|
|
2
|
-
import { nodeOperationData } from '../
|
|
3
|
-
import { isTerminalRunStatus } from '../
|
|
4
|
-
import { isPlainRecord } from '../util/
|
|
2
|
+
import { nodeOperationData } from '../connection/node-operation-data.js';
|
|
3
|
+
import { isTerminalRunStatus } from '../session/runtime/type-guards.js';
|
|
4
|
+
import { isPlainRecord } from '../util/records.js';
|
|
5
5
|
import { isHostedConversationImageRunId } from '../runner/mar-agent/generated-images.js';
|
|
6
6
|
import { assertRunOwner } from './run-ownership-policy.js';
|
|
7
7
|
import { imagePreviews } from './image-preview-service.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { denyPermission } from '../claude-agent-sdk.js';
|
|
2
|
-
import { boundedConversationItemId
|
|
1
|
+
import { denyPermission } from '../runner/claude/claude-agent-sdk.js';
|
|
2
|
+
import { boundedConversationItemId } from '../runner/normalization.js';
|
|
3
|
+
import { isTerminalRunStatus } from '../session/runtime/type-guards.js';
|
|
3
4
|
import { claudeUserInputQuestions } from '../runner/claude/conversation-parser.js';
|
|
4
5
|
export class RunnerInteractionService {
|
|
5
6
|
options;
|
|
@@ -223,7 +224,6 @@ export class RunnerInteractionService {
|
|
|
223
224
|
finally {
|
|
224
225
|
codex.execution.runs.delete(runId);
|
|
225
226
|
codex.releaseEnvironment(runId);
|
|
226
|
-
this.options.state.active.delete(runId);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
respondUserInput(runId, requestId, rawAnswers) {
|
|
@@ -260,13 +260,14 @@ export class RunnerInteractionService {
|
|
|
260
260
|
if (run === undefined)
|
|
261
261
|
return false;
|
|
262
262
|
if (run.status === 'CANCELLING') {
|
|
263
|
-
const status = this.options.
|
|
263
|
+
const status = this.options.runtime.isExecutionInterruptRequested(runId)
|
|
264
|
+
? 'INTERRUPTED'
|
|
265
|
+
: 'CANCELLED';
|
|
264
266
|
this.options.emitRun(runId, 'run.completed', { status }, status);
|
|
265
267
|
}
|
|
266
268
|
else if (!isTerminalRunStatus(run.status))
|
|
267
269
|
return false;
|
|
268
270
|
this.options.codex().execution.runs.delete(runId);
|
|
269
|
-
this.options.state.active.delete(runId);
|
|
270
271
|
return true;
|
|
271
272
|
}
|
|
272
273
|
respondCodexUserInput(runId, requestId, rawAnswers) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { runnerDefaultConfigurationSchema } from '@myagentroam/protocol';
|
|
2
|
-
import { parseSecretEnvironment } from '../
|
|
2
|
+
import { parseSecretEnvironment } from '../mcp/secret-environment.js';
|
|
3
3
|
export class RunnerService {
|
|
4
4
|
database;
|
|
5
5
|
capabilities;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { isPlainRecord
|
|
1
|
+
import { isPlainRecord } from '../util/records.js';
|
|
2
|
+
import { isTerminalRunStatus } from '../session/runtime/type-guards.js';
|
|
2
3
|
/** Projects only already-observed, process-local public facts. Never reads native history. */
|
|
3
4
|
function activity(runtime, sessionId) {
|
|
4
5
|
const candidate = runtime.activeSessionRun(sessionId);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { lstat, open, readdir, readlink, realpath } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { skillInstallMetadataSchema } from '@myagentroam/protocol';
|
|
4
|
-
import { hasBrokenWorkspaceSkillGitExclude } from '
|
|
4
|
+
import { hasBrokenWorkspaceSkillGitExclude } from '../workspace/workspace-git-exclude-service.js';
|
|
5
5
|
const MAX_METADATA_BYTES = 64 * 1024;
|
|
6
6
|
const SKILL_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
7
7
|
const WINDOWS_DEVICE_NAME = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])$/u;
|
|
@@ -4,8 +4,8 @@ import { promisify } from 'node:util';
|
|
|
4
4
|
import { lstat, mkdir, readFile, readdir, readlink, realpath, rename, rm, symlink, writeFile } from 'node:fs/promises';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { skillInstallMetadataSchema } from '@myagentroam/protocol';
|
|
7
|
-
import { GitCommandError, resolveWorkspaceGitRoot } from '../workspace.js';
|
|
8
|
-
import { rewriteWorkspaceGitExclude, updateWorkspaceSkillGitExclude } from '
|
|
7
|
+
import { GitCommandError, resolveWorkspaceGitRoot } from '../workspace/git.js';
|
|
8
|
+
import { rewriteWorkspaceGitExclude, updateWorkspaceSkillGitExclude } from '../workspace/workspace-git-exclude-service.js';
|
|
9
9
|
export class SkillInstallService {
|
|
10
10
|
async recoverNodeHome(home) {
|
|
11
11
|
const agentsRoot = path.join(home, '.agents', 'skills');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { conversationSegmentIdentityForItem, conversationSegments } from './conversation-segment-service.js';
|
|
2
|
-
import { runConversationItemId } from '../runtime-
|
|
3
|
-
import { isNodeAgentRun, isNodeConversationTurn
|
|
2
|
+
import { runConversationItemId } from '../session/runtime/conversation-projection.js';
|
|
3
|
+
import { isNodeAgentRun, isNodeConversationTurn } from '../session/runtime/type-guards.js';
|
|
4
|
+
import { isPlainRecord } from '../util/records.js';
|
|
4
5
|
export function workbenchPayloadSessionId(getRun, category, payload) {
|
|
5
6
|
if (!isPlainRecord(payload))
|
|
6
7
|
return undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createEnvelope } from '@myagentroam/protocol';
|
|
2
|
-
import { isPlainRecord } from '../util/
|
|
2
|
+
import { isPlainRecord } from '../util/records.js';
|
|
3
3
|
import { projectWorkbenchPayload, workbenchPayloadSessionId } from './workbench-event-projection.js';
|
|
4
4
|
export class WorkbenchEventService {
|
|
5
5
|
options;
|