@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.
package/dist/src/monitor.js
CHANGED
|
@@ -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
|
package/dist/src/provider.js
CHANGED
|
@@ -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
|
|
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`);
|