@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
package/dist/runtime-state.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { RuntimeApprovals } from './session/runtime/approvals.js';
|
|
3
|
+
import { projectConversationEvent, conversationItemFromEvent, activeConversationItem, completedStatusForRun } from './session/runtime/conversation-projection.js';
|
|
3
4
|
import { nodeLog } from './operational.js';
|
|
4
5
|
import { safeErrorCode } from './util/safe-error.js';
|
|
5
|
-
import { permissionStopSchema } from '@myagentroam/protocol';
|
|
6
6
|
/** User inputs arrive with a durable Session identity, unlike execution-local output IDs. */
|
|
7
|
-
export function runConversationItemId(runId, itemId, kind) {
|
|
8
|
-
return kind === 'user_message' ? itemId : `${runId}:${itemId}`;
|
|
9
|
-
}
|
|
10
7
|
/**
|
|
11
8
|
* Deliberately process-local runtime domain. No method in this class writes
|
|
12
9
|
* into Node SQLite: a Node restart loses active runs, approvals, leases and
|
|
@@ -18,6 +15,26 @@ export class NodeRuntimeState {
|
|
|
18
15
|
getWorkspace;
|
|
19
16
|
now;
|
|
20
17
|
onRunChanged;
|
|
18
|
+
activeExecutions = new Set();
|
|
19
|
+
interruptedExecutions = new Set();
|
|
20
|
+
executionAccepted(executionId) {
|
|
21
|
+
this.activeExecutions.add(executionId);
|
|
22
|
+
}
|
|
23
|
+
executionReleased(executionId) {
|
|
24
|
+
this.activeExecutions.delete(executionId);
|
|
25
|
+
}
|
|
26
|
+
isExecutionActive(executionId) {
|
|
27
|
+
return this.activeExecutions.has(executionId);
|
|
28
|
+
}
|
|
29
|
+
activeExecutionCount() {
|
|
30
|
+
return this.activeExecutions.size;
|
|
31
|
+
}
|
|
32
|
+
requestExecutionInterrupt(executionId) {
|
|
33
|
+
this.interruptedExecutions.add(executionId);
|
|
34
|
+
}
|
|
35
|
+
isExecutionInterruptRequested(executionId) {
|
|
36
|
+
return this.interruptedExecutions.has(executionId);
|
|
37
|
+
}
|
|
21
38
|
static MAX_COMPLETED_TURNS_PER_SESSION = 10;
|
|
22
39
|
sessions = new Map();
|
|
23
40
|
runs = new Map();
|
|
@@ -33,7 +50,7 @@ export class NodeRuntimeState {
|
|
|
33
50
|
turns = new Map();
|
|
34
51
|
/** New Sessions retain their full history until the bounded Runtime window drops a Turn. */
|
|
35
52
|
completeHistorySessions = new Set();
|
|
36
|
-
|
|
53
|
+
approvalState = new RuntimeApprovals((runId) => this.getRun(runId), (runId) => this.currentExecutionId(runId), (runId) => this.canonicalRunId(runId), () => this.now());
|
|
37
54
|
/** A Session owns at most one running turn; Workspace sessions may run concurrently. */
|
|
38
55
|
leases = new Map();
|
|
39
56
|
/** Blocks new Runs or queued messages while native history is being destructively replaced. */
|
|
@@ -795,6 +812,21 @@ export class NodeRuntimeState {
|
|
|
795
812
|
}));
|
|
796
813
|
return value;
|
|
797
814
|
}
|
|
815
|
+
acceptExecutionTerminal(input) {
|
|
816
|
+
const run = this.getRun(input.runId);
|
|
817
|
+
if (run === undefined)
|
|
818
|
+
return { recorded: undefined, current: false, interrupted: false };
|
|
819
|
+
const currentId = this.currentExecutionId(run.id);
|
|
820
|
+
const current = currentId === input.runId || (currentId === undefined && input.runId === run.id);
|
|
821
|
+
const recorded = this.appendRunEvent(input);
|
|
822
|
+
if (recorded === undefined)
|
|
823
|
+
return { recorded, current, interrupted: false };
|
|
824
|
+
if (current && input.pauseQueue)
|
|
825
|
+
this.pauseSessionQueue(run.sessionId);
|
|
826
|
+
this.activeExecutions.delete(input.runId);
|
|
827
|
+
const interrupted = this.interruptedExecutions.delete(input.runId);
|
|
828
|
+
return { recorded, current, interrupted: current && interrupted };
|
|
829
|
+
}
|
|
798
830
|
appendRunEvent(input) {
|
|
799
831
|
const execution = this.executions.get(input.runId);
|
|
800
832
|
const runId = execution?.runId ?? input.runId;
|
|
@@ -985,65 +1017,22 @@ export class NodeRuntimeState {
|
|
|
985
1017
|
return completedTurn;
|
|
986
1018
|
}
|
|
987
1019
|
createApproval(input) {
|
|
988
|
-
|
|
989
|
-
if (run === undefined)
|
|
990
|
-
throw new Error('RUN_NOT_FOUND');
|
|
991
|
-
if (input.runId !== run.id && this.currentExecutionId(run.id) !== input.runId)
|
|
992
|
-
throw new Error('RUN_EXECUTION_NOT_CURRENT');
|
|
993
|
-
if (this.approvals.has(input.approvalId))
|
|
994
|
-
throw new Error('APPROVAL_ALREADY_EXISTS');
|
|
995
|
-
if (input.expiresAt <= this.now())
|
|
996
|
-
throw new Error('APPROVAL_EXPIRED');
|
|
997
|
-
const value = {
|
|
998
|
-
id: input.approvalId,
|
|
999
|
-
runId: input.runId,
|
|
1000
|
-
status: 'PENDING',
|
|
1001
|
-
payload: input.payload,
|
|
1002
|
-
expiresAt: input.expiresAt,
|
|
1003
|
-
createdAt: this.now(),
|
|
1004
|
-
decidedAt: null
|
|
1005
|
-
};
|
|
1006
|
-
this.approvals.set(value.id, value);
|
|
1007
|
-
return value;
|
|
1020
|
+
return this.approvalState.createApproval(input);
|
|
1008
1021
|
}
|
|
1009
1022
|
getApproval(id) {
|
|
1010
|
-
|
|
1011
|
-
if (value?.status === 'PENDING' && value.expiresAt <= this.now())
|
|
1012
|
-
return this.expireApproval(id);
|
|
1013
|
-
return value;
|
|
1023
|
+
return this.approvalState.getApproval(id);
|
|
1014
1024
|
}
|
|
1015
1025
|
listApprovals(runId) {
|
|
1016
|
-
|
|
1017
|
-
return [...this.approvals.values()]
|
|
1018
|
-
.filter((value) => this.canonicalRunId(value.runId) === canonicalRunId)
|
|
1019
|
-
.map((value) => this.getApproval(value.id));
|
|
1026
|
+
return this.approvalState.listApprovals(runId);
|
|
1020
1027
|
}
|
|
1021
1028
|
expireApproval(id) {
|
|
1022
|
-
|
|
1023
|
-
if (value.status !== 'PENDING')
|
|
1024
|
-
return value;
|
|
1025
|
-
if (value.expiresAt > this.now())
|
|
1026
|
-
throw new Error('APPROVAL_NOT_EXPIRED');
|
|
1027
|
-
const next = { ...value, status: 'EXPIRED', decidedAt: this.now() };
|
|
1028
|
-
this.approvals.set(id, next);
|
|
1029
|
-
return next;
|
|
1029
|
+
return this.approvalState.expireApproval(id);
|
|
1030
1030
|
}
|
|
1031
1031
|
decideApproval(id, decision) {
|
|
1032
|
-
|
|
1033
|
-
if (value === undefined)
|
|
1034
|
-
throw new Error('APPROVAL_NOT_FOUND');
|
|
1035
|
-
if (value.status === 'EXPIRED')
|
|
1036
|
-
throw new Error('APPROVAL_EXPIRED');
|
|
1037
|
-
if (value.status !== 'PENDING')
|
|
1038
|
-
throw new Error('APPROVAL_ALREADY_DECIDED');
|
|
1039
|
-
const next = { ...value, status: decision, decidedAt: this.now() };
|
|
1040
|
-
this.approvals.set(id, next);
|
|
1041
|
-
return next;
|
|
1032
|
+
return this.approvalState.decideApproval(id, decision);
|
|
1042
1033
|
}
|
|
1043
1034
|
expireDueApprovals() {
|
|
1044
|
-
return
|
|
1045
|
-
.filter((value) => value.status === 'PENDING' && value.expiresAt <= this.now())
|
|
1046
|
-
.map((value) => this.expireApproval(value.id));
|
|
1035
|
+
return this.approvalState.expireDueApprovals();
|
|
1047
1036
|
}
|
|
1048
1037
|
listNonterminalRuns() {
|
|
1049
1038
|
return [...this.runs.values()].filter((run) => !terminal(run.status));
|
|
@@ -1100,9 +1089,7 @@ export class NodeRuntimeState {
|
|
|
1100
1089
|
this.messageSubmissions.delete(key);
|
|
1101
1090
|
this.rememberTerminalMessageSubmission(key, runId);
|
|
1102
1091
|
}
|
|
1103
|
-
|
|
1104
|
-
if (approval.runId === runId || executionIds.has(approval.runId))
|
|
1105
|
-
this.approvals.delete(approvalId);
|
|
1092
|
+
this.approvalState.removeRun(runId, executionIds);
|
|
1106
1093
|
}
|
|
1107
1094
|
clearTerminalMessageSubmissions(sessionId) {
|
|
1108
1095
|
for (const key of this.terminalMessageSubmissions.keys())
|
|
@@ -1153,9 +1140,7 @@ export class NodeRuntimeState {
|
|
|
1153
1140
|
for (const key of this.failedMessageSubmissions.keys())
|
|
1154
1141
|
if (key.startsWith(`${sessionId}\u0000`))
|
|
1155
1142
|
this.failedMessageSubmissions.delete(key);
|
|
1156
|
-
|
|
1157
|
-
if (runIds.has(approval.runId) || executionIds.has(approval.runId))
|
|
1158
|
-
this.approvals.delete(approvalId);
|
|
1143
|
+
this.approvalState.removeRuns(runIds, executionIds);
|
|
1159
1144
|
}
|
|
1160
1145
|
beginSessionHistoryMutation(sessionId, options) {
|
|
1161
1146
|
if (this.sessionHistoryMutations.has(sessionId))
|
|
@@ -1226,9 +1211,7 @@ export class NodeRuntimeState {
|
|
|
1226
1211
|
if (separator >= 0 && sessionIds.has(key.slice(0, separator)))
|
|
1227
1212
|
this.failedMessageSubmissions.delete(key);
|
|
1228
1213
|
}
|
|
1229
|
-
|
|
1230
|
-
if (runIds.has(approval.runId) || executionIds.has(approval.runId))
|
|
1231
|
-
this.approvals.delete(approvalId);
|
|
1214
|
+
this.approvalState.removeRuns(runIds, executionIds);
|
|
1232
1215
|
for (const sessionId of sessionIds) {
|
|
1233
1216
|
const queued = this.queuedItems.get(sessionId) ?? [];
|
|
1234
1217
|
this.queuedItems.delete(sessionId);
|
|
@@ -1310,12 +1293,6 @@ export class NodeRuntimeState {
|
|
|
1310
1293
|
throw new Error('QUEUE_ITEM_INVALID');
|
|
1311
1294
|
return value;
|
|
1312
1295
|
}
|
|
1313
|
-
requireApproval(id) {
|
|
1314
|
-
const value = this.approvals.get(id);
|
|
1315
|
-
if (value === undefined)
|
|
1316
|
-
throw new Error('APPROVAL_NOT_FOUND');
|
|
1317
|
-
return value;
|
|
1318
|
-
}
|
|
1319
1296
|
updateTurnForRun(runId, update) {
|
|
1320
1297
|
const run = this.requireRun(runId);
|
|
1321
1298
|
const current = this.turns.get(run.sessionId) ?? [];
|
|
@@ -1438,146 +1415,7 @@ export class NodeRuntimeState {
|
|
|
1438
1415
|
this.currentTurnForRun(event.runId) === undefined &&
|
|
1439
1416
|
conversationItemFromEvent(event) !== undefined)
|
|
1440
1417
|
this.createItemOnlyTurn(run, event.createdAt);
|
|
1441
|
-
|
|
1442
|
-
const update = (turn) => {
|
|
1443
|
-
if (event.eventType === 'text.delta' &&
|
|
1444
|
-
isRecord(event.payload) &&
|
|
1445
|
-
typeof event.payload.text === 'string') {
|
|
1446
|
-
const nativeItemId = typeof event.payload.itemId === 'string' && event.payload.itemId.length <= 88
|
|
1447
|
-
? event.payload.itemId
|
|
1448
|
-
: undefined;
|
|
1449
|
-
const stableItemId = nativeItemId === undefined ? undefined : `${event.runId}:${nativeItemId}`;
|
|
1450
|
-
const lastItem = turn.items.at(-1);
|
|
1451
|
-
const existing = stableItemId === undefined
|
|
1452
|
-
? lastItem?.kind === 'assistant_message' && activeConversationItem(lastItem.status)
|
|
1453
|
-
? lastItem
|
|
1454
|
-
: undefined
|
|
1455
|
-
: turn.items.find((item) => item.id === stableItemId && item.kind === 'assistant_message');
|
|
1456
|
-
const text = `${existing === undefined ? '' : readableText(existing.payload)}${event.payload.text}`;
|
|
1457
|
-
const sourceItemId = conversationSourceItemId(event.payload) ?? existing?.sourceItemId;
|
|
1458
|
-
needsProcessProjection =
|
|
1459
|
-
existing === undefined ||
|
|
1460
|
-
existing.sourceItemId !== sourceItemId ||
|
|
1461
|
-
(!readableText(existing.payload).trim() && !!text.trim());
|
|
1462
|
-
const item = {
|
|
1463
|
-
id: existing?.id ?? stableItemId ?? `${event.runId}:assistant:${event.sequence}`,
|
|
1464
|
-
...(sourceItemId === undefined ? {} : { sourceItemId }),
|
|
1465
|
-
sessionId: run.sessionId,
|
|
1466
|
-
turnId: turn.id,
|
|
1467
|
-
runId: event.runId,
|
|
1468
|
-
parentItemId: null,
|
|
1469
|
-
sourceSequence: existing?.sourceSequence ?? event.sequence,
|
|
1470
|
-
revision: event.sequence,
|
|
1471
|
-
kind: 'assistant_message',
|
|
1472
|
-
...(existing?.processGroup === undefined ? {} : { processGroup: existing.processGroup }),
|
|
1473
|
-
updatedAt: event.createdAt,
|
|
1474
|
-
status: 'IN_PROGRESS',
|
|
1475
|
-
payload: { text, format: 'markdown', model: null },
|
|
1476
|
-
startedAt: existing?.startedAt ?? event.createdAt,
|
|
1477
|
-
completedAt: null
|
|
1478
|
-
};
|
|
1479
|
-
return {
|
|
1480
|
-
...turn,
|
|
1481
|
-
status: 'RUNNING',
|
|
1482
|
-
startedAt: turn.startedAt ?? event.createdAt,
|
|
1483
|
-
items: existing === undefined
|
|
1484
|
-
? [...turn.items, item]
|
|
1485
|
-
: turn.items.map((value) => (value.id === item.id ? item : value))
|
|
1486
|
-
};
|
|
1487
|
-
}
|
|
1488
|
-
const projected = conversationItemFromEvent(event);
|
|
1489
|
-
if (projected !== undefined) {
|
|
1490
|
-
const itemId = runConversationItemId(event.runId, projected.itemId, projected.kind);
|
|
1491
|
-
const trailingItem = turn.items.at(-1);
|
|
1492
|
-
const orderedItems = projected.kind !== 'user_message' &&
|
|
1493
|
-
trailingItem?.kind === 'assistant_message' &&
|
|
1494
|
-
activeConversationItem(trailingItem.status)
|
|
1495
|
-
? turn.items.map((item) => item.id === trailingItem.id
|
|
1496
|
-
? {
|
|
1497
|
-
...item,
|
|
1498
|
-
status: 'COMPLETED',
|
|
1499
|
-
completedAt: event.createdAt,
|
|
1500
|
-
updatedAt: event.createdAt
|
|
1501
|
-
}
|
|
1502
|
-
: item)
|
|
1503
|
-
: turn.items;
|
|
1504
|
-
const existing = orderedItems.find((item) => item.id === itemId) ??
|
|
1505
|
-
(projected.kind === 'assistant_message' &&
|
|
1506
|
-
projected.itemId.startsWith('codex:') &&
|
|
1507
|
-
trailingItem?.kind === 'assistant_message' &&
|
|
1508
|
-
trailingItem.id.startsWith(`${event.runId}:assistant:`) &&
|
|
1509
|
-
activeConversationItem(trailingItem.status)
|
|
1510
|
-
? trailingItem
|
|
1511
|
-
: undefined);
|
|
1512
|
-
const status = projected.status;
|
|
1513
|
-
const sourceItemId = projected.sourceItemId ?? existing?.sourceItemId;
|
|
1514
|
-
const parentItemId = projected.parentItemId === undefined
|
|
1515
|
-
? (existing?.parentItemId ?? null)
|
|
1516
|
-
: runConversationItemId(event.runId, projected.parentItemId);
|
|
1517
|
-
needsProcessProjection =
|
|
1518
|
-
existing === undefined ||
|
|
1519
|
-
existing.kind !== projected.kind ||
|
|
1520
|
-
projected.kind === 'context_compaction' ||
|
|
1521
|
-
existing.parentItemId !== parentItemId ||
|
|
1522
|
-
existing.sourceItemId !== sourceItemId ||
|
|
1523
|
-
(projected.kind === 'assistant_message' &&
|
|
1524
|
-
!!readableText(existing.payload).trim() !== !!readableText(projected.payload).trim()) ||
|
|
1525
|
-
(projected.kind === 'reasoning' && existing.processGroup === undefined);
|
|
1526
|
-
const item = {
|
|
1527
|
-
id: itemId,
|
|
1528
|
-
sessionId: run.sessionId,
|
|
1529
|
-
turnId: turn.id,
|
|
1530
|
-
runId: event.runId,
|
|
1531
|
-
parentItemId,
|
|
1532
|
-
...(sourceItemId === undefined ? {} : { sourceItemId }),
|
|
1533
|
-
sourceSequence: existing?.sourceSequence ?? event.sequence,
|
|
1534
|
-
revision: (existing?.revision ?? -1) + 1,
|
|
1535
|
-
kind: projected.kind,
|
|
1536
|
-
...(existing?.processGroup === undefined ? {} : { processGroup: existing.processGroup }),
|
|
1537
|
-
updatedAt: event.createdAt,
|
|
1538
|
-
status,
|
|
1539
|
-
payload: mergeConversationItemPayload(existing?.payload, projected),
|
|
1540
|
-
...(projected.permissionStop === undefined
|
|
1541
|
-
? {}
|
|
1542
|
-
: { permissionStop: projected.permissionStop }),
|
|
1543
|
-
startedAt: existing?.startedAt ?? event.createdAt,
|
|
1544
|
-
completedAt: completedConversationItem(status) ? event.createdAt : null
|
|
1545
|
-
};
|
|
1546
|
-
return {
|
|
1547
|
-
...turn,
|
|
1548
|
-
status: terminal(run.status) ? run.status : 'RUNNING',
|
|
1549
|
-
startedAt: turn.startedAt ?? event.createdAt,
|
|
1550
|
-
items: existing === undefined
|
|
1551
|
-
? [...orderedItems, item]
|
|
1552
|
-
: orderedItems.map((value) => (value.id === existing.id ? item : value))
|
|
1553
|
-
};
|
|
1554
|
-
}
|
|
1555
|
-
if (event.eventType === 'run.started' || event.eventType === 'run.running')
|
|
1556
|
-
return { ...turn, status: 'RUNNING', startedAt: turn.startedAt ?? event.createdAt };
|
|
1557
|
-
if (event.eventType === 'run.completed' ||
|
|
1558
|
-
event.eventType === 'run.failed' ||
|
|
1559
|
-
event.eventType === 'run.rejected') {
|
|
1560
|
-
const status = event.status ?? this.requireRun(event.runId).status;
|
|
1561
|
-
return {
|
|
1562
|
-
...turn,
|
|
1563
|
-
status,
|
|
1564
|
-
completedAt: event.createdAt,
|
|
1565
|
-
items: turn.items.map((item) => activeConversationItem(item.status)
|
|
1566
|
-
? {
|
|
1567
|
-
...item,
|
|
1568
|
-
status: completedStatusForRun(status),
|
|
1569
|
-
completedAt: event.createdAt
|
|
1570
|
-
}
|
|
1571
|
-
: item)
|
|
1572
|
-
};
|
|
1573
|
-
}
|
|
1574
|
-
return turn;
|
|
1575
|
-
};
|
|
1576
|
-
const project = (turn) => {
|
|
1577
|
-
const next = update(turn);
|
|
1578
|
-
// Ordinary token/output updates retain membership; only structural input needs a scan.
|
|
1579
|
-
return needsProcessProjection ? projectConversationWorkProcesses(next) : next;
|
|
1580
|
-
};
|
|
1418
|
+
const project = (turn) => projectConversationEvent(turn, run, event, terminal(run.status));
|
|
1581
1419
|
if (turnId === undefined)
|
|
1582
1420
|
this.updateCurrentTurnForRun(event.runId, project);
|
|
1583
1421
|
else {
|
|
@@ -1601,168 +1439,6 @@ function transitionAllowed(from, to) {
|
|
|
1601
1439
|
function isRecord(value) {
|
|
1602
1440
|
return typeof value === 'object' && value !== null;
|
|
1603
1441
|
}
|
|
1604
|
-
function readableText(value) {
|
|
1605
|
-
return isRecord(value) && typeof value.text === 'string' ? value.text : '';
|
|
1606
|
-
}
|
|
1607
|
-
function conversationItemFromEvent(event) {
|
|
1608
|
-
if (isRecord(event.payload)) {
|
|
1609
|
-
const approvalId = event.payload.approvalId;
|
|
1610
|
-
if (typeof approvalId === 'string' && approvalId.length > 0) {
|
|
1611
|
-
if (event.eventType === 'approval.request')
|
|
1612
|
-
return {
|
|
1613
|
-
itemId: `approval:${approvalId}`,
|
|
1614
|
-
kind: 'approval_request',
|
|
1615
|
-
status: 'PENDING',
|
|
1616
|
-
payload: {
|
|
1617
|
-
approvalId,
|
|
1618
|
-
approvalStatus: 'PENDING',
|
|
1619
|
-
approval: event.payload.payload,
|
|
1620
|
-
expiresAt: event.payload.expiresAt
|
|
1621
|
-
},
|
|
1622
|
-
merge: false
|
|
1623
|
-
};
|
|
1624
|
-
if (event.eventType === 'approval.decided') {
|
|
1625
|
-
const decision = event.payload.decision;
|
|
1626
|
-
if (decision === 'APPROVED' || decision === 'REJECTED')
|
|
1627
|
-
return {
|
|
1628
|
-
itemId: `approval:${approvalId}`,
|
|
1629
|
-
kind: 'approval_request',
|
|
1630
|
-
status: decision === 'APPROVED' ? 'COMPLETED' : 'DECLINED',
|
|
1631
|
-
payload: { approvalId, approvalStatus: decision },
|
|
1632
|
-
merge: true
|
|
1633
|
-
};
|
|
1634
|
-
}
|
|
1635
|
-
if (event.eventType === 'approval.expired')
|
|
1636
|
-
return {
|
|
1637
|
-
itemId: `approval:${approvalId}`,
|
|
1638
|
-
kind: 'approval_request',
|
|
1639
|
-
status: 'CANCELLED',
|
|
1640
|
-
payload: { approvalId, approvalStatus: 'EXPIRED' },
|
|
1641
|
-
merge: true
|
|
1642
|
-
};
|
|
1643
|
-
}
|
|
1644
|
-
}
|
|
1645
|
-
if (event.eventType !== 'conversation.item' || !isRecord(event.payload))
|
|
1646
|
-
return undefined;
|
|
1647
|
-
const itemId = event.payload.itemId;
|
|
1648
|
-
const kind = event.payload.kind;
|
|
1649
|
-
const status = event.payload.status;
|
|
1650
|
-
const payload = event.payload.payload;
|
|
1651
|
-
if (typeof itemId !== 'string' ||
|
|
1652
|
-
itemId.length === 0 ||
|
|
1653
|
-
itemId.length > 88 ||
|
|
1654
|
-
typeof kind !== 'string' ||
|
|
1655
|
-
!projectableConversationKind(kind) ||
|
|
1656
|
-
typeof status !== 'string' ||
|
|
1657
|
-
!projectableConversationStatus(status) ||
|
|
1658
|
-
!isRecord(payload))
|
|
1659
|
-
return undefined;
|
|
1660
|
-
const append = event.payload.append;
|
|
1661
|
-
const sourceItemId = conversationSourceItemId(event.payload);
|
|
1662
|
-
const permissionStop = permissionStopSchema.safeParse(event.payload.permissionStop);
|
|
1663
|
-
return {
|
|
1664
|
-
itemId,
|
|
1665
|
-
kind,
|
|
1666
|
-
status,
|
|
1667
|
-
payload,
|
|
1668
|
-
...(sourceItemId === undefined ? {} : { sourceItemId }),
|
|
1669
|
-
...(typeof event.payload.parentItemId === 'string' &&
|
|
1670
|
-
event.payload.parentItemId.length > 0 &&
|
|
1671
|
-
event.payload.parentItemId.length <= 88
|
|
1672
|
-
? { parentItemId: event.payload.parentItemId }
|
|
1673
|
-
: {}),
|
|
1674
|
-
...(permissionStop.success ? { permissionStop: permissionStop.data } : {}),
|
|
1675
|
-
merge: event.payload.merge === true,
|
|
1676
|
-
...(append === 'sections' || append === 'outputPreview' || append === 'outputSummary'
|
|
1677
|
-
? { append }
|
|
1678
|
-
: {})
|
|
1679
|
-
};
|
|
1680
|
-
}
|
|
1681
|
-
function conversationSourceItemId(payload) {
|
|
1682
|
-
return typeof payload.sourceItemId === 'string' &&
|
|
1683
|
-
payload.sourceItemId.length > 0 &&
|
|
1684
|
-
payload.sourceItemId.length <= 1024
|
|
1685
|
-
? payload.sourceItemId
|
|
1686
|
-
: undefined;
|
|
1687
|
-
}
|
|
1688
|
-
function projectableConversationKind(value) {
|
|
1689
|
-
return (value === 'user_message' ||
|
|
1690
|
-
value === 'assistant_message' ||
|
|
1691
|
-
value === 'reasoning' ||
|
|
1692
|
-
value === 'tool_call' ||
|
|
1693
|
-
value === 'command_execution' ||
|
|
1694
|
-
value === 'approval_request' ||
|
|
1695
|
-
value === 'user_input_request' ||
|
|
1696
|
-
value === 'plan' ||
|
|
1697
|
-
value === 'todo_list' ||
|
|
1698
|
-
value === 'file_change' ||
|
|
1699
|
-
value === 'context_compaction' ||
|
|
1700
|
-
value === 'unknown' ||
|
|
1701
|
-
value === 'warning' ||
|
|
1702
|
-
value === 'error');
|
|
1703
|
-
}
|
|
1704
|
-
function projectableConversationStatus(value) {
|
|
1705
|
-
return [
|
|
1706
|
-
'PENDING',
|
|
1707
|
-
'IN_PROGRESS',
|
|
1708
|
-
'COMPLETED',
|
|
1709
|
-
'FAILED',
|
|
1710
|
-
'DECLINED',
|
|
1711
|
-
'CANCELLED',
|
|
1712
|
-
'INTERRUPTED'
|
|
1713
|
-
].includes(value);
|
|
1714
|
-
}
|
|
1715
|
-
function mergeConversationItemPayload(existing, next) {
|
|
1716
|
-
const base = next.merge && isRecord(existing) ? existing : {};
|
|
1717
|
-
const value = { ...base, ...next.payload };
|
|
1718
|
-
if (next.append === 'sections') {
|
|
1719
|
-
const prior = Array.isArray(base.sections) ? base.sections : [];
|
|
1720
|
-
const incoming = Array.isArray(next.payload.sections) ? next.payload.sections : [];
|
|
1721
|
-
const sections = new Map();
|
|
1722
|
-
for (const section of [...prior, ...incoming]) {
|
|
1723
|
-
if (!isRecord(section) ||
|
|
1724
|
-
typeof section.index !== 'number' ||
|
|
1725
|
-
!Number.isInteger(section.index) ||
|
|
1726
|
-
section.index < 0 ||
|
|
1727
|
-
typeof section.text !== 'string')
|
|
1728
|
-
continue;
|
|
1729
|
-
sections.set(section.index, appendProjectionText(sections.get(section.index) ?? '', section.text));
|
|
1730
|
-
}
|
|
1731
|
-
value.sections = [...sections]
|
|
1732
|
-
.sort(([left], [right]) => left - right)
|
|
1733
|
-
.map(([index, text]) => ({ index, text }));
|
|
1734
|
-
}
|
|
1735
|
-
if (next.append === 'outputPreview') {
|
|
1736
|
-
const prior = typeof base.outputPreview === 'string' ? base.outputPreview : '';
|
|
1737
|
-
const incoming = typeof next.payload.outputPreview === 'string' ? next.payload.outputPreview : '';
|
|
1738
|
-
value.outputPreview = appendProjectionText(prior, incoming);
|
|
1739
|
-
}
|
|
1740
|
-
if (next.append === 'outputSummary') {
|
|
1741
|
-
const prior = typeof base.outputSummary === 'string' ? base.outputSummary : '';
|
|
1742
|
-
const incoming = typeof next.payload.outputSummary === 'string' ? next.payload.outputSummary : '';
|
|
1743
|
-
value.outputSummary = appendProjectionText(prior, incoming);
|
|
1744
|
-
}
|
|
1745
|
-
return value;
|
|
1746
|
-
}
|
|
1747
|
-
function appendProjectionText(previous, next) {
|
|
1748
|
-
const text = `${previous}${next}`;
|
|
1749
|
-
return text.length <= 10_000 ? text : `${text.slice(0, 9_999)}…`;
|
|
1750
|
-
}
|
|
1751
|
-
function activeConversationItem(status) {
|
|
1752
|
-
return status === 'PENDING' || status === 'IN_PROGRESS';
|
|
1753
|
-
}
|
|
1754
|
-
function completedConversationItem(status) {
|
|
1755
|
-
return !activeConversationItem(status);
|
|
1756
|
-
}
|
|
1757
|
-
function completedStatusForRun(status) {
|
|
1758
|
-
if (status === 'INTERRUPTED')
|
|
1759
|
-
return 'INTERRUPTED';
|
|
1760
|
-
if (status === 'CANCELLED')
|
|
1761
|
-
return 'CANCELLED';
|
|
1762
|
-
if (status === 'FAILED')
|
|
1763
|
-
return 'FAILED';
|
|
1764
|
-
return 'COMPLETED';
|
|
1765
|
-
}
|
|
1766
1442
|
function executionStatusForRun(status) {
|
|
1767
1443
|
if (status === 'FAILED')
|
|
1768
1444
|
return 'FAILED';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computerUseDisableInputSchema, computerUseEnableInputSchema, computerUseEnableResultSchema } from '@myagentroam/protocol';
|
|
2
2
|
import { computerUseRuntimeExecutable, saveNodeConfig } from '../config.js';
|
|
3
|
-
import { nodeOperationData } from '../
|
|
3
|
+
import { nodeOperationData } from '../connection/node-operation-data.js';
|
|
4
4
|
/** Persists Computer Use authorization and owns its asynchronous capability probe. */
|
|
5
5
|
export class ComputerUseEnablementService {
|
|
6
6
|
options;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { withNonImageAttachmentPrompt } from '../
|
|
1
|
+
import { withNonImageAttachmentPrompt } from '../session/attachments.js';
|
|
2
2
|
import { safeErrorCode } from '../util/safe-error.js';
|
|
3
|
-
import { withSessionPrompt } from '../
|
|
3
|
+
import { withSessionPrompt } from '../runner/personal-instructions.js';
|
|
4
4
|
import { prepareComposerResourceInput } from './composer-message-input.js';
|
|
5
5
|
import { nodeLog } from '../operational.js';
|
|
6
6
|
export class ContinuousRunCoordinator {
|
|
@@ -18,6 +18,46 @@ export class ContinuousRunCoordinator {
|
|
|
18
18
|
constructor(options) {
|
|
19
19
|
this.options = options;
|
|
20
20
|
}
|
|
21
|
+
acceptExecutionTerminal(input) {
|
|
22
|
+
const run = this.options.runtime.getRun(input.executionId);
|
|
23
|
+
if (run === undefined)
|
|
24
|
+
return { recorded: undefined, manuallyInterrupted: false };
|
|
25
|
+
let accepted;
|
|
26
|
+
try {
|
|
27
|
+
accepted = this.options.runtime.acceptExecutionTerminal({
|
|
28
|
+
runId: input.executionId,
|
|
29
|
+
sequence: input.sequence,
|
|
30
|
+
eventType: input.eventType,
|
|
31
|
+
payload: input.payload,
|
|
32
|
+
status: input.status,
|
|
33
|
+
pauseQueue: input.permissionStop !== undefined
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { recorded: undefined, manuallyInterrupted: false };
|
|
38
|
+
}
|
|
39
|
+
const { recorded, interrupted: manuallyInterrupted } = accepted;
|
|
40
|
+
if (recorded === undefined || !accepted.current)
|
|
41
|
+
return { recorded, manuallyInterrupted };
|
|
42
|
+
const goalResult = this.options.executionTerminating(input.executionId, input.status, input.permissionStop);
|
|
43
|
+
const queue = this.options.runtime.sessionQueue(run.sessionId);
|
|
44
|
+
const continues = run.status !== 'CANCELLING' &&
|
|
45
|
+
input.permissionStop === undefined &&
|
|
46
|
+
((!queue.paused && queue.itemIds.length > 0) || this.options.keepRunActive(run.sessionId));
|
|
47
|
+
let finalStatus;
|
|
48
|
+
if (!continues) {
|
|
49
|
+
finalStatus =
|
|
50
|
+
input.status === 'CANCELLED' || manuallyInterrupted ? 'INTERRUPTED' : input.status;
|
|
51
|
+
if (finalStatus === 'SUCCEEDED' || finalStatus === 'FAILED' || finalStatus === 'INTERRUPTED')
|
|
52
|
+
this.options.runtime.finishRun(run.id, finalStatus);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
recorded,
|
|
56
|
+
manuallyInterrupted,
|
|
57
|
+
...(finalStatus === undefined ? {} : { finalStatus }),
|
|
58
|
+
...goalResult
|
|
59
|
+
};
|
|
60
|
+
}
|
|
21
61
|
suspend() {
|
|
22
62
|
this.suspended = true;
|
|
23
63
|
for (const timer of this.scheduledSessions.values())
|
|
@@ -430,7 +470,7 @@ export class ContinuousRunCoordinator {
|
|
|
430
470
|
: `${pending.precedingInput}\n\n${resources}`, pending.attachmentPaths, pending.attachmentFiles)
|
|
431
471
|
});
|
|
432
472
|
}
|
|
433
|
-
deleteQueueItem(itemId) {
|
|
473
|
+
deleteQueueItem(itemId, publish = true) {
|
|
434
474
|
const item = this.options.runtime.getQueueItem(itemId);
|
|
435
475
|
if (item === undefined)
|
|
436
476
|
throw new Error('QUEUE_ITEM_INVALID');
|
|
@@ -438,7 +478,8 @@ export class ContinuousRunCoordinator {
|
|
|
438
478
|
this.remove(item.id);
|
|
439
479
|
this.options.clearImages(item.id);
|
|
440
480
|
this.options.cleanupAttachments(item.id);
|
|
441
|
-
|
|
481
|
+
if (publish)
|
|
482
|
+
this.options.emitQueue(item.workspaceId, item.sessionId);
|
|
442
483
|
}
|
|
443
484
|
publishCurrentTurn(runId) {
|
|
444
485
|
const turn = this.options.runtime.conversationTurnForRun(runId);
|
|
@@ -725,7 +766,8 @@ export class ContinuousRunCoordinator {
|
|
|
725
766
|
if (lease !== undefined)
|
|
726
767
|
this.environmentLeases.set(nextId, lease);
|
|
727
768
|
}
|
|
728
|
-
removeGoalQueue(sessionId, preservedGoal, preservedSubmissionId) {
|
|
769
|
+
removeGoalQueue(sessionId, preservedGoal, preservedSubmissionId, publish = true) {
|
|
770
|
+
let changed = false;
|
|
729
771
|
for (const [id, pending] of this.preparedInputs) {
|
|
730
772
|
if (id === preservedSubmissionId)
|
|
731
773
|
continue;
|
|
@@ -737,9 +779,12 @@ export class ContinuousRunCoordinator {
|
|
|
737
779
|
if (pending.goal.id === preservedGoal?.id && pending.goal.revision === preservedGoal.revision)
|
|
738
780
|
continue;
|
|
739
781
|
const item = this.options.runtime.getQueueItem(id);
|
|
740
|
-
if (item !== undefined)
|
|
741
|
-
this.deleteQueueItem(id);
|
|
782
|
+
if (item !== undefined) {
|
|
783
|
+
this.deleteQueueItem(id, publish);
|
|
784
|
+
changed = true;
|
|
785
|
+
}
|
|
742
786
|
}
|
|
787
|
+
return changed;
|
|
743
788
|
}
|
|
744
789
|
removePendingQueue(sessionId, preservedItemId) {
|
|
745
790
|
for (const itemId of [...this.options.runtime.sessionQueue(sessionId).itemIds]) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { projectConversationWorkProcesses } from '
|
|
1
|
+
import { projectConversationWorkProcesses } from '../session/runtime/work-process.js';
|
|
2
2
|
import { discoverNativeSessions, readNativeSession } from '../native-session-history.js';
|
|
3
|
-
import { nativeConversationPage } from '../
|
|
4
|
-
import { isPlainRecord } from '../util/
|
|
5
|
-
import { conversationClientMessageId } from '../
|
|
3
|
+
import { nativeConversationPage } from '../session/runner-native-session-parsers.js';
|
|
4
|
+
import { isPlainRecord } from '../util/records.js';
|
|
5
|
+
import { conversationClientMessageId } from '../session/conversation-identity.js';
|
|
6
6
|
import { nodeLog } from '../operational.js';
|
|
7
7
|
export function hasManagedActiveRun(runtime, session) {
|
|
8
8
|
const current = runtime.getAgentSession(session.id) ?? session;
|
|
@@ -3,7 +3,7 @@ import { mkdir, mkdtemp, rm } from 'node:fs/promises';
|
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { safeErrorCode } from '../util/safe-error.js';
|
|
6
|
-
import { hostedConversationSandboxProfile } from '
|
|
6
|
+
import { hostedConversationSandboxProfile } from '../hosting/hosted-conversation-sandbox-profile.js';
|
|
7
7
|
const CONVERSATION_HOSTING_API_VERSION = 1;
|
|
8
8
|
/** Runs the same bounded Bubblewrap policy used by hosted local processes. */
|
|
9
9
|
export async function probeBubblewrap() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { conversationHostingDisableInputSchema, conversationHostingEnableInputSchema, conversationHostingEnableResultSchema } from '@myagentroam/protocol';
|
|
2
2
|
import { saveNodeConfig } from '../config.js';
|
|
3
|
-
import { nodeOperationData } from '../
|
|
3
|
+
import { nodeOperationData } from '../connection/node-operation-data.js';
|
|
4
4
|
/** Owns management operations that persist and hot-apply hosting configuration. */
|
|
5
5
|
export class ConversationHostingEnablementService {
|
|
6
6
|
options;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { hostedConversationStorePath, nodeDataDirectory } from '../config.js';
|
|
2
|
-
import { HostedConversationStore } from '
|
|
2
|
+
import { HostedConversationStore } from '../hosting/hosted-conversation-store.js';
|
|
3
3
|
import { ConversationTemplateNodeService } from './conversation-template-node-service.js';
|
|
4
|
-
import { HostedConversationNodeService } from '
|
|
4
|
+
import { HostedConversationNodeService } from '../hosting/hosted-conversation-node-service.js';
|
|
5
5
|
import { ConversationHostingMaintenanceService } from './conversation-hosting-maintenance-service.js';
|
|
6
6
|
import { MarAgentHostedConversationRuntime } from '../runner/mar-agent/hosted-conversation-runtime.js';
|
|
7
7
|
import { BubblewrapSandboxExecutor } from '@myagentroam/agent/sandbox/linux';
|
|
8
|
-
import { hostedConversationSandboxProfile } from '
|
|
8
|
+
import { hostedConversationSandboxProfile } from '../hosting/hosted-conversation-sandbox-profile.js';
|
|
9
9
|
import { conversationHostingCapability } from './conversation-hosting-capability-service.js';
|
|
10
10
|
import { nodeLog } from '../operational.js';
|
|
11
11
|
import { safeErrorCode } from '../util/safe-error.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { statfs } from 'node:fs/promises';
|
|
2
2
|
import { conversationHostingCleanupExecuteInputSchema, conversationHostingCleanupPreviewInputSchema, conversationHostingCleanupPreviewSchema, conversationHostingCleanupResultSchema, conversationHostingStorageCapacitySchema } from '@myagentroam/protocol';
|
|
3
|
-
import { nodeOperationData } from '../
|
|
3
|
+
import { nodeOperationData } from '../connection/node-operation-data.js';
|
|
4
4
|
const DAY_MS = 24 * 60 * 60 * 1_000;
|
|
5
5
|
const AUTOMATIC_CLEANUP_INTERVAL_MS = DAY_MS;
|
|
6
6
|
/** Owns aggregate storage watermarks and permanent hosted-conversation cleanup. */
|