@ganglion/xacpx 0.9.0 → 0.9.2
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/README.md +6 -4
- package/dist/bridge/bridge-main.js +50 -16
- package/dist/cli.js +207 -79
- package/dist/commands/command-hints.d.ts +1 -1
- package/dist/commands/command-list.d.ts +3 -3
- package/dist/commands/handlers/resolve-reply-mode.d.ts +13 -0
- package/dist/config/types.d.ts +1 -0
- package/dist/i18n/resolve-locale.d.ts +1 -0
- package/dist/i18n/types.d.ts +6 -1
- package/dist/plugin-api.d.ts +1 -1
- package/dist/plugin-api.js +38 -12
- package/dist/plugins/compatibility.d.ts +4 -1
- package/dist/plugins/types.d.ts +2 -2
- package/dist/state/types.d.ts +1 -1
- package/dist/transport/types.d.ts +9 -1
- package/dist/version.d.ts +2 -2
- package/dist/weixin/agent/interface.d.ts +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -113,10 +113,11 @@ var init_session = __esm(() => {
|
|
|
113
113
|
replyModeHeader: "Current reply mode:",
|
|
114
114
|
replyModeSessionLabel: (alias) => `- Session: ${alias}`,
|
|
115
115
|
replyModeGlobalDefault: (value) => `- Global default: ${value}`,
|
|
116
|
+
replyModeChannelDefault: (value) => `- Channel default: ${value}`,
|
|
116
117
|
replyModeSessionOverride: (value) => `- Session override: ${value}`,
|
|
117
118
|
replyModeEffective: (value) => `- Effective: ${value}`,
|
|
118
119
|
replyModeSet: (replyMode) => `Current session reply mode set to: ${replyMode}`,
|
|
119
|
-
replyModeReset: (
|
|
120
|
+
replyModeReset: (effective) => `Session reply mode reset. Now effective: ${effective}`,
|
|
120
121
|
statusHeader: "Current session:",
|
|
121
122
|
statusNameLabel: (alias) => `- Name: ${alias}`,
|
|
122
123
|
statusAgentLabel: (agent) => `- Agent: ${agent}`,
|
|
@@ -659,6 +660,8 @@ var init_config = __esm(() => {
|
|
|
659
660
|
mustBePositiveNumber: (path) => `${path} must be a positive number.`,
|
|
660
661
|
channelTypeDisabled: "channel.type is a legacy single-channel field; /config set writes are disabled. Use `xacpx channel ...` to manage channels[], then restart xacpx.",
|
|
661
662
|
channelReplyModeInvalid: "channel.replyMode only supports: stream, final, verbose",
|
|
663
|
+
channelRuntimeNotFound: (id) => `Channel "${id}" does not exist; add it first with \`xacpx channel add ${id}\`.`,
|
|
664
|
+
channelRuntimeReplyModeInvalid: (id) => `channels.${id}.replyMode only supports: stream, final, verbose`,
|
|
662
665
|
wechatReplyModeInvalid: "wechat.replyMode only supports: stream, final, verbose",
|
|
663
666
|
wechatReplyModeMapped: (value) => `${value} (mapped to channel.replyMode)`,
|
|
664
667
|
agentNotFound: (name) => `Agent "${name}" does not exist. Create it first.`,
|
|
@@ -879,6 +882,8 @@ var init_channel_cli = __esm(() => {
|
|
|
879
882
|
channelRemoved: (id) => `Channel ${id} removed`,
|
|
880
883
|
cannotDisableLastEnabled: "Cannot disable the last enabled channel.",
|
|
881
884
|
channelEnabledToggled: (id, enabled) => `Channel ${id} ${enabled ? "enabled" : "disabled"}`,
|
|
885
|
+
channelReplyModeSet: (id, mode) => `Channel ${id} default reply mode set to: ${mode}`,
|
|
886
|
+
channelReplyModeInvalid: (mode) => `reply mode must be stream / final / verbose, got: ${mode}`,
|
|
882
887
|
channelAccountAlreadyExists: (type, accountId) => `Account ${accountId} already exists on channel ${type}; run xacpx channel rm ${type} --account ${accountId} first`,
|
|
883
888
|
channelAccountAdded: (type, accountId) => `Channel ${type} account ${accountId} added`,
|
|
884
889
|
channelReEnabled: (type) => `Channel ${type} was disabled; it has been automatically re-enabled.`,
|
|
@@ -1179,10 +1184,11 @@ var init_session2 = __esm(() => {
|
|
|
1179
1184
|
replyModeHeader: "当前 reply mode:",
|
|
1180
1185
|
replyModeSessionLabel: (alias) => `- 会话:${alias}`,
|
|
1181
1186
|
replyModeGlobalDefault: (value) => `- 全局默认:${value}`,
|
|
1187
|
+
replyModeChannelDefault: (value) => `- 频道默认:${value}`,
|
|
1182
1188
|
replyModeSessionOverride: (value) => `- 当前会话覆盖:${value}`,
|
|
1183
1189
|
replyModeEffective: (value) => `- 当前生效:${value}`,
|
|
1184
1190
|
replyModeSet: (replyMode) => `已设置当前会话 reply mode:${replyMode}`,
|
|
1185
|
-
replyModeReset: (
|
|
1191
|
+
replyModeReset: (effective) => `已重置当前会话 reply mode,当前生效:${effective}`,
|
|
1186
1192
|
statusHeader: "当前会话:",
|
|
1187
1193
|
statusNameLabel: (alias) => `- 名称:${alias}`,
|
|
1188
1194
|
statusAgentLabel: (agent2) => `- Agent:${agent2}`,
|
|
@@ -1725,6 +1731,8 @@ var init_config2 = __esm(() => {
|
|
|
1725
1731
|
mustBePositiveNumber: (path) => `${path} 必须是正数。`,
|
|
1726
1732
|
channelTypeDisabled: "channel.type 是旧单频道字段,/config set 已禁用写入;请使用 `xacpx channel ...` 管理 channels[],然后重启 xacpx。",
|
|
1727
1733
|
channelReplyModeInvalid: "channel.replyMode 只支持:stream、final、verbose",
|
|
1734
|
+
channelRuntimeNotFound: (id) => `频道「${id}」不存在;请先用 \`xacpx channel add ${id}\` 添加。`,
|
|
1735
|
+
channelRuntimeReplyModeInvalid: (id) => `channels.${id}.replyMode 只支持:stream、final、verbose`,
|
|
1728
1736
|
wechatReplyModeInvalid: "wechat.replyMode 只支持:stream、final、verbose",
|
|
1729
1737
|
wechatReplyModeMapped: (value) => `${value}(已映射到 channel.replyMode)`,
|
|
1730
1738
|
agentNotFound: (name) => `Agent「${name}」不存在,请先创建。`,
|
|
@@ -1945,6 +1953,8 @@ var init_channel_cli2 = __esm(() => {
|
|
|
1945
1953
|
channelRemoved: (id) => `频道 ${id} 已删除`,
|
|
1946
1954
|
cannotDisableLastEnabled: "不能禁用最后一个启用的频道。",
|
|
1947
1955
|
channelEnabledToggled: (id, enabled) => `频道 ${id} 已${enabled ? "启用" : "禁用"}`,
|
|
1956
|
+
channelReplyModeSet: (id, mode) => `频道 ${id} 的默认 reply mode 已设置为:${mode}`,
|
|
1957
|
+
channelReplyModeInvalid: (mode) => `reply mode 只支持 stream / final / verbose,收到:${mode}`,
|
|
1948
1958
|
channelAccountAlreadyExists: (type, accountId) => `频道 ${type} 的账号 ${accountId} 已存在;先 xacpx channel rm ${type} --account ${accountId}`,
|
|
1949
1959
|
channelAccountAdded: (type, accountId) => `频道 ${type} 账号 ${accountId} 已添加`,
|
|
1950
1960
|
channelReEnabled: (type) => `频道 ${type} 此前是 disabled 状态,已自动启用。`,
|
|
@@ -2209,12 +2219,22 @@ var init_zh = __esm(() => {
|
|
|
2209
2219
|
function isLocale(value) {
|
|
2210
2220
|
return typeof value === "string" && VALID.includes(value);
|
|
2211
2221
|
}
|
|
2222
|
+
function detectSystemLocale() {
|
|
2223
|
+
try {
|
|
2224
|
+
return Intl.DateTimeFormat().resolvedOptions().locale || "";
|
|
2225
|
+
} catch {
|
|
2226
|
+
return "";
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2212
2229
|
function resolveLocale(input = {}) {
|
|
2213
2230
|
const { configLanguage, env = process.env } = input;
|
|
2214
2231
|
if (isLocale(configLanguage))
|
|
2215
2232
|
return configLanguage;
|
|
2216
2233
|
const raw = env.LC_ALL || env.LC_MESSAGES || env.LANG || "";
|
|
2217
|
-
|
|
2234
|
+
if (raw)
|
|
2235
|
+
return /^zh/i.test(raw) ? "zh" : "en";
|
|
2236
|
+
const systemLocale = input.systemLocale ?? detectSystemLocale();
|
|
2237
|
+
return /^zh/i.test(systemLocale) ? "zh" : "en";
|
|
2218
2238
|
}
|
|
2219
2239
|
var VALID;
|
|
2220
2240
|
var init_resolve_locale = __esm(() => {
|
|
@@ -4637,6 +4657,9 @@ function parseRuntimeChannelConfig(raw, index) {
|
|
|
4637
4657
|
throw new Error(`channels[${index}].type must be a non-empty string`);
|
|
4638
4658
|
}
|
|
4639
4659
|
const enabled = raw.enabled !== false;
|
|
4660
|
+
if ("replyMode" in raw && !isReplyMode(raw.replyMode)) {
|
|
4661
|
+
throw new Error(`channels[${index}].replyMode must be stream, final, or verbose`);
|
|
4662
|
+
}
|
|
4640
4663
|
let options = undefined;
|
|
4641
4664
|
if ("feishu" in raw && isRecord(raw.feishu)) {
|
|
4642
4665
|
options = raw.feishu;
|
|
@@ -4647,6 +4670,7 @@ function parseRuntimeChannelConfig(raw, index) {
|
|
|
4647
4670
|
id,
|
|
4648
4671
|
type: raw.type,
|
|
4649
4672
|
enabled,
|
|
4673
|
+
...isReplyMode(raw.replyMode) ? { replyMode: raw.replyMode } : {},
|
|
4650
4674
|
...options ? { options } : {}
|
|
4651
4675
|
};
|
|
4652
4676
|
}
|
|
@@ -4892,7 +4916,7 @@ var init_ensure_config = __esm(() => {
|
|
|
4892
4916
|
},
|
|
4893
4917
|
channel: {
|
|
4894
4918
|
type: "weixin",
|
|
4895
|
-
replyMode: "
|
|
4919
|
+
replyMode: "verbose"
|
|
4896
4920
|
},
|
|
4897
4921
|
agents: {
|
|
4898
4922
|
codex: { driver: "codex" },
|
|
@@ -5384,7 +5408,7 @@ function resolveOrchestrationEndpoint(runtimeDir, platform = process.platform) {
|
|
|
5384
5408
|
const suffix = createHash("sha256").update(runtimeDir).digest("hex").slice(0, 12);
|
|
5385
5409
|
return {
|
|
5386
5410
|
kind: "named-pipe",
|
|
5387
|
-
path: `\\\\.\\pipe\\
|
|
5411
|
+
path: `\\\\.\\pipe\\xacpx-orchestration-${suffix}`
|
|
5388
5412
|
};
|
|
5389
5413
|
}
|
|
5390
5414
|
return {
|
|
@@ -11930,9 +11954,9 @@ function readVersion(moduleUrl = import.meta.url) {
|
|
|
11930
11954
|
}
|
|
11931
11955
|
return "unknown";
|
|
11932
11956
|
}
|
|
11933
|
-
var PACKAGE_NAME = "@ganglion/xacpx",
|
|
11957
|
+
var PACKAGE_NAME = "@ganglion/xacpx", XACPX_CORE_VERSION;
|
|
11934
11958
|
var init_version = __esm(() => {
|
|
11935
|
-
|
|
11959
|
+
XACPX_CORE_VERSION = readVersion();
|
|
11936
11960
|
});
|
|
11937
11961
|
|
|
11938
11962
|
// src/orchestration/task-watch-timeouts.ts
|
|
@@ -12271,7 +12295,7 @@ function isReplyMode2(value) {
|
|
|
12271
12295
|
return value === "stream" || value === "final" || value === "verbose";
|
|
12272
12296
|
}
|
|
12273
12297
|
function isSessionSource(value) {
|
|
12274
|
-
return value === undefined || value === "weacpx" || value === "agent-side";
|
|
12298
|
+
return value === undefined || value === "weacpx" || value === "xacpx" || value === "agent-side";
|
|
12275
12299
|
}
|
|
12276
12300
|
function isSessionRecord(value) {
|
|
12277
12301
|
if (!isRecord2(value)) {
|
|
@@ -12803,7 +12827,7 @@ async function ensureCoreResolution(pluginHome) {
|
|
|
12803
12827
|
await copyFile(srcJs, dstJs);
|
|
12804
12828
|
} catch (error2) {
|
|
12805
12829
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
12806
|
-
console.warn(`
|
|
12830
|
+
console.warn(`xacpx: skipped plugin-api resolution shim for "${name}" — could not copy ${srcJs} (${message}). ` + `Channel plugins importing "${name}/plugin-api" at runtime may fail to load.`);
|
|
12807
12831
|
continue;
|
|
12808
12832
|
}
|
|
12809
12833
|
await writeFile4(join6(targetDir, "package.json"), JSON.stringify({
|
|
@@ -13702,7 +13726,7 @@ async function sendTyping(params) {
|
|
|
13702
13726
|
label: "sendTyping"
|
|
13703
13727
|
});
|
|
13704
13728
|
}
|
|
13705
|
-
var CHANNEL_VERSION, ILINK_APP_CLIENT_VERSION, ILINK_APP_ID, DEFAULT_BOT_AGENT = "
|
|
13729
|
+
var CHANNEL_VERSION, ILINK_APP_CLIENT_VERSION, ILINK_APP_ID, DEFAULT_BOT_AGENT = "xacpx", BOT_AGENT_MAX_LEN = 256, DEFAULT_LONG_POLL_TIMEOUT_MS = 35000, DEFAULT_API_TIMEOUT_MS = 15000, DEFAULT_CONFIG_TIMEOUT_MS = 1e4;
|
|
13706
13730
|
var init_api = __esm(() => {
|
|
13707
13731
|
init_version();
|
|
13708
13732
|
init_accounts();
|
|
@@ -19148,19 +19172,19 @@ function cmpTuple(a, b) {
|
|
|
19148
19172
|
return 0;
|
|
19149
19173
|
}
|
|
19150
19174
|
function validatePluginCompatibility(metadata, context) {
|
|
19151
|
-
const { packageName,
|
|
19175
|
+
const { packageName, currentXacpxVersion } = context;
|
|
19152
19176
|
const apiVersion = metadata.apiVersion;
|
|
19153
19177
|
if (typeof apiVersion !== "number") {
|
|
19154
19178
|
throw new Error(t().pluginCli.compatMissingApiVersion(packageName));
|
|
19155
19179
|
}
|
|
19156
|
-
if (!
|
|
19157
|
-
const supported =
|
|
19180
|
+
if (!XACPX_PLUGIN_API_SUPPORTED_VERSIONS.includes(apiVersion)) {
|
|
19181
|
+
const supported = XACPX_PLUGIN_API_SUPPORTED_VERSIONS.join(", ");
|
|
19158
19182
|
throw new Error(t().pluginCli.compatUnsupportedApiVersion(packageName, apiVersion, supported));
|
|
19159
19183
|
}
|
|
19160
|
-
if (!
|
|
19184
|
+
if (!currentXacpxVersion || currentXacpxVersion === "unknown") {
|
|
19161
19185
|
return;
|
|
19162
19186
|
}
|
|
19163
|
-
const normalizedCurrent = normalizeCoreVersionForCompat(
|
|
19187
|
+
const normalizedCurrent = normalizeCoreVersionForCompat(currentXacpxVersion);
|
|
19164
19188
|
const minVersion = metadata.minXacpxVersion ?? metadata.minWeacpxVersion;
|
|
19165
19189
|
const minVersionField = metadata.minXacpxVersion !== undefined ? "minXacpxVersion" : "minWeacpxVersion";
|
|
19166
19190
|
if (minVersion !== undefined) {
|
|
@@ -19175,7 +19199,7 @@ function validatePluginCompatibility(metadata, context) {
|
|
|
19175
19199
|
throw new Error(t().pluginCli.compatInvalidMinVersionDetail(packageName, minVersionField, detail));
|
|
19176
19200
|
}
|
|
19177
19201
|
if (!satisfied) {
|
|
19178
|
-
throw new Error(t().pluginCli.compatMinVersionNotSatisfied(packageName, minVersion,
|
|
19202
|
+
throw new Error(t().pluginCli.compatMinVersionNotSatisfied(packageName, minVersion, currentXacpxVersion));
|
|
19179
19203
|
}
|
|
19180
19204
|
}
|
|
19181
19205
|
const compatibleVersions = metadata.compatibleXacpxVersions ?? metadata.compatibleWeacpxVersions;
|
|
@@ -19192,14 +19216,17 @@ function validatePluginCompatibility(metadata, context) {
|
|
|
19192
19216
|
throw new Error(t().pluginCli.compatInvalidCompatibleVersionsDetail(packageName, compatibleField, detail));
|
|
19193
19217
|
}
|
|
19194
19218
|
if (!satisfied) {
|
|
19195
|
-
throw new Error(t().pluginCli.compatCompatibleVersionsNotSatisfied(packageName, compatibleVersions,
|
|
19219
|
+
throw new Error(t().pluginCli.compatCompatibleVersionsNotSatisfied(packageName, compatibleVersions, currentXacpxVersion));
|
|
19196
19220
|
}
|
|
19197
19221
|
}
|
|
19198
19222
|
}
|
|
19199
|
-
var
|
|
19223
|
+
var XACPX_PLUGIN_API_VERSION = 1, XACPX_PLUGIN_API_SUPPORTED_VERSIONS, XACPX_PLUGIN_MIN_CORE_VERSION = "0.5.0", WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, SEMVER_RE;
|
|
19200
19224
|
var init_compatibility = __esm(() => {
|
|
19201
19225
|
init_i18n();
|
|
19202
|
-
|
|
19226
|
+
XACPX_PLUGIN_API_SUPPORTED_VERSIONS = [1];
|
|
19227
|
+
WEACPX_PLUGIN_API_VERSION = XACPX_PLUGIN_API_VERSION;
|
|
19228
|
+
WEACPX_PLUGIN_API_SUPPORTED_VERSIONS = XACPX_PLUGIN_API_SUPPORTED_VERSIONS;
|
|
19229
|
+
WEACPX_PLUGIN_MIN_CORE_VERSION = XACPX_PLUGIN_MIN_CORE_VERSION;
|
|
19203
19230
|
SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
19204
19231
|
});
|
|
19205
19232
|
|
|
@@ -19214,14 +19241,14 @@ function validateWeacpxPlugin(value, packageName, options = {}) {
|
|
|
19214
19241
|
if (!isRecord(plugin)) {
|
|
19215
19242
|
throw new Error(t().pluginCli.pluginNoDefaultExport(packageName));
|
|
19216
19243
|
}
|
|
19217
|
-
const
|
|
19244
|
+
const currentXacpxVersion = options.currentXacpxVersion ?? readVersion();
|
|
19218
19245
|
validatePluginCompatibility({
|
|
19219
19246
|
apiVersion: plugin.apiVersion,
|
|
19220
19247
|
minWeacpxVersion: plugin.minWeacpxVersion,
|
|
19221
19248
|
compatibleWeacpxVersions: plugin.compatibleWeacpxVersions,
|
|
19222
19249
|
minXacpxVersion: plugin.minXacpxVersion,
|
|
19223
19250
|
compatibleXacpxVersions: plugin.compatibleXacpxVersions
|
|
19224
|
-
}, { packageName,
|
|
19251
|
+
}, { packageName, currentXacpxVersion });
|
|
19225
19252
|
if ("name" in plugin && typeof plugin.name === "string" && plugin.name.trim() && plugin.name.trim() !== packageName) {
|
|
19226
19253
|
throw new Error(t().pluginCli.pluginNameMismatch(packageName, plugin.name));
|
|
19227
19254
|
}
|
|
@@ -19250,7 +19277,7 @@ function validateWeacpxPlugin(value, packageName, options = {}) {
|
|
|
19250
19277
|
}
|
|
19251
19278
|
}
|
|
19252
19279
|
const normalized = {
|
|
19253
|
-
apiVersion:
|
|
19280
|
+
apiVersion: XACPX_PLUGIN_API_VERSION,
|
|
19254
19281
|
...typeof plugin.name === "string" && plugin.name.trim() ? { name: plugin.name.trim() } : { name: packageName },
|
|
19255
19282
|
channels
|
|
19256
19283
|
};
|
|
@@ -19304,7 +19331,7 @@ async function loadConfiguredPlugins(input) {
|
|
|
19304
19331
|
throw new Error(`failed to load plugin ${config4.name}: ${message}`);
|
|
19305
19332
|
}
|
|
19306
19333
|
const plugin = validateWeacpxPlugin(moduleValue, config4.name, {
|
|
19307
|
-
...input.
|
|
19334
|
+
...input.currentXacpxVersion !== undefined ? { currentXacpxVersion: input.currentXacpxVersion } : {}
|
|
19308
19335
|
});
|
|
19309
19336
|
const channels = plugin.channels ?? [];
|
|
19310
19337
|
for (const channel of channels) {
|
|
@@ -19556,16 +19583,16 @@ var init_prompt_output = __esm(() => {
|
|
|
19556
19583
|
});
|
|
19557
19584
|
|
|
19558
19585
|
// src/commands/command-list.ts
|
|
19559
|
-
function
|
|
19586
|
+
function isKnownXacpxCommandPrefix(prefix) {
|
|
19560
19587
|
return KNOWN_COMMAND_PREFIX_SET.has(prefix.toLowerCase());
|
|
19561
19588
|
}
|
|
19562
|
-
function
|
|
19589
|
+
function isKnownXacpxCommandText(text) {
|
|
19563
19590
|
const firstToken = text.trim().split(/\s+/, 1)[0];
|
|
19564
|
-
return Boolean(firstToken &&
|
|
19591
|
+
return Boolean(firstToken && isKnownXacpxCommandPrefix(firstToken));
|
|
19565
19592
|
}
|
|
19566
|
-
var
|
|
19593
|
+
var XACPX_KNOWN_COMMAND_PREFIXES, KNOWN_COMMAND_PREFIX_SET;
|
|
19567
19594
|
var init_command_list = __esm(() => {
|
|
19568
|
-
|
|
19595
|
+
XACPX_KNOWN_COMMAND_PREFIXES = [
|
|
19569
19596
|
"/help",
|
|
19570
19597
|
"/agents",
|
|
19571
19598
|
"/workspaces",
|
|
@@ -19595,7 +19622,7 @@ var init_command_list = __esm(() => {
|
|
|
19595
19622
|
"/later",
|
|
19596
19623
|
"/lt"
|
|
19597
19624
|
];
|
|
19598
|
-
KNOWN_COMMAND_PREFIX_SET = new Set(
|
|
19625
|
+
KNOWN_COMMAND_PREFIX_SET = new Set(XACPX_KNOWN_COMMAND_PREFIXES);
|
|
19599
19626
|
});
|
|
19600
19627
|
|
|
19601
19628
|
// src/commands/parse-command.ts
|
|
@@ -20085,7 +20112,7 @@ function normalizeCommand(command) {
|
|
|
20085
20112
|
return command;
|
|
20086
20113
|
}
|
|
20087
20114
|
function isRecognizedCommand(command) {
|
|
20088
|
-
return
|
|
20115
|
+
return isKnownXacpxCommandPrefix(command);
|
|
20089
20116
|
}
|
|
20090
20117
|
function toPermissionMode(value) {
|
|
20091
20118
|
if (value === "allow")
|
|
@@ -20599,6 +20626,23 @@ function applySupportedConfigUpdate(config4, path14, rawValue) {
|
|
|
20599
20626
|
}
|
|
20600
20627
|
return { renderedValue: rawValue };
|
|
20601
20628
|
}
|
|
20629
|
+
const channelMatch = path14.match(/^channels\.([^.]+)\.replyMode$/);
|
|
20630
|
+
if (channelMatch) {
|
|
20631
|
+
const [, id] = channelMatch;
|
|
20632
|
+
if (!id) {
|
|
20633
|
+
return { error: c.pathNotSupported(path14) };
|
|
20634
|
+
}
|
|
20635
|
+
const channel = config4.channels.find((entry) => entry.id === id);
|
|
20636
|
+
if (!channel) {
|
|
20637
|
+
return { error: c.channelRuntimeNotFound(id) };
|
|
20638
|
+
}
|
|
20639
|
+
const parsed = parseEnum(rawValue, ["stream", "final", "verbose"]);
|
|
20640
|
+
if (!parsed) {
|
|
20641
|
+
return { error: c.channelRuntimeReplyModeInvalid(id) };
|
|
20642
|
+
}
|
|
20643
|
+
channel.replyMode = parsed;
|
|
20644
|
+
return { renderedValue: parsed };
|
|
20645
|
+
}
|
|
20602
20646
|
return { error: c.pathNotSupported(path14) };
|
|
20603
20647
|
}
|
|
20604
20648
|
function parseEnum(value, allowed) {
|
|
@@ -20628,6 +20672,7 @@ var init_config_handler = __esm(() => {
|
|
|
20628
20672
|
"logging.maxFiles",
|
|
20629
20673
|
"logging.retentionDays",
|
|
20630
20674
|
"channel.replyMode",
|
|
20675
|
+
"channels.<id>.replyMode",
|
|
20631
20676
|
"agents.<name>.driver",
|
|
20632
20677
|
"agents.<name>.command",
|
|
20633
20678
|
"workspaces.<name>.cwd",
|
|
@@ -20968,6 +21013,20 @@ var init_build_coordinator_prompt = __esm(() => {
|
|
|
20968
21013
|
init_render_delegate_question_package();
|
|
20969
21014
|
});
|
|
20970
21015
|
|
|
21016
|
+
// src/commands/handlers/resolve-reply-mode.ts
|
|
21017
|
+
function resolveChannelDefaultReplyMode(config4, chatKey) {
|
|
21018
|
+
if (!config4)
|
|
21019
|
+
return;
|
|
21020
|
+
const channelId = getChannelIdFromChatKey(chatKey);
|
|
21021
|
+
return config4.channels.find((channel) => channel.id === channelId)?.replyMode;
|
|
21022
|
+
}
|
|
21023
|
+
function resolveEffectiveReplyMode(config4, chatKey, sessionOverride) {
|
|
21024
|
+
return sessionOverride ?? resolveChannelDefaultReplyMode(config4, chatKey) ?? config4?.channel.replyMode ?? "verbose";
|
|
21025
|
+
}
|
|
21026
|
+
var init_resolve_reply_mode = __esm(() => {
|
|
21027
|
+
init_channel_scope();
|
|
21028
|
+
});
|
|
21029
|
+
|
|
20971
21030
|
// src/commands/handlers/session-list-marker.ts
|
|
20972
21031
|
function decorateUnread(label, hasUnread) {
|
|
20973
21032
|
return hasUnread ? `● ${label}` : label;
|
|
@@ -21272,14 +21331,16 @@ async function handleReplyModeShow(context, chatKey) {
|
|
|
21272
21331
|
return { text: t().session.noCurrent };
|
|
21273
21332
|
}
|
|
21274
21333
|
const globalDefault = context.config?.channel.replyMode ?? "verbose";
|
|
21334
|
+
const channelDefault = resolveChannelDefaultReplyMode(context.config, chatKey);
|
|
21275
21335
|
const sessionOverride = session3.replyMode;
|
|
21276
|
-
const effective =
|
|
21336
|
+
const effective = resolveEffectiveReplyMode(context.config, chatKey, sessionOverride);
|
|
21277
21337
|
const s = t().session;
|
|
21278
21338
|
return {
|
|
21279
21339
|
text: [
|
|
21280
21340
|
s.replyModeHeader,
|
|
21281
21341
|
s.replyModeSessionLabel(toDisplaySessionAlias(session3.alias)),
|
|
21282
21342
|
s.replyModeGlobalDefault(globalDefault),
|
|
21343
|
+
s.replyModeChannelDefault(channelDefault ?? s.modeNotSet),
|
|
21283
21344
|
s.replyModeSessionOverride(sessionOverride ?? s.modeNotSet),
|
|
21284
21345
|
s.replyModeEffective(effective)
|
|
21285
21346
|
].join(`
|
|
@@ -21300,8 +21361,8 @@ async function handleReplyModeReset(context, chatKey) {
|
|
|
21300
21361
|
return { text: t().session.noCurrent };
|
|
21301
21362
|
}
|
|
21302
21363
|
await context.sessions.setCurrentSessionReplyMode(chatKey, undefined);
|
|
21303
|
-
const
|
|
21304
|
-
return { text: t().session.replyModeReset(
|
|
21364
|
+
const fallback = resolveEffectiveReplyMode(context.config, chatKey, undefined);
|
|
21365
|
+
return { text: t().session.replyModeReset(fallback) };
|
|
21305
21366
|
}
|
|
21306
21367
|
async function handleStatus(context, chatKey) {
|
|
21307
21368
|
const session3 = await context.sessions.getCurrentSession(chatKey);
|
|
@@ -21448,7 +21509,7 @@ async function handleSessionRemove(context, chatKey, alias) {
|
|
|
21448
21509
|
`) };
|
|
21449
21510
|
}
|
|
21450
21511
|
async function promptWithSession(context, session3, chatKey, text, reply, replyContextToken, accountId, media, abortSignal, onToolEvent, onThought, perfSpan, metadata) {
|
|
21451
|
-
const effectiveReplyMode =
|
|
21512
|
+
const effectiveReplyMode = resolveEffectiveReplyMode(context.config, chatKey, session3.replyMode);
|
|
21452
21513
|
if (!session3.replyMode)
|
|
21453
21514
|
session3.replyMode = effectiveReplyMode;
|
|
21454
21515
|
const transportReply = effectiveReplyMode !== "final" ? reply : undefined;
|
|
@@ -21596,6 +21657,7 @@ var DEFAULT_SESSION_TAIL_LINES = 50, MAX_SESSION_TAIL_LINES = 500;
|
|
|
21596
21657
|
var init_session_handler = __esm(() => {
|
|
21597
21658
|
init_build_coordinator_prompt();
|
|
21598
21659
|
init_channel_scope();
|
|
21660
|
+
init_resolve_reply_mode();
|
|
21599
21661
|
init_workspace_name();
|
|
21600
21662
|
init_i18n();
|
|
21601
21663
|
});
|
|
@@ -23647,23 +23709,43 @@ var init_translate_acpx_note = __esm(() => {
|
|
|
23647
23709
|
|
|
23648
23710
|
// src/commands/handlers/session-reset-handler.ts
|
|
23649
23711
|
async function handleSessionResetCommand(context, ops, chatKey) {
|
|
23650
|
-
const
|
|
23651
|
-
if (!
|
|
23712
|
+
const previous = await context.sessions.getCurrentSession(chatKey);
|
|
23713
|
+
if (!previous) {
|
|
23652
23714
|
return { text: t().misc.sessionResetNoCurrentSession };
|
|
23653
23715
|
}
|
|
23654
|
-
const
|
|
23716
|
+
const wasNative = previous.source === "agent-side";
|
|
23717
|
+
const resetSession = ops.resolveSession(previous.alias, previous.agent, previous.workspace, buildResetTransportSessionName(previous, ops.now()));
|
|
23655
23718
|
const releaseTransportReservation = await ops.reserveTransportSession(resetSession.transportSession);
|
|
23656
23719
|
try {
|
|
23657
23720
|
try {
|
|
23658
23721
|
await ops.ensureTransportSession(resetSession);
|
|
23659
23722
|
const exists = await ops.checkTransportSession(resetSession);
|
|
23660
23723
|
if (!exists) {
|
|
23661
|
-
return { text: t().misc.sessionResetFailed(
|
|
23724
|
+
return { text: t().misc.sessionResetFailed(previous.alias) };
|
|
23662
23725
|
}
|
|
23663
23726
|
} catch (error2) {
|
|
23664
23727
|
return renderTransportError(resetSession, error2);
|
|
23665
23728
|
}
|
|
23666
|
-
|
|
23729
|
+
let freshAgentSessionId;
|
|
23730
|
+
if (wasNative) {
|
|
23731
|
+
try {
|
|
23732
|
+
freshAgentSessionId = await context.transport.getAgentSessionId?.(resetSession);
|
|
23733
|
+
} catch (error2) {
|
|
23734
|
+
await context.logger.info("session.reset.native_id_unavailable", "failed to read fresh agent session id; falling back to xacpx session", { alias: resetSession.alias, error: error2 instanceof Error ? error2.message : String(error2) });
|
|
23735
|
+
}
|
|
23736
|
+
}
|
|
23737
|
+
if (wasNative && freshAgentSessionId) {
|
|
23738
|
+
await context.sessions.attachNativeSession({
|
|
23739
|
+
alias: resetSession.alias,
|
|
23740
|
+
agent: resetSession.agent,
|
|
23741
|
+
workspace: resetSession.workspace,
|
|
23742
|
+
transportSession: resetSession.transportSession,
|
|
23743
|
+
agentSessionId: freshAgentSessionId,
|
|
23744
|
+
updatedAt: new Date(ops.now()).toISOString()
|
|
23745
|
+
});
|
|
23746
|
+
} else {
|
|
23747
|
+
await context.sessions.attachSession(resetSession.alias, resetSession.agent, resetSession.workspace, resetSession.transportSession);
|
|
23748
|
+
}
|
|
23667
23749
|
await ops.refreshSessionTransportAgentCommand(resetSession.alias);
|
|
23668
23750
|
await context.sessions.useSession(chatKey, resetSession.alias);
|
|
23669
23751
|
await context.logger.info("session.reset", "reset current logical session", {
|
|
@@ -23671,8 +23753,19 @@ async function handleSessionResetCommand(context, ops, chatKey) {
|
|
|
23671
23753
|
agent: resetSession.agent,
|
|
23672
23754
|
workspace: resetSession.workspace,
|
|
23673
23755
|
transportSession: resetSession.transportSession,
|
|
23674
|
-
chatKey
|
|
23756
|
+
chatKey,
|
|
23757
|
+
native: wasNative && Boolean(freshAgentSessionId)
|
|
23675
23758
|
});
|
|
23759
|
+
if (wasNative && context.transport.removeSession && context.sessions.countAliasesSharingTransport(previous.transportSession) === 0) {
|
|
23760
|
+
try {
|
|
23761
|
+
await context.transport.removeSession(previous);
|
|
23762
|
+
} catch (error2) {
|
|
23763
|
+
await context.logger.info("session.reset.close_previous_failed", "failed to close previous native session after reset", {
|
|
23764
|
+
transportSession: previous.transportSession,
|
|
23765
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
23766
|
+
});
|
|
23767
|
+
}
|
|
23768
|
+
}
|
|
23676
23769
|
} finally {
|
|
23677
23770
|
await releaseTransportReservation();
|
|
23678
23771
|
}
|
|
@@ -24341,7 +24434,7 @@ class ConsoleAgent {
|
|
|
24341
24434
|
return await this.router.handle(request.conversationId, request.text, request.reply, request.replyContextToken, request.accountId, promptMedia, request.metadata, request.abortSignal, request.onToolEvent, request.onThought, request.perfSpan);
|
|
24342
24435
|
}
|
|
24343
24436
|
isKnownCommand(text) {
|
|
24344
|
-
return
|
|
24437
|
+
return isKnownXacpxCommandText(text);
|
|
24345
24438
|
}
|
|
24346
24439
|
async clearSession(conversationId) {
|
|
24347
24440
|
await this.router.clearSession?.(conversationId);
|
|
@@ -29165,7 +29258,7 @@ class DebouncedStateStore {
|
|
|
29165
29258
|
}
|
|
29166
29259
|
|
|
29167
29260
|
// src/commands/command-hints.ts
|
|
29168
|
-
function
|
|
29261
|
+
function listXacpxCommandHints() {
|
|
29169
29262
|
const hints3 = [{ name: "/help", description: t().hints.helpDescription }];
|
|
29170
29263
|
for (const topic of listHelpTopics()) {
|
|
29171
29264
|
const name = PRIMARY_COMMAND_BY_TOPIC[topic.topic];
|
|
@@ -29313,8 +29406,8 @@ async function runConsole(paths, deps) {
|
|
|
29313
29406
|
activeTurns: runtime.activeTurns,
|
|
29314
29407
|
logger: runtime.logger,
|
|
29315
29408
|
perfTracer: runtime.perfTracer,
|
|
29316
|
-
commandHints:
|
|
29317
|
-
coreVersion:
|
|
29409
|
+
commandHints: listXacpxCommandHints(),
|
|
29410
|
+
coreVersion: XACPX_CORE_VERSION,
|
|
29318
29411
|
locale: getLocale()
|
|
29319
29412
|
});
|
|
29320
29413
|
channelStartPromise.catch(() => {});
|
|
@@ -30006,6 +30099,10 @@ ${result.text}` : "" };
|
|
|
30006
30099
|
async removeSession(session3) {
|
|
30007
30100
|
await this.client.request("removeSession", this.toParams(session3));
|
|
30008
30101
|
}
|
|
30102
|
+
async getAgentSessionId(session3) {
|
|
30103
|
+
const result = await this.client.request("getAgentSessionId", this.toParams(session3));
|
|
30104
|
+
return result.agentSessionId;
|
|
30105
|
+
}
|
|
30009
30106
|
async hasSession(session3) {
|
|
30010
30107
|
const result = await this.client.request("hasSession", this.toParams(session3));
|
|
30011
30108
|
return result.exists;
|
|
@@ -30500,10 +30597,10 @@ import { spawn as spawn8 } from "node:child_process";
|
|
|
30500
30597
|
import { readFile as readFile12, unlink } from "node:fs/promises";
|
|
30501
30598
|
import { homedir as homedir8 } from "node:os";
|
|
30502
30599
|
import { join as join17 } from "node:path";
|
|
30503
|
-
function
|
|
30504
|
-
const { command, args } = splitCommandLine(input.
|
|
30600
|
+
function buildXacpxMcpServerSpec(input) {
|
|
30601
|
+
const { command, args } = splitCommandLine(input.xacpxCommand);
|
|
30505
30602
|
return {
|
|
30506
|
-
name: "
|
|
30603
|
+
name: "xacpx",
|
|
30507
30604
|
type: "stdio",
|
|
30508
30605
|
command,
|
|
30509
30606
|
args: [
|
|
@@ -30530,7 +30627,7 @@ function buildQueueOwnerPayload(input) {
|
|
|
30530
30627
|
|
|
30531
30628
|
class AcpxQueueOwnerLauncher {
|
|
30532
30629
|
acpxCommand;
|
|
30533
|
-
|
|
30630
|
+
xacpxCommand;
|
|
30534
30631
|
spawnOwner;
|
|
30535
30632
|
terminateOwner;
|
|
30536
30633
|
baseEnv;
|
|
@@ -30539,7 +30636,7 @@ class AcpxQueueOwnerLauncher {
|
|
|
30539
30636
|
launchLocks = new Map;
|
|
30540
30637
|
constructor(options) {
|
|
30541
30638
|
this.acpxCommand = options.acpxCommand;
|
|
30542
|
-
this.
|
|
30639
|
+
this.xacpxCommand = options.xacpxCommand ?? resolveDefaultXacpxCommand(options.baseEnv ?? process.env);
|
|
30543
30640
|
this.spawnOwner = options.spawnOwner ?? defaultQueueOwnerSpawner;
|
|
30544
30641
|
this.terminateOwner = options.terminateOwner ?? createDefaultQueueOwnerTerminator(options.acpxCommand);
|
|
30545
30642
|
this.baseEnv = options.baseEnv ?? process.env;
|
|
@@ -30567,8 +30664,8 @@ class AcpxQueueOwnerLauncher {
|
|
|
30567
30664
|
nonInteractivePermissions: input.nonInteractivePermissions,
|
|
30568
30665
|
ttlMs: this.ttlMs,
|
|
30569
30666
|
maxQueueDepth: this.maxQueueDepth,
|
|
30570
|
-
mcpServers: [
|
|
30571
|
-
|
|
30667
|
+
mcpServers: [buildXacpxMcpServerSpec({
|
|
30668
|
+
xacpxCommand: this.xacpxCommand,
|
|
30572
30669
|
coordinatorSession: input.coordinatorSession,
|
|
30573
30670
|
...input.sourceHandle ? { sourceHandle: input.sourceHandle } : {}
|
|
30574
30671
|
})]
|
|
@@ -30623,13 +30720,13 @@ function splitCommandLine(value) {
|
|
|
30623
30720
|
current += "\\";
|
|
30624
30721
|
}
|
|
30625
30722
|
if (quote) {
|
|
30626
|
-
throw new Error("
|
|
30723
|
+
throw new Error("xacpx MCP command has an unterminated quote");
|
|
30627
30724
|
}
|
|
30628
30725
|
if (current.length > 0) {
|
|
30629
30726
|
parts.push(current);
|
|
30630
30727
|
}
|
|
30631
30728
|
if (parts.length === 0) {
|
|
30632
|
-
throw new Error("
|
|
30729
|
+
throw new Error("xacpx MCP command must not be empty");
|
|
30633
30730
|
}
|
|
30634
30731
|
return { command: parts[0], args: parts.slice(1) };
|
|
30635
30732
|
}
|
|
@@ -30675,7 +30772,7 @@ function queueLockFilePath(sessionId) {
|
|
|
30675
30772
|
function shortHash(value, length) {
|
|
30676
30773
|
return createHash3("sha256").update(value).digest("hex").slice(0, length);
|
|
30677
30774
|
}
|
|
30678
|
-
function
|
|
30775
|
+
function resolveDefaultXacpxCommand(env) {
|
|
30679
30776
|
const cliCommand = coreEnv("CLI_COMMAND", env);
|
|
30680
30777
|
if (cliCommand?.trim()) {
|
|
30681
30778
|
return cliCommand.trim();
|
|
@@ -31026,8 +31123,9 @@ ${baseText}` : "" };
|
|
|
31026
31123
|
try {
|
|
31027
31124
|
const parsed = JSON.parse(result.stdout);
|
|
31028
31125
|
const acpxRecordId = typeof parsed.acpxRecordId === "string" ? parsed.acpxRecordId : typeof parsed.id === "string" ? parsed.id : undefined;
|
|
31126
|
+
const agentSessionId = typeof parsed.agentSessionId === "string" ? parsed.agentSessionId : undefined;
|
|
31029
31127
|
if (acpxRecordId) {
|
|
31030
|
-
return { acpxRecordId };
|
|
31128
|
+
return { acpxRecordId, agentSessionId };
|
|
31031
31129
|
}
|
|
31032
31130
|
} catch {
|
|
31033
31131
|
const firstLine = result.stdout.trim().split(/\r?\n/, 1)[0];
|
|
@@ -31037,6 +31135,10 @@ ${baseText}` : "" };
|
|
|
31037
31135
|
}
|
|
31038
31136
|
throw new Error("failed to resolve acpx session record id");
|
|
31039
31137
|
}
|
|
31138
|
+
async getAgentSessionId(session3) {
|
|
31139
|
+
const record3 = await this.readSessionRecord(session3);
|
|
31140
|
+
return record3.agentSessionId;
|
|
31141
|
+
}
|
|
31040
31142
|
async run(args, options) {
|
|
31041
31143
|
const result = await this.runCommandWithTimeout(this.runCommand, args, options);
|
|
31042
31144
|
if (result.code !== 0) {
|
|
@@ -33573,7 +33675,7 @@ class DaemonRuntime {
|
|
|
33573
33675
|
}
|
|
33574
33676
|
}
|
|
33575
33677
|
|
|
33576
|
-
// src/mcp/
|
|
33678
|
+
// src/mcp/xacpx-mcp-server.ts
|
|
33577
33679
|
import { stdin, stdout } from "node:process";
|
|
33578
33680
|
|
|
33579
33681
|
// node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/core.js
|
|
@@ -45929,7 +46031,7 @@ class StdioServerTransport {
|
|
|
45929
46031
|
}
|
|
45930
46032
|
}
|
|
45931
46033
|
|
|
45932
|
-
// src/mcp/
|
|
46034
|
+
// src/mcp/xacpx-mcp-server.ts
|
|
45933
46035
|
init_version();
|
|
45934
46036
|
|
|
45935
46037
|
// src/mcp/resolve-endpoint.ts
|
|
@@ -45957,7 +46059,7 @@ function requireHome(env) {
|
|
|
45957
46059
|
return home;
|
|
45958
46060
|
}
|
|
45959
46061
|
|
|
45960
|
-
// src/mcp/
|
|
46062
|
+
// src/mcp/xacpx-mcp-tools.ts
|
|
45961
46063
|
init_task_watch_timeouts();
|
|
45962
46064
|
init_quota_errors();
|
|
45963
46065
|
var taskStatusSchema = exports_external.enum([
|
|
@@ -45978,7 +46080,7 @@ var taskQuestionSchema = exports_external.object({
|
|
|
45978
46080
|
taskId: exports_external.string().min(1),
|
|
45979
46081
|
questionId: exports_external.string().min(1)
|
|
45980
46082
|
}).strict();
|
|
45981
|
-
function
|
|
46083
|
+
function buildXacpxMcpToolRegistry(input) {
|
|
45982
46084
|
const { transport, coordinatorSession, sourceHandle, isExternalCoordinator, internalSessionTools, availableAgents } = input;
|
|
45983
46085
|
const tools = [
|
|
45984
46086
|
{
|
|
@@ -46136,7 +46238,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
46136
46238
|
}).strict(),
|
|
46137
46239
|
handler: async (args) => await asToolResult(async () => {
|
|
46138
46240
|
if (!sourceHandle || sourceHandle.trim().length === 0) {
|
|
46139
|
-
throw new Error("worker_raise_question requires a bound sourceHandle; start mcp-stdio with --source-handle or
|
|
46241
|
+
throw new Error("worker_raise_question requires a bound sourceHandle; start mcp-stdio with --source-handle or XACPX_SOURCE_HANDLE");
|
|
46140
46242
|
}
|
|
46141
46243
|
const result = await transport.workerRaiseQuestion({
|
|
46142
46244
|
sourceHandle,
|
|
@@ -46199,7 +46301,7 @@ function buildWeacpxMcpToolRegistry(input) {
|
|
|
46199
46301
|
if (internalSessionTools && !isExternalCoordinator && !sourceHandle) {
|
|
46200
46302
|
tools.push({
|
|
46201
46303
|
name: "scheduled_create",
|
|
46202
|
-
description: "Schedule a one-shot task to run a natural-language message at a future time, using the recorded chat route. By default — and like /later — the task runs in a FRESH TEMPORARY session (it snapshots the current agent and workspace but starts with brand-new history and is destroyed after running, so it does not pollute this conversation); the reply is still pushed back to this chat. Provide only timeText and message and OMIT mode to get this default. Routing, session, and account are resolved by
|
|
46304
|
+
description: "Schedule a one-shot task to run a natural-language message at a future time, using the recorded chat route. By default — and like /later — the task runs in a FRESH TEMPORARY session (it snapshots the current agent and workspace but starts with brand-new history and is destroyed after running, so it does not pollute this conversation); the reply is still pushed back to this chat. Provide only timeText and message and OMIT mode to get this default. Routing, session, and account are resolved by xacpx.",
|
|
46203
46305
|
inputSchema: exports_external.object({
|
|
46204
46306
|
timeText: exports_external.string().min(1).describe("Time expression, e.g. 'in 2h', '30分钟后', 'tomorrow 09:00', or '周五 09:00'."),
|
|
46205
46307
|
message: exports_external.string().min(1).describe("Natural-language message to run at the scheduled time."),
|
|
@@ -46609,7 +46711,7 @@ function getWatchRequestTimeoutMs(watchTimeoutMs, defaultTimeoutMs) {
|
|
|
46609
46711
|
return Math.max(defaultTimeoutMs, boundedWatchTimeoutMs + TASK_WATCH_RPC_TIMEOUT_PADDING_MS);
|
|
46610
46712
|
}
|
|
46611
46713
|
|
|
46612
|
-
// src/mcp/
|
|
46714
|
+
// src/mcp/xacpx-mcp-transport.ts
|
|
46613
46715
|
function createOrchestrationTransport(endpoint, deps = {}) {
|
|
46614
46716
|
const client = deps.client ?? new OrchestrationClient(endpoint);
|
|
46615
46717
|
return {
|
|
@@ -46637,7 +46739,7 @@ function createOrchestrationTransport(endpoint, deps = {}) {
|
|
|
46637
46739
|
workerRaiseQuestion: async (input) => {
|
|
46638
46740
|
const sourceHandle = input.sourceHandle.trim();
|
|
46639
46741
|
if (sourceHandle.length === 0) {
|
|
46640
|
-
throw new Error("worker_raise_question requires a bound sourceHandle; start mcp-stdio with --source-handle or
|
|
46742
|
+
throw new Error("worker_raise_question requires a bound sourceHandle; start mcp-stdio with --source-handle or XACPX_SOURCE_HANDLE");
|
|
46641
46743
|
}
|
|
46642
46744
|
return await client.workerRaiseQuestion({
|
|
46643
46745
|
taskId: input.taskId,
|
|
@@ -46671,11 +46773,11 @@ function createOrchestrationTransport(endpoint, deps = {}) {
|
|
|
46671
46773
|
};
|
|
46672
46774
|
}
|
|
46673
46775
|
|
|
46674
|
-
// src/mcp/
|
|
46776
|
+
// src/mcp/xacpx-mcp-server.ts
|
|
46675
46777
|
var TASK_OPTIONS_CACHE_LIMIT = 1000;
|
|
46676
46778
|
var TASKS_LIST_PAGE_SIZE = 100;
|
|
46677
46779
|
var WATCH_TASKS_CACHE_LIMIT = 256;
|
|
46678
|
-
var
|
|
46780
|
+
var XACPX_MCP_SERVER_INSTRUCTIONS = [
|
|
46679
46781
|
"Use these tools to orchestrate work across other agents under your coordinator session.",
|
|
46680
46782
|
"",
|
|
46681
46783
|
"Delegate with delegate_request (one task) or delegate_batch (several at once). Each returns a taskId and a status.",
|
|
@@ -46686,12 +46788,12 @@ var WEACPX_MCP_SERVER_INSTRUCTIONS = [
|
|
|
46686
46788
|
"worker_raise_question is worker-side only — call it from inside a delegated task when you are blocked, not from the coordinator waiting on a delegation."
|
|
46687
46789
|
].join(`
|
|
46688
46790
|
`);
|
|
46689
|
-
function
|
|
46791
|
+
function createXacpxMcpServer(options) {
|
|
46690
46792
|
let getToolState;
|
|
46691
46793
|
const taskOptionsById = new Map;
|
|
46692
46794
|
const watchTasksById = new Map;
|
|
46693
46795
|
const server = new Server({
|
|
46694
|
-
name: "
|
|
46796
|
+
name: "xacpx",
|
|
46695
46797
|
version: readVersion()
|
|
46696
46798
|
}, {
|
|
46697
46799
|
capabilities: {
|
|
@@ -46702,8 +46804,8 @@ function createWeacpxMcpServer(options) {
|
|
|
46702
46804
|
requests: { tools: { call: {} } }
|
|
46703
46805
|
}
|
|
46704
46806
|
},
|
|
46705
|
-
instructions:
|
|
46706
|
-
taskStore:
|
|
46807
|
+
instructions: XACPX_MCP_SERVER_INSTRUCTIONS,
|
|
46808
|
+
taskStore: createXacpxTaskStore(async () => await getToolState(), taskOptionsById, watchTasksById)
|
|
46707
46809
|
});
|
|
46708
46810
|
let toolState = null;
|
|
46709
46811
|
let toolStatePromise = null;
|
|
@@ -46716,7 +46818,7 @@ function createWeacpxMcpServer(options) {
|
|
|
46716
46818
|
}
|
|
46717
46819
|
toolStatePromise = resolveMcpIdentity(server, options).then((identity) => {
|
|
46718
46820
|
if (!options.transport) {
|
|
46719
|
-
throw new Error("
|
|
46821
|
+
throw new Error("xacpx MCP transport is not configured");
|
|
46720
46822
|
}
|
|
46721
46823
|
toolState = buildToolState({
|
|
46722
46824
|
transport: options.transport,
|
|
@@ -46797,7 +46899,7 @@ function createWeacpxMcpServer(options) {
|
|
|
46797
46899
|
return server;
|
|
46798
46900
|
}
|
|
46799
46901
|
function buildToolState(options) {
|
|
46800
|
-
const tools =
|
|
46902
|
+
const tools = buildXacpxMcpToolRegistry(options);
|
|
46801
46903
|
return {
|
|
46802
46904
|
tools,
|
|
46803
46905
|
toolMap: new Map(tools.map((tool) => [tool.name, tool])),
|
|
@@ -46956,10 +47058,10 @@ function renderWatchMcpTaskResult(result, watchTaskId) {
|
|
|
46956
47058
|
structuredContent: { watchTaskId, ...result }
|
|
46957
47059
|
};
|
|
46958
47060
|
}
|
|
46959
|
-
function
|
|
47061
|
+
function createXacpxTaskStore(resolveState, taskOptionsById, watchTasksById) {
|
|
46960
47062
|
return {
|
|
46961
47063
|
createTask: async () => {
|
|
46962
|
-
throw new Error("
|
|
47064
|
+
throw new Error("xacpx native MCP tasks are created by delegate_request");
|
|
46963
47065
|
},
|
|
46964
47066
|
getTask: async (taskId) => {
|
|
46965
47067
|
const watchTask = watchTasksById.get(taskId);
|
|
@@ -46970,7 +47072,7 @@ function createWeacpxTaskStore(resolveState, taskOptionsById, watchTasksById) {
|
|
|
46970
47072
|
return task ? toMcpTask(task, taskOptionsById.get(taskId)) : null;
|
|
46971
47073
|
},
|
|
46972
47074
|
storeTaskResult: async () => {
|
|
46973
|
-
throw new Error("
|
|
47075
|
+
throw new Error("xacpx native MCP task results are stored by orchestration");
|
|
46974
47076
|
},
|
|
46975
47077
|
getTaskResult: async (taskId) => {
|
|
46976
47078
|
const watchTask = watchTasksById.get(taskId);
|
|
@@ -46994,7 +47096,7 @@ function createWeacpxTaskStore(resolveState, taskOptionsById, watchTasksById) {
|
|
|
46994
47096
|
await state.transport.cancelTask({ coordinatorSession: state.coordinatorSession, taskId });
|
|
46995
47097
|
return;
|
|
46996
47098
|
}
|
|
46997
|
-
throw new Error(`
|
|
47099
|
+
throw new Error(`xacpx MCP task status is read-only (${status}${statusMessage ? `: ${statusMessage}` : ""})`);
|
|
46998
47100
|
},
|
|
46999
47101
|
listTasks: async (cursor) => {
|
|
47000
47102
|
const state = await resolveState();
|
|
@@ -47254,9 +47356,9 @@ function defaultIsProcessRunning3(pid) {
|
|
|
47254
47356
|
return code !== "ESRCH";
|
|
47255
47357
|
}
|
|
47256
47358
|
}
|
|
47257
|
-
async function
|
|
47359
|
+
async function runXacpxMcpServer(options) {
|
|
47258
47360
|
const transport = options.transport ?? createOrchestrationTransport(options.endpoint ?? resolveDefaultOrchestrationEndpoint(process.env, process.platform));
|
|
47259
|
-
const server =
|
|
47361
|
+
const server = createXacpxMcpServer({
|
|
47260
47362
|
transport,
|
|
47261
47363
|
...options.coordinatorSession ? { coordinatorSession: options.coordinatorSession } : {},
|
|
47262
47364
|
...options.sourceHandle ? { sourceHandle: options.sourceHandle } : {},
|
|
@@ -47841,6 +47943,10 @@ async function handleChannelCli(args, deps) {
|
|
|
47841
47943
|
if (args.length < 2 || !args[1])
|
|
47842
47944
|
return null;
|
|
47843
47945
|
return await dispatchSetEnabled(args[1], false, args.slice(2), deps);
|
|
47946
|
+
case "set-reply-mode":
|
|
47947
|
+
if (args.length < 3 || !args[1] || !args[2])
|
|
47948
|
+
return null;
|
|
47949
|
+
return await setChannelReplyMode(args[1], args[2], args.slice(3), deps);
|
|
47844
47950
|
default:
|
|
47845
47951
|
return null;
|
|
47846
47952
|
}
|
|
@@ -48157,6 +48263,28 @@ async function setChannelEnabled(type, enabled, rawArgs, deps) {
|
|
|
48157
48263
|
deps.print(t().channelCli.channelEnabledToggled(channel.id, enabled));
|
|
48158
48264
|
return await maybeRestartAfterMutation(restartFlags.restart, deps);
|
|
48159
48265
|
}
|
|
48266
|
+
async function setChannelReplyMode(type, mode, rawArgs, deps) {
|
|
48267
|
+
const restartFlags = parseRestartFlags(rawArgs);
|
|
48268
|
+
if (!restartFlags.ok) {
|
|
48269
|
+
deps.print(restartFlags.message);
|
|
48270
|
+
return 1;
|
|
48271
|
+
}
|
|
48272
|
+
if (mode !== "stream" && mode !== "final" && mode !== "verbose") {
|
|
48273
|
+
deps.print(t().channelCli.channelReplyModeInvalid(mode));
|
|
48274
|
+
return 1;
|
|
48275
|
+
}
|
|
48276
|
+
const config4 = await deps.loadConfig();
|
|
48277
|
+
ensureChannelsArray(config4);
|
|
48278
|
+
const channel = findChannel(config4.channels, type);
|
|
48279
|
+
if (!channel) {
|
|
48280
|
+
deps.print(t().channelCli.channelNotFound(type));
|
|
48281
|
+
return 1;
|
|
48282
|
+
}
|
|
48283
|
+
channel.replyMode = mode;
|
|
48284
|
+
await deps.saveConfig(config4);
|
|
48285
|
+
deps.print(t().channelCli.channelReplyModeSet(channel.id, mode));
|
|
48286
|
+
return await maybeRestartAfterMutation(restartFlags.restart, deps);
|
|
48287
|
+
}
|
|
48160
48288
|
function requireMultiAccountProvider(type, deps) {
|
|
48161
48289
|
const provider = getChannelCliProvider(type);
|
|
48162
48290
|
if (!provider) {
|
|
@@ -48483,7 +48611,7 @@ async function inspectPlugins(input) {
|
|
|
48483
48611
|
}
|
|
48484
48612
|
try {
|
|
48485
48613
|
const plugin = validateWeacpxPlugin(moduleValue, configPlugin.name, {
|
|
48486
|
-
...input.
|
|
48614
|
+
...input.currentXacpxVersion !== undefined ? { currentXacpxVersion: input.currentXacpxVersion } : {}
|
|
48487
48615
|
});
|
|
48488
48616
|
const channels = plugin.channels ?? [];
|
|
48489
48617
|
const channelTypes = channels.map((channel) => channel.type);
|
|
@@ -49826,7 +49954,7 @@ async function defaultMcpStdio(args, deps = {}) {
|
|
|
49826
49954
|
`);
|
|
49827
49955
|
return 2;
|
|
49828
49956
|
}
|
|
49829
|
-
await
|
|
49957
|
+
await runXacpxMcpServer({
|
|
49830
49958
|
transport,
|
|
49831
49959
|
...coordinatorSession ? { coordinatorSession } : {},
|
|
49832
49960
|
...sourceHandle ? { sourceHandle } : {},
|