@ynhcj/xiaoyi-channel 0.0.104-next → 0.0.105-next

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/bot.js CHANGED
@@ -253,7 +253,9 @@ export async function handleXYMessage(params) {
253
253
  log(`[BOT-DISPATCHER] ✅ Status interval started for first message`);
254
254
  }
255
255
  log(`[BOT-DISPATCH] ⏳ withReplyDispatcher starting, sessionKey=${route.sessionKey}`);
256
- await core.channel.reply.withReplyDispatcher({
256
+ // 🔐 Set ALS BEFORE withReplyDispatcher so agentTools factory can read it
257
+ // during dispatcher setup (which happens before run() is called).
258
+ await xyAsyncLocalStorage.run({ openclawSessionKey: route.sessionKey }, () => core.channel.reply.withReplyDispatcher({
257
259
  dispatcher,
258
260
  onSettled: () => {
259
261
  log(`[BOT] 🏁 onSettled called for session: ${route.sessionKey}`);
@@ -261,9 +263,7 @@ export async function handleXYMessage(params) {
261
263
  unregisterSession(route.sessionKey);
262
264
  log(`[BOT] ✅ Cleanup completed`);
263
265
  },
264
- run: () =>
265
- // 🔐 Run inside ALS with openclawSessionKey so agentTools factory can read it
266
- xyAsyncLocalStorage.run({ openclawSessionKey: route.sessionKey }, async () => {
266
+ run: async () => {
267
267
  log(`[BOT-DISPATCH] ⏳ dispatchReplyFromConfig starting...`);
268
268
  log(`[BOT-DISPATCH] - sessionKey: ${ctxPayload.SessionKey}`);
269
269
  log(`[BOT-DISPATCH] - provider: ${ctxPayload.Provider}`);
@@ -288,8 +288,8 @@ export async function handleXYMessage(params) {
288
288
  error(`[BOT-DISPATCH] - error stack: ${dispatchErr instanceof Error ? dispatchErr.stack?.slice(0, 500) : "N/A"}`);
289
289
  throw dispatchErr;
290
290
  }
291
- }),
292
- });
291
+ },
292
+ }));
293
293
  log(`[BOT] ✅ Dispatcher completed for session: ${parsed.sessionId}`);
294
294
  log(`xy: dispatch complete (session=${parsed.sessionId})`);
295
295
  }
@@ -454,9 +454,34 @@ export const xiaoyiProvider = {
454
454
  ? getSession(alsContext.openclawSessionKey)?.a2aSessionId ?? null
455
455
  : null;
456
456
  return async (model, context, options) => {
457
- // 每次请求时从 ctx.extraParams 动态读取 header
458
457
  const dynamicHeaders = {};
459
- if (ctx.extraParams) {
458
+ // Priority: session store lookup (captured a2aSessionId) → prepareExtraParams cache → uid fallback
459
+ // We check capturedA2ASessionId FIRST because OpenClaw caches prepareExtraParams
460
+ // by provider/modelId (not per-session). A previous call without ALS may have
461
+ // populated the cache with FALLBACK_PREFIX_KEY, which would shadow the session
462
+ // lookup if we checked it first.
463
+ let resolvedTaskId = null;
464
+ if (capturedA2ASessionId) {
465
+ resolvedTaskId = getSessionByA2AId(capturedA2ASessionId)?.taskId ?? null;
466
+ }
467
+ if (resolvedTaskId) {
468
+ // Session mode: use taskId from store (supports steer).
469
+ const sessionId = resolvedTaskId.split("&")[0];
470
+ const interactionId = resolvedTaskId.split("&")[1] || "";
471
+ const isCron = isCronTriggered(context.messages);
472
+ dynamicHeaders[HEADER_TRACE_ID] = isCron ? `cron_${resolvedTaskId}_${Date.now()}` : resolvedTaskId;
473
+ dynamicHeaders[HEADER_SESSION_ID] = sessionId;
474
+ dynamicHeaders[HEADER_INTERACTION_ID] = interactionId;
475
+ if (isCron) {
476
+ const cronTitle = extractCronTitle(context.messages);
477
+ if (cronTitle)
478
+ dynamicHeaders["x-cron-title"] = encodeURIComponent(cronTitle);
479
+ if (context.messages?.length === 1)
480
+ dynamicHeaders["x-cron-flag"] = "begin";
481
+ }
482
+ }
483
+ else if (ctx.extraParams) {
484
+ // No active session — try extraParams (may contain cached prepareExtraParams result).
460
485
  const fallbackPrefix = ctx.extraParams[FALLBACK_PREFIX_KEY];
461
486
  if (typeof fallbackPrefix === "string") {
462
487
  // Fallback mode: generate fresh timestamp per request
@@ -474,18 +499,10 @@ export const xiaoyiProvider = {
474
499
  }
475
500
  }
476
501
  else {
477
- // Session mode: resolve taskId from store using captured a2aSessionId.
478
- // This always returns the latest taskId (supports steer).
479
- let resolvedTaskId = null;
480
- if (capturedA2ASessionId) {
481
- resolvedTaskId = getSessionByA2AId(capturedA2ASessionId)?.taskId ?? null;
482
- }
483
- const traceId = resolvedTaskId ?? ctx.extraParams[HEADER_TRACE_ID];
484
- const sessionId = resolvedTaskId?.split("&")[0]
485
- ?? ctx.extraParams[HEADER_SESSION_ID];
486
- const interactionId = resolvedTaskId?.split("&")[1]
487
- ?? ctx.extraParams[HEADER_INTERACTION_ID]
488
- ?? "";
502
+ // No captured session, no fallback use whatever is in prepareExtraParams cache.
503
+ const traceId = ctx.extraParams[HEADER_TRACE_ID];
504
+ const sessionId = ctx.extraParams[HEADER_SESSION_ID];
505
+ const interactionId = ctx.extraParams[HEADER_INTERACTION_ID];
489
506
  if (typeof traceId === "string") {
490
507
  const isCron = isCronTriggered(context.messages);
491
508
  dynamicHeaders[HEADER_TRACE_ID] = isCron ? `cron_${traceId}_${Date.now()}` : traceId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ynhcj/xiaoyi-channel",
3
- "version": "0.0.104-next",
3
+ "version": "0.0.105-next",
4
4
  "description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",