@myagentroam/node 0.9.145 → 0.9.147
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/runner/mar-agent/hosted-conversation-runtime.js +29 -2
- package/dist/runner/mar-agent/managed-run-controller.js +43 -3
- package/dist/runner/mar-agent/runtime-model-factory.js +0 -4
- package/dist/service/scheduled-session-store.js +12 -0
- package/dist/service/session-schedule-service.js +6 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import { LocalAgentHost, MarAgentError, createMarAgent, openMarAgentSessionCatalog } from '@myagentroam/agent';
|
|
2
|
+
import { LocalAgentHost, MarAgentError, createMarAgent, generateSessionTitle, openMarAgentSessionCatalog } from '@myagentroam/agent';
|
|
3
3
|
import { projectMarAgentHistory } from './history-projection.js';
|
|
4
4
|
import { MarAgentConversationNormalizer } from './conversation-normalizer.js';
|
|
5
5
|
import { hostedConversationGeneratedImagesDisplayDirectory, hostedConversationImageRunId, marAgentGeneratedImageSources, marAgentGeneratedImagesDirectory } from './generated-images.js';
|
|
@@ -12,6 +12,7 @@ import { createImageGenerationExtensions } from './image-generation-extensions.j
|
|
|
12
12
|
*/
|
|
13
13
|
export class MarAgentHostedConversationRuntime {
|
|
14
14
|
#createAgent;
|
|
15
|
+
#generateTitle;
|
|
15
16
|
#createHost;
|
|
16
17
|
#openCatalog;
|
|
17
18
|
#now;
|
|
@@ -22,6 +23,7 @@ export class MarAgentHostedConversationRuntime {
|
|
|
22
23
|
#registerNativeImages;
|
|
23
24
|
constructor(options = {}) {
|
|
24
25
|
this.#createAgent = options.createAgent ?? createMarAgent;
|
|
26
|
+
this.#generateTitle = options.generateTitle ?? generateSessionTitle;
|
|
25
27
|
this.#createHost = options.createHost ?? ((input) => new LocalAgentHost(input));
|
|
26
28
|
this.#openCatalog = options.openCatalog ?? openMarAgentSessionCatalog;
|
|
27
29
|
this.#now = options.now ?? Date.now;
|
|
@@ -109,7 +111,10 @@ export class MarAgentHostedConversationRuntime {
|
|
|
109
111
|
async startRun(input) {
|
|
110
112
|
if (this.#active.has(input.sessionId))
|
|
111
113
|
throw new Error('HOSTED_CONVERSATION_RUN_ACTIVE');
|
|
112
|
-
const { agent, mcp, closeImages } = await this.#createRuntime(input);
|
|
114
|
+
const { agent, mcp, closeImages, models } = await this.#createRuntime(input);
|
|
115
|
+
const titleController = new AbortController();
|
|
116
|
+
let titleTask;
|
|
117
|
+
const metadata = await agent.getSession(input.sessionId).catch(() => undefined);
|
|
113
118
|
let execution;
|
|
114
119
|
try {
|
|
115
120
|
const session = await agent.openSession(input.sessionId);
|
|
@@ -132,6 +137,13 @@ export class MarAgentHostedConversationRuntime {
|
|
|
132
137
|
const completion = (async () => {
|
|
133
138
|
try {
|
|
134
139
|
for await (const event of execution) {
|
|
140
|
+
if (event.type === 'execution.started' && metadata?.automaticTitlePending && !titleTask)
|
|
141
|
+
titleTask = this.#generateTitle({
|
|
142
|
+
models: sdkModelConfigurations(models),
|
|
143
|
+
currentModelId: input.modelId,
|
|
144
|
+
prompt: input.userPrompt,
|
|
145
|
+
signal: titleController.signal
|
|
146
|
+
}).catch(() => undefined);
|
|
135
147
|
await this.#onEvent?.(input.conversationId, event);
|
|
136
148
|
for (const projected of projectHostedEvent(normalizer, event, {
|
|
137
149
|
clientMessageId: input.clientMessageId,
|
|
@@ -140,6 +152,17 @@ export class MarAgentHostedConversationRuntime {
|
|
|
140
152
|
await input.onEvent?.(projected);
|
|
141
153
|
}
|
|
142
154
|
const result = await execution.result();
|
|
155
|
+
if (result.status === 'cancelled')
|
|
156
|
+
titleController.abort();
|
|
157
|
+
const generatedTitle = await titleTask;
|
|
158
|
+
if (generatedTitle && !titleController.signal.aborted)
|
|
159
|
+
await agent
|
|
160
|
+
.setSessionTitle(input.sessionId, generatedTitle, {
|
|
161
|
+
automatic: true,
|
|
162
|
+
expectedTitle: metadata.title,
|
|
163
|
+
executionId: execution.executionId
|
|
164
|
+
})
|
|
165
|
+
.catch(() => undefined);
|
|
143
166
|
const title = await this.#readGeneratedTitle(input.homeDirectory, input.sessionId).catch(() => undefined);
|
|
144
167
|
return {
|
|
145
168
|
status: result.status === 'completed'
|
|
@@ -160,6 +183,8 @@ export class MarAgentHostedConversationRuntime {
|
|
|
160
183
|
};
|
|
161
184
|
}
|
|
162
185
|
finally {
|
|
186
|
+
titleController.abort();
|
|
187
|
+
await titleTask;
|
|
163
188
|
settled = true;
|
|
164
189
|
this.#active.delete(input.sessionId);
|
|
165
190
|
await agent.dispose().catch(() => undefined);
|
|
@@ -178,6 +203,7 @@ export class MarAgentHostedConversationRuntime {
|
|
|
178
203
|
cancel: () => {
|
|
179
204
|
if (settled || this.#active.get(input.sessionId)?.handle !== handle)
|
|
180
205
|
return false;
|
|
206
|
+
titleController.abort();
|
|
181
207
|
execution.cancel();
|
|
182
208
|
return true;
|
|
183
209
|
}
|
|
@@ -297,6 +323,7 @@ export class MarAgentHostedConversationRuntime {
|
|
|
297
323
|
};
|
|
298
324
|
return {
|
|
299
325
|
agent: await this.#createAgent(options),
|
|
326
|
+
models,
|
|
300
327
|
closeImages,
|
|
301
328
|
...(mcp === undefined ? {} : { mcp })
|
|
302
329
|
};
|
|
@@ -4,7 +4,7 @@ import { homedir } from 'node:os';
|
|
|
4
4
|
import { access, constants } from 'node:fs/promises';
|
|
5
5
|
import { nodeExecutionEnvironment } from '../../node-execution-environment.js';
|
|
6
6
|
import { BUNDLED_RIPGREP_VERSION, bundledRipgrepPath, prependBundledRipgrepToPath } from '../../ripgrep-binary.js';
|
|
7
|
-
import { LocalAgentHost, createMarAgent } from '@myagentroam/agent';
|
|
7
|
+
import { LocalAgentHost, createMarAgent, generateSessionTitle } from '@myagentroam/agent';
|
|
8
8
|
import { marAgentReasoningEffortSchema, marAgentRuntimeModelConfigurationSchema } from '@myagentroam/protocol';
|
|
9
9
|
import { boundedConversationItemId } from '../codex/conversation-parser.js';
|
|
10
10
|
import { parseSecretEnvironment } from '../../util/secret-environment.js';
|
|
@@ -29,6 +29,7 @@ export class MarAgentManagedRunController {
|
|
|
29
29
|
#createAgent;
|
|
30
30
|
#modelFactory;
|
|
31
31
|
#computerUse;
|
|
32
|
+
#generateTitle;
|
|
32
33
|
#disposePromise;
|
|
33
34
|
#disposed = false;
|
|
34
35
|
constructor(runner, host, options = {}) {
|
|
@@ -44,6 +45,7 @@ export class MarAgentManagedRunController {
|
|
|
44
45
|
}
|
|
45
46
|
});
|
|
46
47
|
this.#computerUse = options.computerUse;
|
|
48
|
+
this.#generateTitle = options.generateTitle ?? generateSessionTitle;
|
|
47
49
|
}
|
|
48
50
|
dispose() {
|
|
49
51
|
if (this.#disposePromise !== undefined)
|
|
@@ -244,6 +246,8 @@ export class MarAgentManagedRunController {
|
|
|
244
246
|
let executionMcpBinding;
|
|
245
247
|
let computerUseBinding;
|
|
246
248
|
let executionModels = [];
|
|
249
|
+
const titleController = new AbortController();
|
|
250
|
+
let titleTask;
|
|
247
251
|
try {
|
|
248
252
|
const sessionKey = input.externalSessionId ?? input.sessionId;
|
|
249
253
|
// Reserve both identities while opening so a concurrent release can await the same runtime.
|
|
@@ -364,6 +368,9 @@ export class MarAgentManagedRunController {
|
|
|
364
368
|
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
365
369
|
images: input.images
|
|
366
370
|
};
|
|
371
|
+
const metadata = input.mode === 'compact' || !runtime.automaticTitleEnabled
|
|
372
|
+
? undefined
|
|
373
|
+
: await runtime.agent.getSession(session.id).catch(() => undefined);
|
|
367
374
|
const handle = input.mode === 'plan'
|
|
368
375
|
? session.plan({
|
|
369
376
|
...runInput
|
|
@@ -372,12 +379,36 @@ export class MarAgentManagedRunController {
|
|
|
372
379
|
? session.compact(runInput)
|
|
373
380
|
: session.run(runInput);
|
|
374
381
|
this.#executions.set(input.runId, {
|
|
375
|
-
cancel: () =>
|
|
382
|
+
cancel: () => {
|
|
383
|
+
titleController.abort();
|
|
384
|
+
handle.cancel();
|
|
385
|
+
}
|
|
376
386
|
});
|
|
377
387
|
this.host.emit(input.runId, 'run.running', {}, 'RUNNING');
|
|
378
|
-
for await (const event of handle)
|
|
388
|
+
for await (const event of handle) {
|
|
389
|
+
if (event.type === 'execution.started' && metadata?.automaticTitlePending && !titleTask) {
|
|
390
|
+
titleTask = this.#generateTitle({
|
|
391
|
+
models: sdkModelConfigurations(executionModels),
|
|
392
|
+
currentModelId: input.model.id,
|
|
393
|
+
prompt: input.input,
|
|
394
|
+
signal: titleController.signal
|
|
395
|
+
}).catch(() => undefined);
|
|
396
|
+
runtime.automaticTitleTask = { cancel: () => titleController.abort(), result: titleTask };
|
|
397
|
+
}
|
|
379
398
|
this.project(input.runId, event);
|
|
399
|
+
}
|
|
380
400
|
const result = await handle.result();
|
|
401
|
+
if (result.status === 'cancelled')
|
|
402
|
+
titleController.abort();
|
|
403
|
+
const title = await titleTask;
|
|
404
|
+
if (title && !titleController.signal.aborted)
|
|
405
|
+
await runtime.agent
|
|
406
|
+
.setSessionTitle(session.id, title, {
|
|
407
|
+
automatic: true,
|
|
408
|
+
expectedTitle: metadata.title,
|
|
409
|
+
executionId: handle.executionId
|
|
410
|
+
})
|
|
411
|
+
.catch(() => undefined);
|
|
381
412
|
await this.host.syncTitle(session.id, input.cwd);
|
|
382
413
|
const status = result.status === 'completed'
|
|
383
414
|
? 'SUCCEEDED'
|
|
@@ -412,6 +443,10 @@ export class MarAgentManagedRunController {
|
|
|
412
443
|
this.host.emit(input.runId, 'run.failed', projected, 'FAILED');
|
|
413
444
|
}
|
|
414
445
|
finally {
|
|
446
|
+
titleController.abort();
|
|
447
|
+
await titleTask;
|
|
448
|
+
if (runtime !== undefined && runtime.automaticTitleTask?.result === titleTask)
|
|
449
|
+
delete runtime.automaticTitleTask;
|
|
415
450
|
this.clearInteractions(input.runId);
|
|
416
451
|
this.#normalizers.delete(input.runId);
|
|
417
452
|
this.host.active.delete(input.runId);
|
|
@@ -554,6 +589,7 @@ export class MarAgentManagedRunController {
|
|
|
554
589
|
normalizer: new MarAgentConversationNormalizer(),
|
|
555
590
|
mcpLease,
|
|
556
591
|
dynamicCredentials,
|
|
592
|
+
automaticTitleEnabled: input.externalSessionId === undefined,
|
|
557
593
|
models,
|
|
558
594
|
released: false
|
|
559
595
|
};
|
|
@@ -608,6 +644,10 @@ export class MarAgentManagedRunController {
|
|
|
608
644
|
delete runtime.idleTimer;
|
|
609
645
|
}
|
|
610
646
|
try {
|
|
647
|
+
if (runtime.automaticTitleTask !== undefined) {
|
|
648
|
+
runtime.automaticTitleTask.cancel();
|
|
649
|
+
await runtime.automaticTitleTask.result;
|
|
650
|
+
}
|
|
611
651
|
try {
|
|
612
652
|
await this.#computerUse?.releaseSession(runtime.session.id);
|
|
613
653
|
}
|
|
@@ -76,9 +76,6 @@ export class MarAgentRuntimeModelFactory {
|
|
|
76
76
|
...(configuration.responsesTransport === undefined
|
|
77
77
|
? {}
|
|
78
78
|
: { responsesTransport: configuration.responsesTransport }),
|
|
79
|
-
...(configuration.responsesEncoding === undefined
|
|
80
|
-
? {}
|
|
81
|
-
: { responsesEncoding: configuration.responsesEncoding }),
|
|
82
79
|
responsesToolNamespace: configuration.responsesToolNamespace,
|
|
83
80
|
responsesPreviousResponseId: configuration.responsesPreviousResponseId,
|
|
84
81
|
enabled: configuration.enabled
|
|
@@ -114,7 +111,6 @@ export class MarAgentRuntimeModelFactory {
|
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
: {}),
|
|
117
|
-
responsesEncoding: configuration.responsesEncoding ?? 'STANDARD',
|
|
118
114
|
responsesConfigurationUpdates: configuration.responsesConfigurationUpdates === true,
|
|
119
115
|
credentialProvider: provider
|
|
120
116
|
};
|
|
@@ -152,6 +152,18 @@ export class ScheduledSessionStore {
|
|
|
152
152
|
.prepare('SELECT * FROM scheduled_session_occurrences WHERE task_id=? ORDER BY due_at DESC LIMIT ?')
|
|
153
153
|
.all(taskId, Math.max(1, Math.min(limit, 100)));
|
|
154
154
|
}
|
|
155
|
+
recentPage(taskId, page = 1) {
|
|
156
|
+
if (!Number.isSafeInteger(page) || page < 1)
|
|
157
|
+
throw new Error('SCHEDULE_INVALID');
|
|
158
|
+
const total = this.database
|
|
159
|
+
.prepare('SELECT COUNT(*) AS count FROM scheduled_session_occurrences WHERE task_id=?')
|
|
160
|
+
.get(taskId).count;
|
|
161
|
+
const actualPage = Math.min(page, Math.max(1, Math.ceil(total / 10)));
|
|
162
|
+
const occurrences = this.database
|
|
163
|
+
.prepare('SELECT * FROM scheduled_session_occurrences WHERE task_id=? ORDER BY due_at DESC, id DESC LIMIT 10 OFFSET ?')
|
|
164
|
+
.all(taskId, (actualPage - 1) * 10);
|
|
165
|
+
return { occurrences, occurrenceTotal: total, occurrencePage: actualPage };
|
|
166
|
+
}
|
|
155
167
|
pendingProposals(taskId) {
|
|
156
168
|
return this.database
|
|
157
169
|
.prepare(`SELECT * FROM scheduled_session_proposals
|
|
@@ -30,11 +30,16 @@ export class SessionScheduleService {
|
|
|
30
30
|
const session = await this.requireSession(input);
|
|
31
31
|
const store = this.store();
|
|
32
32
|
const task = store.get(session.externalSessionId ?? session.id);
|
|
33
|
+
const page = input.occurrencePage === undefined ? 1 : input.occurrencePage;
|
|
34
|
+
if (typeof page !== 'number' || !Number.isSafeInteger(page) || page < 1)
|
|
35
|
+
throw new Error('SCHEDULE_INVALID');
|
|
33
36
|
return {
|
|
34
37
|
task: task ?? null,
|
|
35
38
|
nodeTimezone: nodeTimezone(),
|
|
36
39
|
canResolveProposals: task !== undefined && input.__requestUserId === task.ownerUserId,
|
|
37
|
-
|
|
40
|
+
...(task === undefined
|
|
41
|
+
? { occurrences: [], occurrenceTotal: 0, occurrencePage: 1 }
|
|
42
|
+
: store.recentPage(task.id, page)),
|
|
38
43
|
proposals: task === undefined ? [] : store.pendingProposals(task.id)
|
|
39
44
|
};
|
|
40
45
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myagentroam/node",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.147",
|
|
4
4
|
"description": "MyAgentRoam Node runtime CLI.",
|
|
5
5
|
"license": "Apache-2.0 AND GPL-2.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"zod": "4.4.3",
|
|
37
37
|
"@myagentroam/marctl": "0.9.120",
|
|
38
38
|
"@myagentroam/code-navigation": "0.9.129",
|
|
39
|
-
"@myagentroam/
|
|
40
|
-
"@myagentroam/
|
|
39
|
+
"@myagentroam/agent": "0.9.147",
|
|
40
|
+
"@myagentroam/protocol": "0.9.147"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/ws": "^8.18.1"
|