metame-cli 1.5.24 → 1.5.26
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/package.json
CHANGED
|
@@ -224,6 +224,21 @@ function createBridgeStarter(deps) {
|
|
|
224
224
|
},
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
|
+
|
|
228
|
+
function _createPipelineTarget({ pipelineChatId, effectiveChatId, bot }) {
|
|
229
|
+
const replyChatId = String(pipelineChatId || '').trim();
|
|
230
|
+
const processChatId = String(effectiveChatId || pipelineChatId || '').trim();
|
|
231
|
+
if (!replyChatId || !processChatId) {
|
|
232
|
+
return { processChatId: replyChatId || processChatId, bot };
|
|
233
|
+
}
|
|
234
|
+
if (replyChatId === processChatId) {
|
|
235
|
+
return { processChatId, bot };
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
processChatId,
|
|
239
|
+
bot: _createTeamProxyBot(bot, replyChatId),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
227
242
|
// Get team member's working directory inside the source tree, never under ~/.metame.
|
|
228
243
|
// Creates agents/<key>/ directory by default, or ensures an explicit member.cwd exists.
|
|
229
244
|
function _getMemberCwd(parentCwd, key, explicitCwd = null) {
|
|
@@ -877,6 +892,13 @@ function createBridgeStarter(deps) {
|
|
|
877
892
|
// Use pipelineChatId so each topic gets independent sticky state
|
|
878
893
|
const _chatKey = String(pipelineChatId);
|
|
879
894
|
const _rawChatKey = _threadRawChatId(_chatKey);
|
|
895
|
+
const _topicMainRoute = !!(
|
|
896
|
+
threadRootId
|
|
897
|
+
&& _parentMapping
|
|
898
|
+
&& !_isQuotedReply
|
|
899
|
+
&& _parentMapping.logicalChatId
|
|
900
|
+
&& !String(_parentMapping.logicalChatId).startsWith('_agent_')
|
|
901
|
+
);
|
|
880
902
|
const _setSticky = (key) => {
|
|
881
903
|
if (!_st.team_sticky) _st.team_sticky = {};
|
|
882
904
|
_st.team_sticky[_chatKey] = key;
|
|
@@ -899,6 +921,11 @@ function createBridgeStarter(deps) {
|
|
|
899
921
|
saveState(_st);
|
|
900
922
|
};
|
|
901
923
|
let _stickyKey = (_st.team_sticky || {})[_chatKey] || (_st.team_sticky || {})[_rawChatKey] || null;
|
|
924
|
+
const _pipelineTarget = _createPipelineTarget({
|
|
925
|
+
pipelineChatId,
|
|
926
|
+
effectiveChatId: _topicMainRoute ? chatId : pipelineChatId,
|
|
927
|
+
bot,
|
|
928
|
+
});
|
|
902
929
|
|
|
903
930
|
// Team group routing: if bound project has a team array, check message for member nickname
|
|
904
931
|
// Non-/stop slash commands bypass team routing → handled by main project
|
|
@@ -978,7 +1005,13 @@ function createBridgeStarter(deps) {
|
|
|
978
1005
|
// Cases b & c: no agentKey (main agent) or stale/unknown agentKey
|
|
979
1006
|
_clearSticky();
|
|
980
1007
|
log('INFO', `Quoted reply → route to main (agentKey=${_replyAgentKey} mappingFound=${_replyMappingFound})`);
|
|
981
|
-
await pipeline.processMessage(
|
|
1008
|
+
await pipeline.processMessage(_pipelineTarget.processChatId, trimmedText, {
|
|
1009
|
+
bot: _pipelineTarget.bot,
|
|
1010
|
+
config: liveCfg,
|
|
1011
|
+
executeTaskByName,
|
|
1012
|
+
senderId: acl.senderId,
|
|
1013
|
+
readOnly: acl.readOnly,
|
|
1014
|
+
});
|
|
982
1015
|
return;
|
|
983
1016
|
}
|
|
984
1017
|
// 1. Explicit nickname → route + set sticky
|
|
@@ -1034,7 +1067,13 @@ function createBridgeStarter(deps) {
|
|
|
1034
1067
|
return;
|
|
1035
1068
|
}
|
|
1036
1069
|
try {
|
|
1037
|
-
await pipeline.processMessage(
|
|
1070
|
+
await pipeline.processMessage(_pipelineTarget.processChatId, rest, {
|
|
1071
|
+
bot: _pipelineTarget.bot,
|
|
1072
|
+
config: liveCfg,
|
|
1073
|
+
executeTaskByName,
|
|
1074
|
+
senderId: acl.senderId,
|
|
1075
|
+
readOnly: acl.readOnly,
|
|
1076
|
+
});
|
|
1038
1077
|
} catch (e) {
|
|
1039
1078
|
log('ERROR', `Team main-route handleCommand failed: ${e.message}`);
|
|
1040
1079
|
bot.sendMessage(pipelineChatId, `❌ 执行失败: ${e.message}`).catch(() => {});
|
|
@@ -1058,7 +1097,13 @@ function createBridgeStarter(deps) {
|
|
|
1058
1097
|
}
|
|
1059
1098
|
|
|
1060
1099
|
try {
|
|
1061
|
-
await pipeline.processMessage(
|
|
1100
|
+
await pipeline.processMessage(_pipelineTarget.processChatId, text, {
|
|
1101
|
+
bot: _pipelineTarget.bot,
|
|
1102
|
+
config: liveCfg,
|
|
1103
|
+
executeTaskByName,
|
|
1104
|
+
senderId: acl.senderId,
|
|
1105
|
+
readOnly: acl.readOnly,
|
|
1106
|
+
});
|
|
1062
1107
|
} catch (e) {
|
|
1063
1108
|
log('ERROR', `Feishu handleCommand failed for ${chatId}: ${e.message}`);
|
|
1064
1109
|
bot.sendMessage(pipelineChatId, `❌ 命令执行失败: ${e.message}`).catch(() => {});
|
|
@@ -431,7 +431,8 @@ function createCommandRouter(deps) {
|
|
|
431
431
|
!!curHasEngine &&
|
|
432
432
|
cur.cwd !== projCwd &&
|
|
433
433
|
!rawHasEngine;
|
|
434
|
-
|
|
434
|
+
const _isControlCmd = text && /^\/(stop|quit)$/.test(text.trim());
|
|
435
|
+
if (!_isControlCmd && (!cur || !curHasEngine || shouldReattachForCwdChange)) {
|
|
435
436
|
const initReason = !cur ? 'no-session' : (!curHasEngine ? 'engine-missing' : 'cwd-changed');
|
|
436
437
|
log('INFO', `SESSION-INIT [${String(sessionChatId).slice(-32)}] ${initReason}`);
|
|
437
438
|
attachOrCreateSession(sessionChatId, projCwd, proj.name || mappedKey, targetEngine);
|
|
@@ -4,6 +4,7 @@ const { classifyTaskUsage } = require('./usage-classifier');
|
|
|
4
4
|
const { normalizeModel } = require('./daemon-task-scheduler');
|
|
5
5
|
const { resolveEngineModel } = require('./daemon-engine-runtime');
|
|
6
6
|
const { createCommandSessionResolver } = require('./daemon-command-session-route');
|
|
7
|
+
const { isThreadChatId: _isThreadChatId, rawChatId: _rawThreadChatId } = require('./core/thread-chat-id');
|
|
7
8
|
|
|
8
9
|
function createExecCommandHandler(deps) {
|
|
9
10
|
const {
|
|
@@ -218,7 +219,12 @@ function createExecCommandHandler(deps) {
|
|
|
218
219
|
const _pl = pipeline && pipeline.current;
|
|
219
220
|
if (_pl) {
|
|
220
221
|
_pl.clearQueue(chatId);
|
|
221
|
-
|
|
222
|
+
let stopped = _pl.interruptActive(chatId);
|
|
223
|
+
if (!stopped && _isThreadChatId(chatId)) {
|
|
224
|
+
// Thread-scoped /stop: fall back to raw chatId (task may be keyed at group level).
|
|
225
|
+
// Do NOT clearQueue(_raw) — that would discard queued tasks from other threads.
|
|
226
|
+
stopped = _pl.interruptActive(_rawThreadChatId(chatId));
|
|
227
|
+
}
|
|
222
228
|
if (stopped) {
|
|
223
229
|
await bot.sendMessage(chatId, '⏹ Stopping current engine task...');
|
|
224
230
|
} else {
|
|
@@ -226,7 +232,8 @@ function createExecCommandHandler(deps) {
|
|
|
226
232
|
}
|
|
227
233
|
} else {
|
|
228
234
|
// Fallback: direct activeProcesses manipulation (pipeline not yet initialized)
|
|
229
|
-
const
|
|
235
|
+
const _raw = _isThreadChatId(chatId) ? _rawThreadChatId(chatId) : null;
|
|
236
|
+
const proc = activeProcesses.get(chatId) || (_raw && activeProcesses.get(_raw));
|
|
230
237
|
if (proc && proc.child) {
|
|
231
238
|
proc.aborted = true;
|
|
232
239
|
const signal = proc.killSignal || 'SIGTERM';
|
|
@@ -248,9 +255,12 @@ function createExecCommandHandler(deps) {
|
|
|
248
255
|
const _pl = pipeline && pipeline.current;
|
|
249
256
|
if (_pl) {
|
|
250
257
|
_pl.clearQueue(chatId);
|
|
251
|
-
_pl.interruptActive(chatId)
|
|
258
|
+
if (!_pl.interruptActive(chatId) && _isThreadChatId(chatId)) {
|
|
259
|
+
_pl.interruptActive(_rawThreadChatId(chatId));
|
|
260
|
+
}
|
|
252
261
|
} else {
|
|
253
|
-
const
|
|
262
|
+
const _raw = _isThreadChatId(chatId) ? _rawThreadChatId(chatId) : null;
|
|
263
|
+
const proc = activeProcesses.get(chatId) || (_raw && activeProcesses.get(_raw));
|
|
254
264
|
if (proc && proc.child) {
|
|
255
265
|
proc.aborted = true;
|
|
256
266
|
const signal = proc.killSignal || 'SIGTERM';
|