dominds 1.26.6 → 1.27.0

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.
@@ -6,15 +6,10 @@ export declare const NO_ACTIVE_REPLY_PREFIX_EN = "[Dominds no reply needed]";
6
6
  export declare const NO_ACTIVE_REPLY_PREFIX_ZH = "[Dominds \u65E0\u9700\u56DE\u8D34]";
7
7
  export declare const REPLY_TOOL_REMINDER_PREFIX_EN = "[Dominds send the reply now]";
8
8
  export declare const REPLY_TOOL_REMINDER_PREFIX_ZH = "[Dominds \u73B0\u5728\u53D1\u9001\u56DE\u8D34]";
9
- export declare const REPLY_REASSERTION_PREFIX_EN = "[Dominds resume earlier work]";
10
- export declare const REPLY_REASSERTION_PREFIX_ZH = "[Dominds \u63A5\u56DE\u539F\u4EFB\u52A1]";
9
+ export declare const ANSWERING_REPLY_REMINDER_PREFIX_EN = "[Dominds requester still needs reply]";
10
+ export declare const ANSWERING_REPLY_REMINDER_PREFIX_ZH = "[Dominds \u8BC9\u8BF7\u8005\u4ECD\u9700\u56DE\u8D34]";
11
11
  export declare const REPLY_SUPPRESSION_PREFIX_EN = "[Dominds handle this interjection first]";
12
12
  export declare const REPLY_SUPPRESSION_PREFIX_ZH = "[Dominds \u5148\u63A5\u4F4F\u8FD9\u8F6E]";
