@myagentroam/node 0.9.103 → 0.9.105

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/connector.js CHANGED
@@ -56,7 +56,7 @@ import { ContinuousRunCoordinator } from './service/continuous-run-coordinator.j
56
56
  import { SessionIdentityService } from './service/session-identity-service.js';
57
57
  import { NativeSessionProjectionService } from './service/native-session-projection-service.js';
58
58
  import { composeConversationRuntimePage, ConversationHistoryService, convergeConversationWatchPage, hasManagedActiveRun } from './service/conversation-history-service.js';
59
- import { ConversationSegmentService, conversationSegments } from './service/conversation-segment-service.js';
59
+ import { ConversationSegmentService } from './service/conversation-segment-service.js';
60
60
  import { RunnerInteractionService } from './service/runner-interaction-service.js';
61
61
  import { SessionLifecycleService } from './service/session-lifecycle-service.js';
62
62
  import { ExternalSessionResumeService } from './service/external-session-resume-service.js';
@@ -1799,8 +1799,7 @@ export class NodeConnector {
1799
1799
  this.runEventBridge.emitConversationItem(runId, item);
1800
1800
  };
1801
1801
  emitConversationTurn = (turn) => {
1802
- const segments = isPlainRecord(turn) && Array.isArray(turn.items) ? conversationSegments(turn) : [];
1803
- this.emitWorkbenchEvent('conversation', { turn, segments });
1802
+ this.emitWorkbenchEvent('conversation', { turn });
1804
1803
  };
