@ynhcj/xiaoyi-channel 0.0.132-next → 0.0.133-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.d.ts
CHANGED
|
@@ -24,3 +24,8 @@ export interface HandleXYMessageParams {
|
|
|
24
24
|
* Runtime is expected to be validated before calling this function.
|
|
25
25
|
*/
|
|
26
26
|
export declare function handleXYMessage(params: HandleXYMessageParams): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* 由 provider.ts 在 wrapStreamFn 调用时触发。
|
|
29
|
+
* 这是模型 API 被调用的精确时刻,此时 isStreaming 一定为 true。
|
|
30
|
+
*/
|
|
31
|
+
export declare function notifyModelStreaming(sessionId: string): void;
|
package/dist/src/bot.js
CHANGED
|
@@ -254,9 +254,10 @@ export async function handleXYMessage(params) {
|
|
|
254
254
|
// so the dispatcher skips all user-facing callbacks (deliver, onIdle, etc.)
|
|
255
255
|
// and onSettled skips cleanup.
|
|
256
256
|
const steerState = { steered: isUpdate };
|
|
257
|
-
// 🔑
|
|
258
|
-
|
|
259
|
-
|
|
257
|
+
// 🔑 第一条消息创建 streaming 信号(provider.ts 的 wrapStreamFn 触发)
|
|
258
|
+
if (!isUpdate) {
|
|
259
|
+
createStreamingSignal(parsed.sessionId);
|
|
260
|
+
}
|
|
260
261
|
// 🔑 创建dispatcher
|
|
261
262
|
logger.log(`[BOT-DISPATCHER] 🎯 Creating reply dispatcher`);
|
|
262
263
|
logger.log(`[BOT-DISPATCHER] - taskId: ${parsed.taskId}`);
|
|
@@ -268,7 +269,6 @@ export async function handleXYMessage(params) {
|
|
|
268
269
|
messageId: parsed.messageId,
|
|
269
270
|
accountId: route.accountId,
|
|
270
271
|
steerState,
|
|
271
|
-
onFirstStream: streamingSignal?.notify,
|
|
272
272
|
});
|
|
273
273
|
// Steer injections don't need status intervals
|
|
274
274
|
if (!skipReg) {
|
|
@@ -404,6 +404,18 @@ function buildXYMediaPayload(mediaList) {
|
|
|
404
404
|
};
|
|
405
405
|
}
|
|
406
406
|
const streamingSignals = new Map();
|
|
407
|
+
/**
|
|
408
|
+
* 由 provider.ts 在 wrapStreamFn 调用时触发。
|
|
409
|
+
* 这是模型 API 被调用的精确时刻,此时 isStreaming 一定为 true。
|
|
410
|
+
*/
|
|
411
|
+
export function notifyModelStreaming(sessionId) {
|
|
412
|
+
const signal = streamingSignals.get(sessionId);
|
|
413
|
+
if (signal) {
|
|
414
|
+
streamingSignals.delete(sessionId);
|
|
415
|
+
signal.notify();
|
|
416
|
+
logger.log(`[STEER-QUEUE] 📡 Model streaming signal fired for session=${sessionId}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
407
419
|
function createStreamingSignal(sessionId) {
|
|
408
420
|
let resolve;
|
|
409
421
|
const promise = new Promise(r => { resolve = r; });
|
package/dist/src/provider.js
CHANGED
|
@@ -11,6 +11,7 @@ import { createHash } from "crypto";
|
|
|
11
11
|
import { logger } from "./utils/logger.js";
|
|
12
12
|
import { getCurrentSessionContext } from "./tools/session-manager.js";
|
|
13
13
|
import { selfEvolutionManager } from "./utils/self-evolution-manager.js";
|
|
14
|
+
import { notifyModelStreaming } from "./bot.js";
|
|
14
15
|
// ── Retry config ──────────────────────────────────────────────
|
|
15
16
|
const RETRY_DELAYS_MS = [10_000, 20_000, 40_000, 60_000, 60_000];
|
|
16
17
|
const MAX_RETRY_ATTEMPTS = 5;
|
|
@@ -536,6 +537,11 @@ export const xiaoyiProvider = {
|
|
|
536
537
|
}
|
|
537
538
|
// 记录输入
|
|
538
539
|
logger.log(`[xiaoyiprovider] input messages count: ${context.messages?.length ?? 0}`);
|
|
540
|
+
// 🔑 通知 steer 队列:模型 API 已被调用,此时 isStreaming 一定为 true
|
|
541
|
+
const sessionCtx = getCurrentSessionContext();
|
|
542
|
+
if (sessionCtx?.sessionId) {
|
|
543
|
+
notifyModelStreaming(sessionCtx.sessionId);
|
|
544
|
+
}
|
|
539
545
|
if (context.systemPrompt) {
|
|
540
546
|
logger.log(`[xiaoyiprovider] system prompt length: ${context.systemPrompt.length}`);
|
|
541
547
|
}
|
|
@@ -9,8 +9,6 @@ export interface CreateXYReplyDispatcherParams {
|
|
|
9
9
|
steerState: {
|
|
10
10
|
steered: boolean;
|
|
11
11
|
};
|
|
12
|
-
/** Called the first time deliver fires for a non-steered dispatch — signals the model is streaming. */
|
|
13
|
-
onFirstStream?: () => void;
|
|
14
12
|
}
|
|
15
13
|
/**
|
|
16
14
|
* 清理 /tmp/xy_channel 目录中超过 24 小时的旧文件
|
|
@@ -45,7 +45,7 @@ export async function cleanupStaleTempFiles(tempDir = "/tmp/xy_channel") {
|
|
|
45
45
|
* Runtime is expected to be validated before calling this function.
|
|
46
46
|
*/
|
|
47
47
|
export function createXYReplyDispatcher(params) {
|
|
48
|
-
const { cfg, runtime, sessionId, taskId, messageId, accountId, steerState
|
|
48
|
+
const { cfg, runtime, sessionId, taskId, messageId, accountId, steerState } = params;
|
|
49
49
|
logger.log(`[DISPATCHER-CREATE] ******* Creating dispatcher *******`);
|
|
50
50
|
logger.log(`[DISPATCHER-CREATE] - taskId: ${taskId}`);
|
|
51
51
|
// 初始taskId和messageId(作为fallback)
|
|
@@ -73,7 +73,6 @@ export function createXYReplyDispatcher(params) {
|
|
|
73
73
|
let hasSentResponse = false;
|
|
74
74
|
let finalSent = false;
|
|
75
75
|
let accumulatedText = "";
|
|
76
|
-
let streamingSignaled = false;
|
|
77
76
|
/**
|
|
78
77
|
* Start the status update interval
|
|
79
78
|
*/
|
|
@@ -119,11 +118,6 @@ export function createXYReplyDispatcher(params) {
|
|
|
119
118
|
logger.log(`[DELIVER] Steered dispatch - skipping deliver, info.kind=${info?.kind}`);
|
|
120
119
|
return;
|
|
121
120
|
}
|
|
122
|
-
// 🔑 第一次 deliver = 模型开始 streaming,通知等待中的 steer
|
|
123
|
-
if (onFirstStream && !streamingSignaled) {
|
|
124
|
-
streamingSignaled = true;
|
|
125
|
-
onFirstStream();
|
|
126
|
-
}
|
|
127
121
|
const text = payload.text ?? "";
|
|
128
122
|
const currentTaskId = getActiveTaskId();
|
|
129
123
|
const currentMessageId = getActiveMessageId();
|