13
- type ReplyObligationCopyArgs = {
14
- language: LanguageCode;
15
- directive: TellaskReplyDirective;
16
- replyTargetAgentId?: string;
17
- };
18
13
  export declare function buildActiveReplyToolNote(args: {
19
14
  language: LanguageCode;
20
15
  toolName: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack';
@@ -30,12 +25,15 @@ export declare function buildSideDialogRoleHeaderCopy(args: {
30
25
  expectedReplyTool?: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | undefined;
31
26
  }): string;
32
27
  export declare function buildReplyObligationSuppressionGuideText(language: LanguageCode): string;
33
- export declare function buildReplyObligationReassertionText(args: ReplyObligationCopyArgs): string;
34
28
  export declare function buildReplyToolReminderText(args: {
35
29
  language: LanguageCode;
36
30
  directive: TellaskReplyDirective;
37
31
  replyTargetAgentId?: string;
38
32
  }): string;
33
+ export declare function buildAnsweringReplyReminderText(args: {
34
+ language: LanguageCode;
35
+ directive: TellaskReplyDirective;
36
+ replyTargetAgentId?: string;
37
+ }): string;
39
38
  export declare function isReplyToolReminderPromptContent(content: string): boolean;
40
39
  export declare function isStandaloneRuntimeGuidePromptContent(content: string): boolean;
41
- export {};
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REPLY_SUPPRESSION_PREFIX_ZH = exports.REPLY_SUPPRESSION_PREFIX_EN = exports.REPLY_REASSERTION_PREFIX_ZH = exports.REPLY_REASSERTION_PREFIX_EN = exports.REPLY_TOOL_REMINDER_PREFIX_ZH = exports.REPLY_TOOL_REMINDER_PREFIX_EN = exports.NO_ACTIVE_REPLY_PREFIX_ZH = exports.NO_ACTIVE_REPLY_PREFIX_EN = exports.ACTIVE_REPLY_TOOL_PREFIX_ZH = exports.ACTIVE_REPLY_TOOL_PREFIX_EN = void 0;
3
+ exports.REPLY_SUPPRESSION_PREFIX_ZH = exports.REPLY_SUPPRESSION_PREFIX_EN = exports.ANSWERING_REPLY_REMINDER_PREFIX_ZH = exports.ANSWERING_REPLY_REMINDER_PREFIX_EN = exports.REPLY_TOOL_REMINDER_PREFIX_ZH = exports.REPLY_TOOL_REMINDER_PREFIX_EN = exports.NO_ACTIVE_REPLY_PREFIX_ZH = exports.NO_ACTIVE_REPLY_PREFIX_EN = exports.ACTIVE_REPLY_TOOL_PREFIX_ZH = exports.ACTIVE_REPLY_TOOL_PREFIX_EN = void 0;
4
4
  exports.buildActiveReplyToolNote = buildActiveReplyToolNote;
5
5
  exports.buildActiveReplyObligationContextText = buildActiveReplyObligationContextText;
6
6
  exports.buildSideDialogCompletionRule = buildSideDialogCompletionRule;
7
7
  exports.buildSideDialogRoleHeaderCopy = buildSideDialogRoleHeaderCopy;
8
8
  exports.buildReplyObligationSuppressionGuideText = buildReplyObligationSuppressionGuideText;
9
- exports.buildReplyObligationReassertionText = buildReplyObligationReassertionText;
10
9
  exports.buildReplyToolReminderText = buildReplyToolReminderText;
10
+ exports.buildAnsweringReplyReminderText = buildAnsweringReplyReminderText;
11
11
  exports.isReplyToolReminderPromptContent = isReplyToolReminderPromptContent;
12
12
  exports.isStandaloneRuntimeGuidePromptContent = isStandaloneRuntimeGuidePromptContent;
13
13
  const tellask_labels_1 = require("./tellask-labels");
@@ -17,8 +17,8 @@ exports.NO_ACTIVE_REPLY_PREFIX_EN = '[Dominds no reply needed]';
17
17
  exports.NO_ACTIVE_REPLY_PREFIX_ZH = '[Dominds 无需回贴]';
18
18
  exports.REPLY_TOOL_REMINDER_PREFIX_EN = '[Dominds send the reply now]';
19
19
  exports.REPLY_TOOL_REMINDER_PREFIX_ZH = '[Dominds 现在发送回贴]';
20
- exports.REPLY_REASSERTION_PREFIX_EN = '[Dominds resume earlier work]';
21
- exports.REPLY_REASSERTION_PREFIX_ZH = '[Dominds 接回原任务]';
20
+ exports.ANSWERING_REPLY_REMINDER_PREFIX_EN = '[Dominds requester still needs reply]';
21
+ exports.ANSWERING_REPLY_REMINDER_PREFIX_ZH = '[Dominds 诉请者仍需回贴]';
22
22
  exports.REPLY_SUPPRESSION_PREFIX_EN = '[Dominds handle this interjection first]';
23
23
  exports.REPLY_SUPPRESSION_PREFIX_ZH = '[Dominds 先接住这轮]';
24
24
  function formatReplyTargetAgentId(agentId, language) {
@@ -27,18 +27,6 @@ function formatReplyTargetAgentId(agentId, language) {
27
27
  }
28
28
  return language === 'zh' ? '对方' : 'the other dialog';
29
29
  }
30
- function buildReplyObligationReassertionLine(args) {
31
- const toolName = args.directive.expectedReplyCallName;
32
- const replyTarget = formatReplyTargetAgentId(args.replyTargetAgentId, args.language);
33
- const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
34
- language: args.language,
35
- name: args.directive.expectedReplyCallName,
36
- bracketed: true,
37
- });
38
- return args.language === 'zh'
39
- ? `${replyTarget} 还在等你完成${kindLabel}的回贴。等你准备好最终内容后,调用 \`${toolName}\` 发送。这里不是催你立刻回复。`
40
- : `${replyTarget} is still waiting for your ${kindLabel} reply. When the final content is ready, call \`${toolName}\` to send it. This is not asking you to reply immediately.`;
41
- }
42
30
  function buildReplyToolReminderLine(args) {
43
31
  const toolName = args.directive.expectedReplyCallName;
44
32
  const replyTarget = formatReplyTargetAgentId(args.replyTargetAgentId, args.language);
@@ -127,50 +115,30 @@ function buildSideDialogRoleHeaderCopy(args) {
127
115
  : `${tellaskerTag} has assigned you, via this ${kindLabel}, to handle the request content below. When the final reply is ready, call \`${args.expectedReplyTool}\` to send it back. Call \`tellaskBack\` only when you truly need to ask the tellasker back and existing SOP cannot directly identify another owner.`;
128
116
  }
129
117
  // Business scenario: a real user interjected while a longer-running requester reply was still
130
- // open. Dominds has parked the older reply task and will reassert it after the user sees a local
131
- // answer. The model-facing copy must not ask the model to decide whether the old request or the
132
- // new user message wins; Dominds already decided. It also must not ban tools generally: tools are
133
- // fine when the current user message itself needs them, but old request/reminder context must not
134
- // pull the model back into the parked work before the visible user answer.
118
+ // open. The current user message wins the immediate turn; the older reply task remains ordinary
119
+ // durable state for later drive logic. The model-facing copy must not ask the model to decide
120
+ // whether the old request or the new user message wins; Dominds already decided. It also must not
121
+ // ban tools generally: tools are fine when the current user message itself needs them, but old
122
+ // request/reminder context must not pull the model back into earlier handoff work before the
123
+ // visible user answer.
135
124
  function buildReplyObligationSuppressionGuideText(language) {
136
125
  if (language === 'zh') {
137
126
  return [
138
127
  exports.REPLY_SUPPRESSION_PREFIX_ZH,
139
128
  '本轮最新用户消息是真实用户插话;先按这条最新用户消息回答,让用户看到你已经接住了当前话题。',
140
- '原来的长线诉请、回贴任务、技能/SOP 触发条件都已暂存;不要在回答当前用户消息前切回旧任务、旧工具流程或旧收口。',
129
+ '原来的长线诉请、回贴任务、技能/SOP 触发条件都不能抢在当前用户消息前面;不要在回答当前用户消息前切回旧任务、旧工具流程或旧收口。',
141
130
  '只有当前用户消息本身需要,才使用工具;不要因为旧长线任务、旧技能提示或旧提醒项去调用工具。',
142
- '等当前用户插话已经得到可见回复后,Dominds 会再提醒你接回原来的长线。',
131
+ '当前用户插话得到可见回复后,Dominds 会按已有回复义务、续推和普通驱动规则继续处理后续状态。',
143
132
  ].join('\n');
144
133
  }
145
134
  return [
146
135
  exports.REPLY_SUPPRESSION_PREFIX_EN,
147
136
  'The latest user message in this turn is a real user interjection; answer that latest user message first so the user can see you handled the current topic.',
148
- 'The earlier long-line request, reply task, and skill/SOP triggers are parked; do not switch back to the old task, old tool flow, or old closure before answering the current user message.',
137
+ 'The earlier long-line request, reply task, and skill/SOP triggers must not jump ahead of the current user message; do not switch back to the old task, old tool flow, or old closure before answering the current user message.',
149
138
  'Use tools only if the current user message itself requires them; do not call tools because of the earlier long-line task, old skill hints, or old reminders.',
150
- 'After the current user interjection has a visible reply, Dominds will remind you to resume the earlier long-line thread.',
139
+ 'After the current user interjection has a visible reply, Dominds will continue according to the existing reply obligation, diligence push, and normal drive rules.',
151
140
  ].join('\n');
152
141
  }
153
- // Business scenario: the visible answer to the user interjection has been delivered, so the
154
- // previously parked long-line reply task becomes current again. This is intentionally softer than
155
- // the "send now" reminder: the original task resumes, but the final reply tool is still used only
156
- // when final content is ready.
157
- function buildReplyObligationReassertionText(args) {
158
- return args.language === 'zh'
159
- ? [
160
- exports.REPLY_REASSERTION_PREFIX_ZH,
161
- '',
162
- '刚才那轮插话已经处理完了,现在继续原来的长线任务。',
163
- '',
164
- buildReplyObligationReassertionLine(args),
165
- ].join('\n')
166
- : [
167
- exports.REPLY_REASSERTION_PREFIX_EN,
168
- '',
169
- 'The interjection has been handled. Now continue the original longer-running task.',
170
- '',
171
- buildReplyObligationReassertionLine(args),
172
- ].join('\n');
173
- }
174
142
  // Business scenario: the model already wrote content that can be sent back to the requester but
175
143
  // stopped as plain text instead of using the reply tool Dominds named. In that state Dominds can
176
144
  // be precise: this is no longer "keep working", it is "send the already-produced final content
@@ -196,13 +164,43 @@ function buildReplyToolReminderText(args) {
196
164
  'Use this tool to send it now; do not rely on plain text, because the other dialog may not receive a formal reply that way.',
197
165
  ].join('\n');
198
166
  }
