@ynhcj/xiaoyi-channel 0.0.98-beta → 0.0.99-beta

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.
@@ -71,7 +71,6 @@ export async function monitorXYProvider(opts = {}) {
71
71
  const messageHandler = (message, sessionId, serverId) => {
72
72
  const messageKey = `${sessionId}::${message.id}`;
73
73
  log(`[MONITOR-HANDLER] ####### messageHandler triggered: sessionId=${sessionId}, messageId=${message.id} #######`);
74
- console.log(`[MONITOR-HANDLER] A2A message body: ${JSON.stringify(message)}`);
75
74
  // ✅ Report health: received a message
76
75
  trackEvent?.();
77
76
  // Check for duplicate message handling
@@ -41,6 +41,25 @@ function isCronTriggered(messages) {
41
41
  }
42
42
  return /^\[cron:/i.test(text.trim());
43
43
  }
44
+ /** Extract cron title from first user message matching `[cron:<uuid> <title>]`. */
45
+ function extractCronTitle(messages) {
46
+ if (!messages)
47
+ return undefined;
48
+ const firstUser = messages.find(m => m.role === "user");
49
+ if (!firstUser)
50
+ return undefined;
51
+ let text = "";
52
+ if (typeof firstUser.content === "string") {
53
+ text = firstUser.content;
54
+ }
55
+ else if (Array.isArray(firstUser.content)) {
56
+ const block = firstUser.content.find(b => b.type === "text" && typeof b.text === "string");
57
+ if (block)
58
+ text = block.text;
59
+ }
60
+ const match = text.trim().match(/^\[cron:[^\s]+\s+(.+)\]$/);
61
+ return match ? match[1] : undefined;
62
+ }
44
63
  /** Compute retry delay in ms for the given 1-based attempt, with up to 10s jitter. */
45
64
  function getRetryDelayMs(attempt, isCron = false) {
46
65
  if (isCron) {
@@ -293,6 +312,11 @@ export const xiaoyiProvider = {
293
312
  dynamicHeaders[HEADER_TRACE_ID] = isCron ? `cron_${fallbackValue}` : fallbackValue;
294
313
  dynamicHeaders[HEADER_SESSION_ID] = fallbackValue;
295
314
  dynamicHeaders[HEADER_INTERACTION_ID] = fallbackValue;
315
+ if (isCron) {
316
+ const cronTitle = extractCronTitle(context.messages);
317
+ if (cronTitle)
318
+ dynamicHeaders["x-cron-title"] = cronTitle;
319
+ }
296
320
  }
297
321
  else {
298
322
  // Session mode: use pre-resolved session headers + fresh timestamp
@@ -303,6 +327,11 @@ export const xiaoyiProvider = {
303
327
  if (typeof traceId === "string") {
304
328
  const isCron = isCronTriggered(context.messages);
305
329
  dynamicHeaders[HEADER_TRACE_ID] = isCron ? `cron_${traceId}${ts}` : `${traceId}${ts}`;
330
+ if (isCron) {
331
+ const cronTitle = extractCronTitle(context.messages);
332
+ if (cronTitle)
333
+ dynamicHeaders["x-cron-title"] = cronTitle;
334
+ }
306
335
  }
307
336
  if (typeof sessionId === "string")
308
337
  dynamicHeaders[HEADER_SESSION_ID] = sessionId;
@@ -38,30 +38,22 @@ export function createBeforePromptBuildHandler(config) {
38
38
  return async (event, ctx) => {
39
39
  const userPrompt = event.prompt;
40
40
  if (ctx?.sessionKey?.includes(":subagent:")) {
41
- console.log(`${PLUGIN_LOG_PREFIX} [SKIP] Sub-agent detected, skipping search`);
42
41
  return undefined;
43
42
  }
44
43
  if (!config.enabled) {
45
- console.log(`${PLUGIN_LOG_PREFIX} [SKIP] Plugin disabled, original query: "${userPrompt}"`);
46
44
  return undefined;
47
45
  }
48
46
  if (!userPrompt || userPrompt.trim().length === 0) {
49
- console.log(`${PLUGIN_LOG_PREFIX} [SKIP] Empty query`);
50
47
  return undefined;
51
48
  }
52
- console.log(`${PLUGIN_LOG_PREFIX} [RECEIVED] Original user query (len=${userPrompt.length}): "${userPrompt}"`);
53
49
  const extractedQuery = extractUserQuery(userPrompt);
54
- console.log(`${PLUGIN_LOG_PREFIX} [EXTRACTED] Extracted user query: "${extractedQuery}"`);
55
50
  if (!extractedQuery || extractedQuery.length === 0) {
56
- console.log(`${PLUGIN_LOG_PREFIX} [SKIP] No valid user query after extraction, skipping search`);
57
51
  return undefined;
58
52
  }
59
53
  const skipReason = shouldSkipSearch(extractedQuery);
60
54
  if (skipReason) {
61
- console.log(`${PLUGIN_LOG_PREFIX} [SKIP] ${skipReason}, extracted query: "${extractedQuery}"`);
62
55
  return undefined;
63
56
  }
64
- console.log(`${PLUGIN_LOG_PREFIX} [PROCEED] Calling skill search API (timeout=${config.timeoutMs}ms) for query: "${extractedQuery}"`);
65
57
  try {
66
58
  const searchResult = await searchTools({
67
59
  query: extractedQuery,
@@ -74,16 +66,14 @@ export function createBeforePromptBuildHandler(config) {
74
66
  timeoutMs: config.timeoutMs,
75
67
  });
76
68
  if (!searchResult || searchResult.tools.length === 0) {
77
- console.log(`${PLUGIN_LOG_PREFIX} [RESULT] No skills found for query: "${extractedQuery}"`);
78
69
  return undefined;
79
70
  }
80
71
  console.log(`${PLUGIN_LOG_PREFIX} [RESULT] Found ${searchResult.tools.length} skills, building context...`);
81
72
  const toolsContext = formatToolsForContext(searchResult, config.includeUninstalledOnly);
82
73
  if (!toolsContext) {
83
- console.log(`${PLUGIN_LOG_PREFIX} [ERROR] Failed to format skills context for query: "${extractedQuery}"`);
74
+ console.log(`${PLUGIN_LOG_PREFIX} [ERROR] Failed to format skills context`);
84
75
  return undefined;
85
76
  }
86
- console.log(`${PLUGIN_LOG_PREFIX} [SUCCESS] Built context with ${searchResult.tools.length} skills for query: "${extractedQuery}"`);
87
77
  return {
88
78
  prependContext: TOOL_RETRIEVER_HEADER + toolsContext + TOOL_RETRIEVER_FOOTER,
89
79
  };
@@ -81,7 +81,6 @@ export async function searchTools(options) {
81
81
  const { query, maxTools = 5, includeUninstalledOnly = true, envFilePath = "~/.openclaw/.xiaoyienv", serviceUrl: configServiceUrl, apiKey: configApiKey, uid: configUid, timeoutMs = 1000, } = options;
82
82
  const envConfig = readEnvFile(envFilePath);
83
83
  const hasRequiredConfig = !!envConfig.SERVICE_URL && !!envConfig.PERSONAL_API_KEY && !!envConfig.PERSONAL_UID;
84
- console.log(`${PLUGIN_LOG_PREFIX} Env file loaded: ${hasRequiredConfig}, keys: ${Object.keys(envConfig).join(", ")}`);
85
84
  const serviceUrl = configServiceUrl ?? envConfig.SERVICE_URL;
86
85
  const apiKey = configApiKey ?? envConfig.PERSONAL_API_KEY;
87
86
  const uid = configUid ?? envConfig.PERSONAL_UID;
@@ -89,7 +88,6 @@ export async function searchTools(options) {
89
88
  console.warn(`${PLUGIN_LOG_PREFIX} Missing required configuration. serviceUrl: "${serviceUrl}", apiKey: "${apiKey ? '(set)' : '(missing)'} ", uid: "${uid ? '(set)' : '(missing)'}"`);
90
89
  return null;
91
90
  }
92
- console.log(`${PLUGIN_LOG_PREFIX} Configuration loaded - serviceUrl: ${serviceUrl}, uid: ${uid}`);
93
91
  const traceId = crypto.randomUUID();
94
92
  const apiUrl = `${serviceUrl}/celia-claw/v1/rest-api/skill/execute`;
95
93
  const headers = {
@@ -101,7 +99,6 @@ export async function searchTools(options) {
101
99
  "x-request-from": "openclaw",
102
100
  };
103
101
  const payload = { query };
104
- console.log(`${PLUGIN_LOG_PREFIX} [USER_REQUEST] origin-query:${query}, payload:${JSON.stringify(payload)}`);
105
102
  try {
106
103
  const response = await fetch(apiUrl, {
107
104
  method: "POST",
@@ -119,13 +116,9 @@ export async function searchTools(options) {
119
116
  responseData.content &&
120
117
  responseData.content.skills) {
121
118
  const rawSkills = responseData.content.skills;
122
- console.log(`${PLUGIN_LOG_PREFIX} [DEBUG] Raw skills from API: ${rawSkills.length}, ids: ${rawSkills.map((s) => s.skillId).join(", ")}`);
123
119
  const installedSkills = getInstalledSkills();
124
- console.log(`${PLUGIN_LOG_PREFIX} [DEBUG] Installed skills: ${installedSkills.length}, ids: ${installedSkills.join(", ")}`);
125
120
  const formattedData = formatSkillData(rawSkills, installedSkills);
126
- console.log(`${PLUGIN_LOG_PREFIX} [DEBUG] Formatted skills: ${formattedData.length}, statuses: ${formattedData.map((t) => `${t.skillId}:${t.status}`).join(", ")}`);
127
121
  const topTools = formattedData.slice(0, 2);
128
- console.log(`${PLUGIN_LOG_PREFIX} [DEBUG] Top 2 skills: ${topTools.length}, statuses: ${topTools.map((t) => `${t.skillId}:${t.status}`).join(", ")}`);
129
122
  const allInstalled = topTools.every((tool) => tool.status === "已安装");
130
123
  if (allInstalled) {
131
124
  console.log(`${PLUGIN_LOG_PREFIX} [DEBUG] All top 2 skills are installed, returning null`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.98-beta",
3
+ "version": "0.0.99-beta",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",