@myagentroam/node 0.11.36 → 0.11.38

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.
Files changed (145) hide show
  1. package/dist/application/execution-lifecycle.js +54 -0
  2. package/dist/application/node-lifecycle.js +104 -0
  3. package/dist/application/node-operation-admission.js +51 -0
  4. package/dist/application/node-operation-contracts.js +1 -0
  5. package/dist/application/runner-composition.js +22 -0
  6. package/dist/application/session-projection-composition.js +26 -0
  7. package/dist/application/workspace-application.js +61 -0
  8. package/dist/application/workspace-composition.js +21 -0
  9. package/dist/capabilities.js +2 -3
  10. package/dist/codex-app-server.js +1 -471
  11. package/dist/connection/authorization.js +26 -0
  12. package/dist/{service → connection}/direct-transfer-service.js +1 -1
  13. package/dist/connection/endpoints.js +32 -0
  14. package/dist/connector.js +145 -253
  15. package/dist/control-outbound-scheduler.js +3 -0
  16. package/dist/database.js +34 -14
  17. package/dist/git-askpass.js +1 -1
  18. package/dist/git-execution-helper.js +1 -1
  19. package/dist/hosting/hosted-conversation-file-identity.js +27 -0
  20. package/dist/hosting/hosted-conversation-file-operations.js +44 -0
  21. package/dist/hosting/hosted-conversation-node-service.js +974 -0
  22. package/dist/hosting/hosted-conversation-runs.js +599 -0
  23. package/dist/hosting/hosted-conversation-templates.js +280 -0
  24. package/dist/hosting/hosted-conversation-uploads.js +344 -0
  25. package/dist/hosting/hosted-conversation-watch.js +194 -0
  26. package/dist/hosting/runtime-contracts.js +1 -0
  27. package/dist/runner/abstract-runner.js +4 -13
  28. package/dist/{claude-agent-sdk.js → runner/claude/claude-agent-sdk.js} +2 -2
  29. package/dist/runner/claude/conversation-parser.js +2 -1
  30. package/dist/runner/claude/managed-run-controller.js +6 -7
  31. package/dist/runner/claude/message-parsers.js +2 -1
  32. package/dist/runner/claude/native-transcript.js +2 -1
  33. package/dist/runner/claude/tool-normalizer.js +1 -1
  34. package/dist/runner/claude-code-runner.js +2 -2
  35. package/dist/runner/codex/codex-app-server.js +471 -0
  36. package/dist/runner/codex/conversation-parser.js +4 -2
  37. package/dist/runner/codex/managed-run-controller.js +7 -9
  38. package/dist/runner/codex/native-transcript.js +1 -1
  39. package/dist/runner/codex/tool-normalizer.js +1 -1
  40. package/dist/runner/codex-runner.js +9 -27
  41. package/dist/runner/contracts.js +1 -0
  42. package/dist/runner/mar-agent/conversation-normalizer.js +2 -2
  43. package/dist/runner/mar-agent/history-projection.js +1 -1
  44. package/dist/runner/mar-agent/hosted-conversation-runtime.js +6 -10
  45. package/dist/runner/mar-agent/managed-run-controller.js +85 -61
  46. package/dist/runner/mar-agent/runtime-model-factory.js +0 -3
  47. package/dist/runner/mar-agent-runner.js +1 -1
  48. package/dist/runner/normalization.js +42 -0
  49. package/dist/runner/opencode/conversation-parser.js +1 -1
  50. package/dist/runner/opencode/managed-run-controller.js +6 -7
  51. package/dist/{opencode-server.js → runner/opencode/opencode-server.js} +2 -2
  52. package/dist/runner/opencode/tool-normalizer.js +1 -1
  53. package/dist/runner/opencode-runner.js +4 -5
  54. package/dist/runner/runner-registry.js +4 -1
  55. package/dist/runtime-state.js +48 -372
  56. package/dist/service/computer-use-enablement-service.js +1 -1
  57. package/dist/service/continuous-run-coordinator.js +52 -7
  58. package/dist/service/conversation-history-service.js +4 -4
  59. package/dist/service/conversation-hosting-capability-service.js +1 -1
  60. package/dist/service/conversation-hosting-enablement-service.js +1 -1
  61. package/dist/service/conversation-hosting-lifecycle-service.js +3 -3
  62. package/dist/service/conversation-hosting-maintenance-service.js +1 -1
  63. package/dist/service/conversation-observation.js +1 -1
  64. package/dist/service/conversation-segment-service.js +1 -1
  65. package/dist/service/external-session-resume-service.js +47 -27
  66. package/dist/service/fake-managed-run-service.js +3 -7
  67. package/dist/service/git-operation-service.js +1 -1
  68. package/dist/service/goal-continuation-coordinator.js +14 -7
  69. package/dist/service/mar-agent-model-transport-test-service.js +1 -1
  70. package/dist/service/native-session-watch-service.js +1 -1
  71. package/dist/service/node-connection-lifecycle-service.js +6 -3
  72. package/dist/service/node-control-channel.js +48 -11
  73. package/dist/service/node-request-service.js +1 -1
  74. package/dist/service/node-terminal-channel.js +2 -1
  75. package/dist/service/node-workspace-coordinator.js +3 -2
  76. package/dist/service/notification-mcp-bridge.js +6 -2
  77. package/dist/service/recent-run-projection-service.js +1 -1
  78. package/dist/service/restart-session-restorer.js +1 -1
  79. package/dist/service/run-event-service.js +49 -42
  80. package/dist/service/run-workbench-service.js +3 -3
  81. package/dist/service/runner-interaction-service.js +6 -5
  82. package/dist/service/runner-service.js +1 -1
  83. package/dist/service/session-recent-activity.js +2 -1
  84. package/dist/service/skill-directory-service.js +1 -1
  85. package/dist/service/skill-install-service.js +2 -2
  86. package/dist/service/terminal-service.js +1 -1
  87. package/dist/service/workbench-event-projection.js +3 -2
  88. package/dist/service/workbench-event-service.js +1 -1
  89. package/dist/service/workspace-service.js +3 -2
  90. package/dist/session/attachments.js +110 -0
  91. package/dist/session/contracts.js +1 -0
  92. package/dist/{util → session}/conversation-identity.js +1 -1
  93. package/dist/session/input-validation.js +15 -0
  94. package/dist/{service → session}/native-session-projection-service.js +40 -11
  95. package/dist/session/pagination.js +77 -0
  96. package/dist/{util → session}/runner-native-session-parsers.js +2 -1
  97. package/dist/session/runtime/approvals.js +90 -0
  98. package/dist/session/runtime/conversation-projection.js +310 -0
  99. package/dist/session/runtime/type-guards.js +19 -0
  100. package/dist/{service → session}/session-catalog-service.js +5 -4
  101. package/dist/{service → session}/session-command-service.js +3 -3
  102. package/dist/{service → session}/session-identity-service.js +1 -1
  103. package/dist/{service → session}/session-lifecycle-service.js +18 -7
  104. package/dist/{service → session}/session-message-service.js +6 -5
  105. package/dist/{service → session}/session-presentation-service.js +1 -1
  106. package/dist/{service → session}/session-query-service.js +2 -2
  107. package/dist/{service → session}/session-schedule-service.js +2 -2
  108. package/dist/util/records.js +3 -0
  109. package/dist/workspace/contracts.js +1 -0
  110. package/dist/workspace/file-index.js +534 -0
  111. package/dist/workspace/files.js +466 -0
  112. package/dist/workspace/git.js +991 -0
  113. package/dist/workspace/path-access.js +184 -0
  114. package/dist/workspace/utf8.js +12 -0
  115. package/dist/{service → workspace}/workspace-change-service.js +45 -21
  116. package/dist/{service → workspace}/workspace-code-navigation-service.js +6 -6
  117. package/dist/{service → workspace}/workspace-file-manager-service.js +1 -1
  118. package/dist/{service → workspace}/workspace-file-service.js +16 -16
  119. package/dist/{service → workspace}/workspace-git-exclude-service.js +1 -1
  120. package/dist/{service → workspace}/workspace-queue-workbench-service.js +3 -2
  121. package/dist/{service → workspace}/workspace-session-service.js +45 -40
  122. package/dist/{service → workspace}/workspace-upload-service.js +28 -28
  123. package/dist/{service → workspace}/workspace-watch-service.js +29 -28
  124. package/dist/{service → workspace}/workspace-workbench-service.js +4 -3
  125. package/package.json +4 -4
  126. package/dist/service/hosted-conversation-node-service.js +0 -2252
  127. package/dist/service/run-domain-state.js +0 -4
  128. package/dist/service/session-domain-state.js +0 -9
  129. package/dist/service/workspace-domain-state.js +0 -41
  130. package/dist/util/node-operation-parsers.js +0 -320
  131. package/dist/workspace.js +0 -2168
  132. /package/dist/{connector → application}/node-connector-options.js +0 -0
  133. /package/dist/{util → connection}/node-operation-data.js +0 -0
  134. /package/dist/{connector → connection}/node-operation-router.js +0 -0
  135. /package/dist/{service → hosting}/hosted-conversation-sandbox-profile.js +0 -0
  136. /package/dist/{service → hosting}/hosted-conversation-store.js +0 -0
  137. /package/dist/{util → mcp}/secret-environment.js +0 -0
  138. /package/dist/{claude-channel.js → runner/claude/claude-channel.js} +0 -0
  139. /package/dist/{util → runner}/personal-instructions.js +0 -0
  140. /package/dist/{util → runner}/runner-error.js +0 -0
  141. /package/dist/{service/conversation-work-process.js → session/runtime/work-process.js} +0 -0
  142. /package/dist/{service → session}/session-context-service.js +0 -0
  143. /package/dist/{util → workspace}/git-credential-client.js +0 -0
  144. /package/dist/{service → workspace}/workspace-content-search-service.js +0 -0
  145. /package/dist/{service → workspace}/workspace-watch-snapshot-service.js +0 -0