167
+ // Business scenario: the model produced structured `answering` (or called `answerHuman`) while a
168
+ // Side Dialog still owes a formal reply to its requester. A2H is a human-attention record; it is
169
+ // intentionally not the requester delivery channel. Keep this as a reply-tool reminder so a later
170
+ // plain-text answer can use the same direct-fallback recovery semantics as ordinary reminders.
171
+ function buildAnsweringReplyReminderText(args) {
172
+ const prefix = args.language === 'zh'
173
+ ? exports.ANSWERING_REPLY_REMINDER_PREFIX_ZH
174
+ : exports.ANSWERING_REPLY_REMINDER_PREFIX_EN;
175
+ const replyTarget = formatReplyTargetAgentId(args.replyTargetAgentId, args.language);
176
+ const kindLabel = (0, tellask_labels_1.getTellaskKindLabel)({
177
+ language: args.language,
178
+ name: args.directive.expectedReplyCallName,
179
+ bracketed: true,
180
+ });
181
+ return args.language === 'zh'
182
+ ? [
183
+ prefix,
184
+ '',
185
+ '`answering` / `answerHuman` 只会记录给人类看的 A2H 答复,不会把正式回贴送达诉请者。',
186
+ '',
187
+ `${replyTarget} 还在等你完成${kindLabel}的回贴。若最终内容已经准备好,请现在调用 \`${args.directive.expectedReplyCallName}({ replyContent })\` 发送;不要用 \`answering\` 或 \`answerHuman\` 代替诉请者回贴。`,
188
+ ].join('\n')
189
+ : [
190
+ prefix,
191
+ '',
192
+ '`answering` / `answerHuman` only records an A2H answer for the human. It does not deliver the formal reply to the requester.',
193
+ '',
194
+ `${replyTarget} is still waiting for your ${kindLabel} reply. If the final content is ready, call \`${args.directive.expectedReplyCallName}({ replyContent })\` now; do not use \`answering\` or \`answerHuman\` as the requester reply path.`,
195
+ ].join('\n');
196
+ }
199
197
  function isReplyToolReminderPromptContent(content) {
200
198
  return (content.startsWith(exports.REPLY_TOOL_REMINDER_PREFIX_ZH) ||
201
- content.startsWith(exports.REPLY_TOOL_REMINDER_PREFIX_EN));
199
+ content.startsWith(exports.REPLY_TOOL_REMINDER_PREFIX_EN) ||
200
+ content.startsWith(exports.ANSWERING_REPLY_REMINDER_PREFIX_ZH) ||
201
+ content.startsWith(exports.ANSWERING_REPLY_REMINDER_PREFIX_EN));
202
202
  }
