@ynhcj/xiaoyi-channel 0.0.137-next → 0.0.138-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 +2 -2
- package/dist/src/provider.js +45 -87
- package/package.json +1 -1
package/dist/src/bot.js
CHANGED
|
@@ -270,7 +270,7 @@ export async function handleXYMessage(params) {
|
|
|
270
270
|
SenderId: parsed.sessionId,
|
|
271
271
|
Provider: "xiaoyi-channel",
|
|
272
272
|
Surface: "xiaoyi-channel",
|
|
273
|
-
MessageSid:
|
|
273
|
+
MessageSid: `xiaoyi_${parsed.taskId}_${deviceType}`,
|
|
274
274
|
Timestamp: Date.now(),
|
|
275
275
|
WasMentioned: false,
|
|
276
276
|
CommandAuthorized: true,
|
|
@@ -532,7 +532,7 @@ async function dispatchSteerWhenReady(params) {
|
|
|
532
532
|
SenderId: sessionId,
|
|
533
533
|
Provider: "xiaoyi-channel",
|
|
534
534
|
Surface: "xiaoyi-channel",
|
|
535
|
-
MessageSid:
|
|
535
|
+
MessageSid: `xiaoyi_${params.parsed.taskId}_${params.deviceType}`,
|
|
536
536
|
Timestamp: Date.now(),
|
|
537
537
|
WasMentioned: false,
|
|
538
538
|
CommandAuthorized: true,
|
package/dist/src/provider.js
CHANGED
|
@@ -236,8 +236,6 @@ const HEADER_SESSION_ID = "x-session-id";
|
|
|
236
236
|
const HEADER_INTERACTION_ID = "x-interaction-id";
|
|
237
237
|
/** Internal key for passing fallback uid prefix from prepareExtraParams to wrapStreamFn. */
|
|
238
238
|
const FALLBACK_PREFIX_KEY = "_xiaoyi_fallback_prefix";
|
|
239
|
-
/** Internal key for passing deviceType from prepareExtraParams to wrapStreamFn. */
|
|
240
|
-
const DEVICE_TYPE_KEY = "_xiaoyi_device_type";
|
|
241
239
|
const SELF_EVOLUTION_PROMPT_BEGIN = "<self_evolution_prompt>";
|
|
242
240
|
const SELF_EVOLUTION_PROMPT_END = "</self_evolution_prompt>";
|
|
243
241
|
const SELF_EVOLUTION_ENABLED_PROMPT_SECTION = `
|
|
@@ -397,7 +395,9 @@ function trimUserMetadata(text) {
|
|
|
397
395
|
}
|
|
398
396
|
/**
|
|
399
397
|
* Extract A2A taskId and deviceType from Conversation info JSON.
|
|
400
|
-
* bot.ts stores them as MessageSid = "
|
|
398
|
+
* bot.ts stores them as MessageSid = "xiaoyi_taskId_deviceType".
|
|
399
|
+
* The "xiaoyi_" prefix ensures extraction only happens for messages
|
|
400
|
+
* routed through xiaoyi-channel, not other channels sharing the provider.
|
|
401
401
|
*/
|
|
402
402
|
function extractA2AFromConversationInfo(text) {
|
|
403
403
|
const match = text.match(/Conversation info \(untrusted metadata\):\n```json\n([\s\S]*?)\n```/);
|
|
@@ -407,9 +407,9 @@ function extractA2AFromConversationInfo(text) {
|
|
|
407
407
|
if (!msgIdMatch)
|
|
408
408
|
return null;
|
|
409
409
|
const parts = msgIdMatch[1].split("_");
|
|
410
|
-
if (parts.length <
|
|
410
|
+
if (parts.length < 3 || parts[0] !== "xiaoyi")
|
|
411
411
|
return null;
|
|
412
|
-
return { taskId: parts[
|
|
412
|
+
return { taskId: parts[1], deviceType: parts[2] };
|
|
413
413
|
}
|
|
414
414
|
export const xiaoyiProvider = {
|
|
415
415
|
id: "xiaoyiprovider",
|
|
@@ -418,31 +418,12 @@ export const xiaoyiProvider = {
|
|
|
418
418
|
auth: [],
|
|
419
419
|
isCacheTtlEligible: () => true,
|
|
420
420
|
/**
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
* 1. Session context (from AsyncLocalStorage, set by bot.ts)
|
|
426
|
-
* 2. uid-based fallback: sha256(uid).hex[:32]_timestamp
|
|
427
|
-
* 3. No uid available → return undefined (no headers injected)
|
|
421
|
+
* Store uid-based fallback prefix for lazy timestamp generation in wrapStreamFn.
|
|
422
|
+
* Session-level headers (traceId / sessionId / interactionId) are resolved
|
|
423
|
+
* directly in wrapStreamFn via cron detection, Conversation info extraction,
|
|
424
|
+
* or uid fallback.
|
|
428
425
|
*/
|
|
429
426
|
prepareExtraParams: (ctx) => {
|
|
430
|
-
const sessionCtx = getCurrentSessionContext();
|
|
431
|
-
if (sessionCtx) {
|
|
432
|
-
const taskId = sessionCtx.taskId;
|
|
433
|
-
const sessionId = taskId.split("&")[0];
|
|
434
|
-
const interactionId = taskId.split("&")[1] || "";
|
|
435
|
-
return {
|
|
436
|
-
...ctx.extraParams,
|
|
437
|
-
[HEADER_TRACE_ID]: taskId,
|
|
438
|
-
[HEADER_SESSION_ID]: sessionId,
|
|
439
|
-
[HEADER_INTERACTION_ID]: interactionId,
|
|
440
|
-
[DEVICE_TYPE_KEY]: sessionCtx.deviceType ?? "",
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
// Fallback: store uid prefix for lazy timestamp generation in wrapStreamFn.
|
|
444
|
-
// This ensures each model call gets a fresh timestamp instead of reusing
|
|
445
|
-
// the same one across tool-use loops and retries.
|
|
446
427
|
const uid = getUidFromConfig(ctx.config);
|
|
447
428
|
if (!uid)
|
|
448
429
|
return undefined;
|
|
@@ -493,68 +474,46 @@ export const xiaoyiProvider = {
|
|
|
493
474
|
}
|
|
494
475
|
}
|
|
495
476
|
// ── Build dynamic headers ────────────────────────────
|
|
496
|
-
|
|
497
|
-
|
|
477
|
+
// Priority:
|
|
478
|
+
// 1. Cron-triggered: uid → cronUuid, with cron-specific headers
|
|
479
|
+
// 2. Xiaoyi A2A: taskId extracted from Conversation info (xiaoyi_ prefix)
|
|
480
|
+
// 3. UID-based fallback: sha256(uid).hex[:32]_timestamp
|
|
481
|
+
const isCron = isCronTriggered(context.messages);
|
|
482
|
+
if (isCron) {
|
|
483
|
+
const fallbackPrefix = ctx.extraParams?.[FALLBACK_PREFIX_KEY];
|
|
498
484
|
if (typeof fallbackPrefix === "string") {
|
|
499
|
-
// Fallback mode: generate fresh timestamp per request
|
|
500
|
-
const isCron = isCronTriggered(context.messages);
|
|
501
485
|
const fallbackValue = `${fallbackPrefix}_${Date.now()}`;
|
|
502
|
-
dynamicHeaders[HEADER_TRACE_ID] =
|
|
486
|
+
dynamicHeaders[HEADER_TRACE_ID] = `cron_${fallbackValue}`;
|
|
503
487
|
dynamicHeaders[HEADER_SESSION_ID] = fallbackValue;
|
|
504
488
|
dynamicHeaders[HEADER_INTERACTION_ID] = fallbackValue;
|
|
505
|
-
if (isCron) {
|
|
506
|
-
const cronTitle = extractCronTitle(context.messages);
|
|
507
|
-
if (cronTitle)
|
|
508
|
-
dynamicHeaders["x-cron-title"] = encodeURIComponent(cronTitle);
|
|
509
|
-
if (context.messages?.length === 1)
|
|
510
|
-
dynamicHeaders["x-cron-flag"] = "begin";
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
else if (extractedTaskId) {
|
|
514
|
-
// Session mode: taskId extracted from Conversation info
|
|
515
|
-
const traceId = extractedTaskId;
|
|
516
|
-
const sessionId = traceId.split("&")[0];
|
|
517
|
-
const interactionId = traceId.split("&")[1] ?? "";
|
|
518
|
-
const isCron = isCronTriggered(context.messages);
|
|
519
|
-
dynamicHeaders[HEADER_TRACE_ID] = isCron ? `cron_${traceId}_${Date.now()}` : traceId;
|
|
520
|
-
if (isCron) {
|
|
521
|
-
const cronTitle = extractCronTitle(context.messages);
|
|
522
|
-
if (cronTitle)
|
|
523
|
-
dynamicHeaders["x-cron-title"] = encodeURIComponent(cronTitle);
|
|
524
|
-
if (context.messages?.length === 1)
|
|
525
|
-
dynamicHeaders["x-cron-flag"] = "begin";
|
|
526
|
-
}
|
|
527
|
-
dynamicHeaders[HEADER_SESSION_ID] = sessionId;
|
|
528
|
-
dynamicHeaders[HEADER_INTERACTION_ID] = interactionId;
|
|
529
489
|
}
|
|
530
490
|
else {
|
|
531
|
-
|
|
532
|
-
const
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
}
|
|
491
|
+
const cronUuid = extractCronUuid(context.messages) ?? "cron";
|
|
492
|
+
const cronSessionId = `cron_${cronUuid}_${Date.now()}`;
|
|
493
|
+
dynamicHeaders[HEADER_TRACE_ID] = cronSessionId;
|
|
494
|
+
dynamicHeaders[HEADER_SESSION_ID] = cronUuid;
|
|
495
|
+
dynamicHeaders[HEADER_INTERACTION_ID] = cronSessionId;
|
|
496
|
+
}
|
|
497
|
+
const cronTitle = extractCronTitle(context.messages);
|
|
498
|
+
if (cronTitle)
|
|
499
|
+
dynamicHeaders["x-cron-title"] = encodeURIComponent(cronTitle);
|
|
500
|
+
if (context.messages?.length === 1)
|
|
501
|
+
dynamicHeaders["x-cron-flag"] = "begin";
|
|
502
|
+
}
|
|
503
|
+
else if (extractedTaskId) {
|
|
504
|
+
const sessionId = extractedTaskId.split("&")[0];
|
|
505
|
+
const interactionId = extractedTaskId.split("&")[1] ?? "";
|
|
506
|
+
dynamicHeaders[HEADER_TRACE_ID] = extractedTaskId;
|
|
507
|
+
dynamicHeaders[HEADER_SESSION_ID] = sessionId;
|
|
508
|
+
dynamicHeaders[HEADER_INTERACTION_ID] = interactionId;
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
const fallbackPrefix = ctx.extraParams?.[FALLBACK_PREFIX_KEY];
|
|
512
|
+
if (typeof fallbackPrefix === "string") {
|
|
513
|
+
const fallbackValue = `${fallbackPrefix}_${Date.now()}`;
|
|
514
|
+
dynamicHeaders[HEADER_TRACE_ID] = fallbackValue;
|
|
515
|
+
dynamicHeaders[HEADER_SESSION_ID] = fallbackValue;
|
|
516
|
+
dynamicHeaders[HEADER_INTERACTION_ID] = fallbackValue;
|
|
558
517
|
}
|
|
559
518
|
}
|
|
560
519
|
// 记录输入
|
|
@@ -568,9 +527,8 @@ export const xiaoyiProvider = {
|
|
|
568
527
|
logger.log(`[xiaoyiprovider] system prompt length: ${context.systemPrompt.length}`);
|
|
569
528
|
}
|
|
570
529
|
// deviceType: prefer value extracted from Conversation info,
|
|
571
|
-
// then
|
|
572
|
-
const
|
|
573
|
-
const deviceType = (extractedDeviceType || extraParamsDeviceType)
|
|
530
|
+
// then ALS fallback.
|
|
531
|
+
const deviceType = extractedDeviceType
|
|
574
532
|
?? getCurrentSessionContext()?.deviceType;
|
|
575
533
|
// 在发送给模型前,优化 systemPrompt 结构
|
|
576
534
|
if (context.systemPrompt) {
|