1805
1804
  publishWorkbenchEvent = (category, payload) => {
1806
1805
  if (category === 'session') {
@@ -1,5 +1,16 @@
1
1
  const TURN_PAGE_SIZE = 30;
2
+ function conversationSegmentPrefix(turn) {
3
+ const user = turn.items.find((item) => item.kind === 'user_message');
4
+ const payload = typeof user?.payload === 'object' && user.payload !== null && !Array.isArray(user.payload)
5
+ ? user.payload
6
+ : undefined;
7
+ const clientMessageId = payload?.clientMessageId;
8
+ return typeof clientMessageId === 'string' && clientMessageId.length > 0
9
+ ? `${turn.sessionId}:message:${clientMessageId}`
10
+ : turn.id;
11
+ }
2
12
  export function conversationSegments(turn) {
13
+ const prefix = conversationSegmentPrefix(turn);
3
14
  const groups = [];
4
15
  let current = [];
5
16
  for (const item of turn.items) {
@@ -12,7 +23,7 @@ export function conversationSegments(turn) {
12
23
  if (current.length > 0 || groups.length === 0)
13
24
  groups.push(current);
14
25
  return groups.map((items, index) => {
15
- const id = `${turn.id}:segment:${index}`;
26
+ const id = `${prefix}:segment:${index}`;
16
27
  const latest = index === groups.length - 1;
17
28
  const projectedItems = items.map((item) => ({
18
29
  ...item,
@@ -35,6 +46,7 @@ export function conversationSegments(turn) {
35
46
  });
36
47
  }
37
48
  export function conversationSegmentIdentityForItem(turn, itemId, itemKind) {
49
+ const prefix = conversationSegmentPrefix(turn);
38
50
  let index = 0;
39
51
  const runtimeItemId = turn.runId === null ? itemId : `${turn.runId}:${itemId}`;
40
52
  for (const [itemIndex, item] of turn.items.entries()) {
@@ -42,11 +54,11 @@ export function conversationSegmentIdentityForItem(turn, itemId, itemKind) {
42
54
  if (previous?.kind === 'assistant_message' && item.kind !== 'assistant_message')
43
55
  index += 1;
44
56
  if (item.id === itemId || item.id === runtimeItemId)
45
- return { id: `${turn.id}:segment:${index}`, index };
57
+ return { id: `${prefix}:segment:${index}`, index };
46
58
  }
47
59
  if (turn.items.at(-1)?.kind === 'assistant_message' && itemKind !== 'assistant_message')
48
60
  index += 1;
49
- return { id: `${turn.id}:segment:${index}`, index };
61
+ return { id: `${prefix}:segment:${index}`, index };
50
62
  }
51
63
  export class ConversationSegmentService {
52
64
  readTurns;
@@ -258,6 +258,12 @@ export class HostedConversationNodeService {
258
258
  const displayVersionId = latestVersionId ?? conversation.activeVersionId;
259
259
  const version = await this.loadTemplateVersion(displayVersionId, conversation.templateId);
260
260
  const models = networkModels(allowedModels(version, availableModels), version.draft.networkMode);
261
+ if (models.length > 0) {
262
+ const configuredModelId = conversation.modelId;
263
+ const selected = selectModel(version, availableModels, conversation.modelId);
264
+ if (selected.id !== conversation.modelId)
265
+ conversation = await this.options.store.updateConversation(conversation.id, (current) => current.modelId === configuredModelId ? { ...current, modelId: selected.id } : current);
266
+ }
261
267
  const paths = this.options.store.pathsForConversation(userId, conversation.id);
262
268
  const history = historyOverride ??
263
269
  (await this.options.runtime.history({
@@ -96,9 +96,13 @@ export class NodeRunEventBridge {
96
96
  else {
97
97
  if (payload.event.eventType !== 'run.started' && payload.event.eventType !== 'run.running')
98
98
  return;
99
- payload = { turn, segments: conversationSegments(turn) };
99
+ payload = { turn };
100
100
  }
101
101
  }
102
+ if (category === 'conversation' &&
103
+ isPlainRecord(payload) &&
104
+ isNodeConversationTurn(payload.turn))
105
+ return { ...payload, segments: conversationSegments(payload.turn) };
102
106
  return payload;
103
107
  }
104
108
  emitConversationItem(runId, item) {
@@ -3,6 +3,7 @@ import { lstat, mkdir, open, readFile, rename, rm } from 'node:fs/promises';
3
3
  import { dirname, join, posix, resolve } from 'node:path';
4
4
  import { parseComposerAttachmentUpload, validComposerAttachmentName } from '../util/node-operation-parsers.js';
5
5
  import { preflightWorkspaceUpload, workspaceUploadTemporaryName } from '../workspace.js';
6
+ import { ensureWorkspaceGitExclude } from './workspace-git-exclude-service.js';
6
7
  const CHUNK_BYTES = 512 * 1024;
7
8
  const TTL_MS = 60 * 60_000;
8
9
  const MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
@@ -258,6 +259,7 @@ export class WorkspaceUploadService {
258
259
  await rm(dirname(attachment.targetPath), { recursive: true, force: true }).catch(() => undefined);
259
260
  }
260
261
  async attachmentTarget(workspacePath, id, name) {
262
+ await ensureWorkspaceGitExclude(workspacePath);
261
263
  const mar = resolve(workspacePath, '.mar');
262
264
  await mkdir(mar, { recursive: true, mode: 0o700 });
263
265
  await safeDirectory(mar);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myagentroam/node",
3
- "version": "0.9.103",
3
+ "version": "0.9.105",
4
4
  "description": "MyAgentRoam Node runtime CLI.",
5
5
  "license": "Apache-2.0 AND GPL-2.0-or-later",
6
6
  "type": "module",
@@ -30,9 +30,9 @@
30
30
  "npm": "11.12.1",
31
31
  "ws": "^8.21.3",
32
32
  "zod": "4.4.3",
33
- "@myagentroam/agent": "0.9.103",
34
- "@myagentroam/code-navigation": "0.9.103",
35
- "@myagentroam/protocol": "0.9.103"
33
+ "@myagentroam/agent": "0.9.105",
34
+ "@myagentroam/code-navigation": "0.9.105",
35
+ "@myagentroam/protocol": "0.9.105"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/ws": "^8.18.1"