203
203
  function isStandaloneRuntimeGuidePromptContent(content) {
204
- return (content.startsWith(exports.REPLY_REASSERTION_PREFIX_ZH) ||
205
- content.startsWith(exports.REPLY_REASSERTION_PREFIX_EN) ||
206
- content.startsWith(exports.REPLY_SUPPRESSION_PREFIX_ZH) ||
204
+ return (content.startsWith(exports.REPLY_SUPPRESSION_PREFIX_ZH) ||
207
205
  content.startsWith(exports.REPLY_SUPPRESSION_PREFIX_EN));
208
206
  }
@@ -74,6 +74,14 @@ function compareVersions(a, b) {
74
74
  }
75
75
  return 0;
76
76
  }
77
+ function isVersionGreaterThan(a, b) {
78
+ const comparison = compareVersions(a, b);
79
+ return comparison !== null ? comparison > 0 : a !== b;
80
+ }
81
+ function isVersionAtLeast(a, b) {
82
+ const comparison = compareVersions(a, b);
83
+ return comparison !== null ? comparison >= 0 : a === b;
84
+ }
77
85
  function detectRunKind(mode) {
78
86
  if (mode !== 'production')
79
87
  return 'disabled';
@@ -746,10 +754,13 @@ async function readCurrentDomindsPackageRootAbs() {
746
754
  }
747
755
  async function readCurrentDomindsPackageVersion() {
748
756
  const runningPackageRoot = await readCurrentDomindsPackageRootAbs();
749
- const packageJsonPath = path_1.default.join(runningPackageRoot, 'package.json');
757
+ return await readDomindsPackageVersionAtRootAbs(runningPackageRoot);
758
+ }
759
+ async function readDomindsPackageVersionAtRootAbs(packageRootAbs) {
760
+ const packageJsonPath = path_1.default.join(packageRootAbs, 'package.json');
750
761
  const version = await readPackageVersionFromPackageJson(packageJsonPath);
751
762
  if (version === null) {
752
- throw new Error(`Cannot read current Dominds package metadata at ${packageJsonPath}`);
763
+ throw new Error(`Cannot read Dominds package metadata at ${packageJsonPath}`);
753
764
  }
754
765
  return version;
755
766
  }
@@ -1213,9 +1224,26 @@ async function getDomindsSelfUpdateStatus() {
1213
1224
  targetVersion: latestObservation.latestVersion,
1214
1225
  });
1215
1226
  }
