2026-09-24 15:09:37 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* A1 阶段的占位引擎:把用户输入回显成一条助手消息,用来打通 HTTP / SSE 链路。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 它刻意不做任何「理解」,也不调用 Provider——避免把假能力写进真实链路。
|
|
|
|
|
|
* A3.1 定义正式 AgentRuntime、A3.2 写 FakeRuntime 之后,本文件整体替换。
|
|
|
|
|
|
*/
|
2026-09-24 15:37:35 +08:00
|
|
|
|
import type { EventBus } from './events.js';
|
2026-09-24 15:09:37 +08:00
|
|
|
|
|
|
|
|
|
|
export interface EchoRunInput {
|
|
|
|
|
|
sessionId: string;
|
|
|
|
|
|
runId: string;
|
|
|
|
|
|
messageId: string;
|
|
|
|
|
|
text: string;
|
|
|
|
|
|
bus: EventBus;
|
|
|
|
|
|
signal: AbortSignal;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface EchoRunResult {
|
|
|
|
|
|
text: string;
|
|
|
|
|
|
finishReason: 'stop' | 'cancelled';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const CHUNK_SIZE = 6;
|
|
|
|
|
|
const CHUNK_DELAY_MS = 25;
|
|
|
|
|
|
|
|
|
|
|
|
const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
|
|
|
|
|
|
|
|
export async function runEcho(input: EchoRunInput): Promise<EchoRunResult> {
|
|
|
|
|
|
const { bus, signal, sessionId, runId, messageId } = input;
|
|
|
|
|
|
const replyMessageId = `${messageId}-reply`;
|
|
|
|
|
|
const reply = `(A1 占位引擎)收到:${input.text}`;
|
|
|
|
|
|
let emitted = '';
|
|
|
|
|
|
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'run.state', data: { state: 'running' } });
|
|
|
|
|
|
|
|
|
|
|
|
for (let index = 0; index < reply.length; index += CHUNK_SIZE) {
|
|
|
|
|
|
if (signal.aborted) return finish(true);
|
|
|
|
|
|
const piece = reply.slice(index, index + CHUNK_SIZE);
|
|
|
|
|
|
emitted += piece;
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'message.delta', data: { messageId: replyMessageId, text: piece } });
|
|
|
|
|
|
await sleep(CHUNK_DELAY_MS);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (signal.aborted) return finish(true);
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'message.completed', data: { messageId: replyMessageId, finishReason: 'stop' } });
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'run.state', data: { state: 'idle' } });
|
|
|
|
|
|
return { text: emitted, finishReason: 'stop' };
|
|
|
|
|
|
|
|
|
|
|
|
function finish(cancelled: boolean): EchoRunResult {
|
|
|
|
|
|
// 取消路径:cancelling → 一条带 cancelled 结束原因的消息 → 回到 idle。
|
|
|
|
|
|
// 'cancelled' 这个运行状态当前不使用(A3.1 定稿再确认语义)。
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'run.state', data: { state: 'cancelling' } });
|
|
|
|
|
|
bus.publish({
|
|
|
|
|
|
sessionId,
|
|
|
|
|
|
runId,
|
|
|
|
|
|
type: 'message.completed',
|
|
|
|
|
|
data: { messageId: replyMessageId, finishReason: cancelled ? 'cancelled' : 'stop' },
|
|
|
|
|
|
});
|
|
|
|
|
|
bus.publish({ sessionId, runId, type: 'run.state', data: { state: 'idle' } });
|
|
|
|
|
|
return { text: emitted, finishReason: 'cancelled' };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|