@@ -1,4 +0,0 @@
1
- export class RunDomainState {
2
- active = new Set();
3
- interruptRequested = new Set();
4
- }
@@ -1,9 +0,0 @@
1
- export class SessionDomainState {
2
- directNative = new Map();
3
- externalActivity = new Map();
4
- resumedByDirectId = new Map();
5
- resumeFailures = new Map();
6
- messageResumeFailures = new Map();
7
- resumeFailureDetails = new Map();
8
- failureTimers = new Map();
9
- }
@@ -1,41 +0,0 @@
1
- export class WorkspaceDomainState {
2
- uploads = new Map();
3
- composerAttachments = new Map();
4
- changesReads = new Map();
5
- changesCache = new Map();
6
- changesVersions = new Map();
7
- fileIndexes = new Map();
8
- watches = new Map();
9
- watchRevisions = new Map();
10
- watchSnapshotSequence = 0;
11
- sessionWatchTimers = new Map();
12
- sessionWatchSignatures = new Map();
13
- sessionWatchReads = new Map();
14
- sessionCache = new Map();
15
- sessionCacheReads = new Map();
16
- changesLimiter = new AsyncLimiter(3);
17
- }
18
- class AsyncLimiter {
19
- limit;
20
- active = 0;
21
- waiters = [];
22
- constructor(limit) {
23
- this.limit = limit;
24
- }
25
- async run(task) {
26
- if (this.active < this.limit)
27
- this.active += 1;
28
- else
29
- await new Promise((resolve) => this.waiters.push(resolve));
30
- try {
31
- return await task();
32
- }
33
- finally {
34
- const next = this.waiters.shift();
35
- if (next === undefined)
36
- this.active -= 1;
37
- else
38
- next();
39
- }
40
- }
41
- }
@@ -1,320 +0,0 @@
1
- import { nodeCapabilitiesSchema, serializeComposerTag, parseComposerTags, composerVisibleText } from '@myagentroam/protocol';
2
- const MAX_COMPOSER_ATTACHMENT_BYTES = 5 * 1024 * 1024;
3
- const MAX_COMPOSER_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
4
- const USER_AUTHORIZATION_CLOCK_SKEW_MS = 60 * 60 * 1_000;
5
- const COMPOSER_IMAGE_MIME_TYPES = new Set([
6
- 'image/png',
7
- 'image/jpeg',
8
- 'image/gif',
9
- 'image/webp'
10
- ]);
11
- export const DEFAULT_SESSION_PAGE_SIZE = 10;
12
- export const MAX_SESSION_PAGE_SIZE = 100;
13
- export function sessionPage(sessions, input) {
14
- const limit = typeof input.limit === 'number' &&
15
- Number.isInteger(input.limit) &&
16
- input.limit >= 1 &&
17
- input.limit <= MAX_SESSION_PAGE_SIZE
18
- ? input.limit
19
- : DEFAULT_SESSION_PAGE_SIZE;
20
- const cursor = typeof input.cursor === 'string' ? input.cursor : undefined;
21
- const ordered = [...sessions].sort(compareSessionPageEntries);
22
- const cursorEntry = cursor === undefined ? undefined : parseSessionPageCursor(cursor);
23
- const afterCursor = cursor === undefined
24
- ? ordered
25
- : cursorEntry === undefined
26
- ? []
27
- : ordered.filter((session) => compareSessionPageEntries(session, cursorEntry) > 0);
28
- const pinned = ordered.filter((session) => session.pinOrder !== null && session.pinOrder !== undefined);
29
- const pinnedIndexes = new Map(pinned.map((session, index) => [session.id, index]));
30
- const page = afterCursor.slice(0, limit).map((session) => {
31
- const pinIndex = pinnedIndexes.get(session.id);
32
- if (pinIndex === undefined)
33
- return session;
34
- return {
35
- ...session,
36
- canMovePinUp: pinIndex > 0,
37
- canMovePinDown: pinIndex < pinned.length - 1
38
- };
39
- });
40
- const last = page.at(-1);
41
- return {
42
- sessions: page,
43
- nextCursor: last !== undefined && afterCursor.length > page.length ? createSessionPageCursor(last) : null
44
- };
45
- }
46
- export function parseSessionPageCursor(cursor) {
47
- try {
48
- const value = JSON.parse(decodeURIComponent(cursor));
49
- if (!Array.isArray(value) || value.length !== 3)
50
- return undefined;
51
- const [pinOrder, lastActivityAt, id] = value;
52
- if ((pinOrder !== null && (typeof pinOrder !== 'number' || !Number.isFinite(pinOrder))) ||
53
- (lastActivityAt !== null &&
54
- (typeof lastActivityAt !== 'number' || !Number.isFinite(lastActivityAt))) ||
55
- typeof id !== 'string')
56
- return undefined;
57
- return {
58
- id,
59
- lastActivityAt: lastActivityAt ?? 0,
60
- pinOrder,
61
- externalDiscovered: lastActivityAt !== null
62
- };
63
- }
64
- catch {
65
- return undefined;
66
- }
67
- }
68
- export function createSessionPageCursor(session) {
69
- return encodeURIComponent(JSON.stringify([
70
- session.pinOrder ?? null,
71
- session.externalDiscovered === false ? null : session.lastActivityAt,
72
- session.id
73
- ]));
74
- }
75
- export function compareSessionPageEntries(left, right) {
76
- const leftPinned = left.pinOrder !== null && left.pinOrder !== undefined;
77
- const rightPinned = right.pinOrder !== null && right.pinOrder !== undefined;
78
- if (leftPinned !== rightPinned)
79
- return leftPinned ? -1 : 1;
80
- if (leftPinned && rightPinned)
81
- return (left.pinOrder - right.pinOrder || left.id.localeCompare(right.id));
82
- const leftFound = left.externalDiscovered !== false;
83
- const rightFound = right.externalDiscovered !== false;
84
- if (leftFound !== rightFound)
85
- return leftFound ? -1 : 1;
86
- return right.lastActivityAt - left.lastActivityAt || left.id.localeCompare(right.id, 'en');
87
- }
88
- export function compactRunnerText(value, limit) {
89
- return value.length <= limit ? value : `${value.slice(0, Math.max(0, limit - 1))}…`;
90
- }
91
- export function compactRunnerValue(value, limit) {
92
- if (value === undefined || value === null)
93
- return { text: '', truncated: false };
94
- let text;
95
- if (typeof value === 'string')
96
- text = value;
97
- else {
98
- try {
99
- text = JSON.stringify(value);
100
- }
101
- catch {
102
- return { text: '(Unable to display)', truncated: false };
103
- }
104
- }
105
- return { text: compactRunnerText(text, limit), truncated: text.length > limit };
106
- }
107
- export function nativePageEnd(cursor, sessionId, fallback) {
108
- if (cursor === undefined)
109
- return fallback;
110
- try {
111
- const value = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));
112
- return value.sessionId === sessionId &&
113
- Number.isInteger(value.end) &&
114
- value.end >= 0
115
- ? Math.min(value.end, fallback)
116
- : fallback;
117
- }
118
- catch {
119
- return fallback;
120
- }
121
- }
122
- export function boundedConversationItemId(prefix, value) {
123
- const candidate = `${prefix}:${value}`;
124
- if (candidate.length <= 88)
125
- return candidate;
126
- return `${prefix}:${Buffer.from(value)
127
- .toString('base64url')
128
- .slice(0, 88 - prefix.length - 1)}`;
129
- }
130
- export function validUserAuthorization(value, envelope, operation, nodeId, now = Date.now()) {
131
- if (typeof value !== 'object' || value === null || nodeId === undefined)
132
- return false;
133
- const authorization = value;
134
- const modelResourceCapability = operation === 'model.resource.read' &&
135
- authorization.userId === 0 &&
136
- authorization.sessionHash === 'model-resource';
137
- return ((modelResourceCapability ||
138
- (typeof authorization.userId === 'number' &&
139
- Number.isSafeInteger(authorization.userId) &&
140
- authorization.userId > 0 &&
141
- typeof authorization.sessionHash === 'string' &&
142
- /^[A-Za-z0-9_-]{43}$/.test(authorization.sessionHash))) &&
143
- authorization.nodeId === nodeId &&
144
- authorization.operation === operation &&
145
- authorization.requestId === envelope.id &&
146
- typeof authorization.issuedAt === 'number' &&
147
- typeof authorization.expiresAt === 'number' &&
148
- Number.isSafeInteger(authorization.issuedAt) &&
149
- Number.isSafeInteger(authorization.expiresAt) &&
150
- authorization.expiresAt >= authorization.issuedAt &&
151
- authorization.issuedAt <= now + USER_AUTHORIZATION_CLOCK_SKEW_MS &&
152
- authorization.expiresAt >= now - USER_AUTHORIZATION_CLOCK_SKEW_MS &&
153
- authorization.expiresAt - authorization.issuedAt <= 15_000);
154
- }
155
- export function isTerminalRunStatus(status) {
156
- return (status === 'SUCCEEDED' ||
157
- status === 'FAILED' ||
158
- status === 'CANCELLED' ||
159
- status === 'INTERRUPTED');
160
- }
161
- export function validSessionOption(value) {
162
- return (value === undefined ||
163
- (typeof value === 'string' && value.trim().length > 0 && value.length <= 120));
164
- }
165
- export function validSessionEffort(value) {
166
- return value === undefined || (typeof value === 'string' && value.length <= 120);
167
- }
168
- export function validSessionTitle(value) {
169
- return (value === undefined ||
170
- (typeof value === 'string' && value.trim().length > 0 && value.length <= 160));
171
- }
172
- export function sessionTitleFromFirstMessage(content) {
173
- return composerVisibleText(content).replace(/\s+/g, ' ').slice(0, 160);
174
- }
175
- export function parseComposerAttachmentUpload(input) {
176
- if (input.composerAttachmentId === undefined && input.mime === undefined)
177
- return undefined;
178
- if (typeof input.composerAttachmentId !== 'string' ||
179
- !isUuid(input.composerAttachmentId) ||
180
- typeof input.name !== 'string' ||
181
- !validComposerAttachmentName(input.name) ||
182
- typeof input.mime !== 'string' ||
183
- input.mime.length === 0 ||
184
- input.mime.length > 120)
185
- throw new Error('COMPOSER_ATTACHMENT_INVALID');
186
- return { id: input.composerAttachmentId, name: input.name, mime: input.mime };
187
- }
188
- export function parseComposerAttachmentIds(value) {
189
- if (value === undefined)
190
- return [];
191
- if (!Array.isArray(value) || value.length > 5 || value.some((id) => typeof id !== 'string'))
192
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
193
- const ids = value;
194
- if (ids.some((id) => !isUuid(id)) || new Set(ids).size !== ids.length)
195
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
196
- return ids;
197
- }
198
- export function validComposerAttachmentName(name) {
199
- return (name.trim().length > 0 &&
200
- name.length <= 255 &&
201
- name !== '.' &&
202
- name !== '..' &&
203
- !name.includes('/') &&
204
- !name.includes('\\') &&
205
- !Array.from(name).some((character) => {
206
- const code = character.charCodeAt(0);
207
- return code <= 31 || code === 127 || '<>:"|?*'.includes(character);
208
- }));
209
- }
210
- export function isUuid(value) {
211
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
212
- }
213
- export function parseMessageAttachments(value) {
214
- if (value === undefined)
215
- return [];
216
- if (!Array.isArray(value) || value.length > 5)
217
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
218
- let totalBytes = 0;
219
- return value.map((attachment) => {
220
- if (!isPlainRecord(attachment))
221
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
222
- if (typeof attachment.name !== 'string' ||
223
- typeof attachment.mime !== 'string' ||
224
- typeof attachment.dataBase64 !== 'string')
225
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
226
- if (!validComposerAttachmentName(attachment.name) ||
227
- attachment.mime.length === 0 ||
228
- attachment.mime.length > 120 ||
229
- !isCanonicalBase64(attachment.dataBase64))
230
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
231
- const byteSize = Buffer.byteLength(attachment.dataBase64, 'base64');
232
- if (byteSize === 0 || byteSize > MAX_COMPOSER_ATTACHMENT_BYTES)
233
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
234
- totalBytes += byteSize;
235
- if (totalBytes > MAX_COMPOSER_ATTACHMENTS_BYTES)
236
- throw new Error('MESSAGE_ATTACHMENTS_INVALID');
237
- return { name: attachment.name, mime: attachment.mime, dataBase64: attachment.dataBase64 };
238
- });
239
- }
240
- export function parseRunnerImageAttachments(value) {
241
- return parseMessageAttachments(value).map((attachment) => {
242
- if (!isRunnerImageAttachment(attachment))
243
- throw new Error('MESSAGE_ATTACHMENT_UNSUPPORTED');
244
- return attachment;
245
- });
246
- }
247
- export function isRunnerImageAttachment(attachment) {
248
- return COMPOSER_IMAGE_MIME_TYPES.has(attachment.mime);
249
- }
250
- export function isImageAttachment(attachment) {
251
- return attachment.mime.startsWith('image/');
252
- }
253
- export function withNonImageAttachmentPrompt(input, paths, files) {
254
- if (paths.length === 0)
255
- return input;
256
- const tag = serializeComposerTag('mar_attachments', {
257
- files: files
258
- ? [...files]
259
- : paths.map((path) => ({
260
- name: path.split(/[\\/]/u).at(-1),
261
- mime: 'application/octet-stream',
262
- path
263
- }))
264
- });
265
- const body = parseComposerTags(input)
266
- .filter((part) => part.kind !== 'mar_attachments')
267
- .map((part) => (part.kind === 'text' ? part.text : part.raw))
268
- .join('')
269
- .trimEnd();
270
- return `${body}\n${tag}`;
271
- }
272
- export function isCanonicalBase64(value) {
273
- return value.length > 0 && value.length % 4 === 0 && /^[A-Za-z0-9+/]+={0,2}$/.test(value);
274
- }
275
- export function validatedCapabilities(value) {
276
- return nodeCapabilitiesSchema.parse(value);
277
- }
278
- export function nodeConnectEndpoint(serverUrl) {
279
- const endpoint = new URL(serverUrl);
280
- if (endpoint.protocol === 'http:')
281
- endpoint.protocol = 'ws:';
282
- if (endpoint.protocol === 'https:')
283
- endpoint.protocol = 'wss:';
284
- if (endpoint.protocol !== 'ws:' && endpoint.protocol !== 'wss:') {
285
- throw new Error('SERVER_URL_INVALID');
286
- }
287
- endpoint.pathname = `${endpoint.pathname.replace(/\/$/, '')}/api/node/connect`;
288
- endpoint.search = '';
289
- endpoint.hash = '';
290
- return endpoint.toString();
291
- }
292
- export function nodeTerminalConnectEndpoint(serverUrl) {
293
- const endpoint = new URL(serverUrl);
294
- if (endpoint.protocol === 'http:')
295
- endpoint.protocol = 'ws:';
296
- if (endpoint.protocol === 'https:')
297
- endpoint.protocol = 'wss:';
298
- if (endpoint.protocol !== 'ws:' && endpoint.protocol !== 'wss:') {
299
- throw new Error('SERVER_URL_INVALID');
300
- }
301
- endpoint.pathname = `${endpoint.pathname.replace(/\/$/, '')}/api/node/terminal-connect`;
302
- endpoint.search = '';
303
- endpoint.hash = '';
304
- return endpoint.toString();
305
- }
306
- export function isPlainRecord(value) {
307
- return typeof value === 'object' && value !== null && !Array.isArray(value);
308
- }
309
- export function isNodeAgentRun(value) {
310
- return (isPlainRecord(value) &&
311
- typeof value.id === 'string' &&
312
- typeof value.sessionId === 'string' &&
313
- typeof value.status === 'string');
314
- }
315
- export function isNodeConversationTurn(value) {
316
- return (isPlainRecord(value) &&
317
- typeof value.id === 'string' &&
318
- typeof value.sessionId === 'string' &&
319
- Array.isArray(value.items));
320
- }