1227
+ const installedVersion = await readDomindsPackageVersionAtRootAbs(globalTargetVerification.managerPackageRootAbs);
1228
+ if (isVersionGreaterThan(installedVersion, runningVersion) &&
1229
+ isVersionAtLeast(installedVersion, latestObservation.latestVersion)) {
1230
+ return buildStatus({
1231
+ currentVersion: runningVersion,
1232
+ installedVersion,
1233
+ latestVersion: latestObservation.latestVersion,
1234
+ checkedAt: latestObservation.checkedAt,
1235
+ mode: cfg.mode,
1236
+ runKind,
1237
+ action: 'restart',
1238
+ busy: 'idle',
1239
+ reason: 'restart_required',
1240
+ message: 'Latest Dominds is already installed and waiting for restart',
1241
+ targetVersion: installedVersion,
1242
+ });
1243
+ }
1216
1244
  return buildStatus({
1217
1245
  currentVersion: runningVersion,
1218
- installedVersion: runningVersion,
1246
+ installedVersion,
1219
1247
  latestVersion: latestObservation.latestVersion,
1220
1248
  checkedAt: latestObservation.checkedAt,
1221
1249
  mode: cfg.mode,
@@ -1277,6 +1305,18 @@ async function installLatestDominds() {
1277
1305
  if (globalTargetVerification.kind === 'unsupported') {
1278
1306
  throw new Error(globalTargetVerification.message);
1279
1307
  }
1308
+ const installedVersion = await readDomindsPackageVersionAtRootAbs(globalTargetVerification.managerPackageRootAbs);
1309
+ if (isVersionGreaterThan(installedVersion, runningVersion) &&
1310
+ isVersionAtLeast(installedVersion, targetVersion)) {
1311
+ restartState = {
1312
+ kind: 'restart_required',
1313
+ installedVersion,
1314
+ installReport: 'Latest Dominds is already installed and waiting for restart',
1315
+ reason: 'restart_required',
1316
+ };
1317
+ installFailureObservation = null;
1318
+ return await getDomindsSelfUpdateStatus();
1319
+ }
1280
1320
  let installCommandError = null;
1281
1321
  try {
1282
1322
  await runPackageManagerCommand(await buildGlobalInstallCommandSpec(globalTargetVerification.manager), buildGlobalInstallArgs(globalTargetVerification.manager), {
@@ -1514,7 +1554,9 @@ async function restartDomindsIntoLatest() {
1514
1554
  throw new Error('Dominds npx restart requires launching Dominds with dominds@latest');
1515
1555
  }
1516
1556
  }
1517
- else if (previousRestartRequiredState === null) {
1557
+ else if (previousRestartRequiredState === null &&
1558
+ (status.targetVersion === null ||
1559
+ !isVersionGreaterThan(status.targetVersion, status.currentVersion))) {
1518
1560
  throw new Error('Dominds restart requires a completed install or a restartable session');
1519
1561
  }
1520
1562
  return await requestDomindsRestart({
@@ -1224,7 +1224,6 @@ async function handleDisplayDialog(ws, packet) {
1224
1224
  taskDocPath: a.taskDocPath,
1225
1225
  content: a.content,
1226
1226
  answeredAt: a.answeredAt,
1227
- userInterjection: a.userInterjection,
1228
1227
  answerRef: a.answerRef,
1229
1228
  })),
1230
1229
  };
@@ -1283,7 +1282,6 @@ async function handleGetQ4HState(ws, _packet) {
1283
1282
  taskDocPath: a.taskDocPath,
1284
1283
  content: a.content,
1285
1284
  answeredAt: a.answeredAt,
1286
- userInterjection: a.userInterjection,
1287
1285
  answerRef: a.answerRef,
1288
1286
  }));
1289
1287
  // Send single response packet with all questions (not PubChan events)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dominds",
3
- "version": "1.26.6",
3
+ "version": "1.27.0",
4
4
  "description": "Dominds CLI and aggregation shell for the LongRun AI kernel/runtime packages.",
5
5
  "type": "commonjs",
6
6
  "publishConfig": {
@@ -55,8 +55,8 @@
55
55
  "yaml": "^2.8.2",
56
56
  "zod": "^4.3.6",
57
57
  "@longrun-ai/codex-auth": "0.13.0",
58
- "@longrun-ai/kernel": "1.16.0",
59
- "@longrun-ai/shell": "1.16.0"
58
+ "@longrun-ai/kernel": "1.17.0",
59
+ "@longrun-ai/shell": "1.17.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^25.3.5",