


















@@ -703,7 +703,7 @@ function createMockAcpSessionManager() {
703703}
704704705705function firstToolResultPayload(dispatcher: ReplyDispatcher): ReplyPayload | undefined {
706-return (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as
706+return (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0] as
707707| ReplyPayload
708708| undefined;
709709}
@@ -861,9 +861,9 @@ describe("dispatchReplyFromConfig", () => {
861861const replyResolver = async () => ({ text: "hi" }) satisfies ReplyPayload;
862862await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
863863864-const pluginLoadOptions = runtimePluginMocks.ensureRuntimePluginsLoaded.mock.calls[0]?.[0] as
865-| { config?: unknown; workspaceDir?: unknown }
866- | undefined;
864+const pluginLoadOptions = runtimePluginMocks.ensureRuntimePluginsLoaded.mock.calls.at(
865+0,
866+)?.[0] as { config?: unknown; workspaceDir?: unknown } | undefined;
867867expect(pluginLoadOptions?.config).toBe(cfg);
868868expect(typeof pluginLoadOptions?.workspaceDir).toBe("string");
869869expect(runtimePluginMocks.ensureRuntimePluginsLoaded.mock.invocationCallOrder[0]).toBeLessThan(
@@ -916,7 +916,7 @@ describe("dispatchReplyFromConfig", () => {
916916await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
917917918918expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
919-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
919+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
920920| {
921921accountId?: unknown;
922922channel?: unknown;
@@ -963,7 +963,7 @@ describe("dispatchReplyFromConfig", () => {
963963await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
964964965965expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
966-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
966+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
967967| { accountId?: unknown; channel?: unknown; to?: unknown }
968968| undefined;
969969expect(routeCall?.channel).toBe("telegram");
@@ -973,7 +973,7 @@ describe("dispatchReplyFromConfig", () => {
973973.calls[0]?.[0] as { accountId?: unknown; messageProvider?: unknown } | undefined;
974974expect(normalizerOptions?.messageProvider).toBe("telegram");
975975expect(normalizerOptions?.accountId).toBe("acc-1");
976-const replyDispatchCall = hookMocks.runner.runReplyDispatch.mock.calls[0] as
976+const replyDispatchCall = hookMocks.runner.runReplyDispatch.mock.calls.at(0) as
977977| [
978978{
979979originatingChannel?: unknown;
@@ -1012,7 +1012,7 @@ describe("dispatchReplyFromConfig", () => {
10121012await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
1013101310141014expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
1015-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1015+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
10161016| { accountId?: unknown; channel?: unknown; to?: unknown }
10171017| undefined;
10181018expect(routeCall?.channel).toBe("discord");
@@ -1058,7 +1058,7 @@ describe("dispatchReplyFromConfig", () => {
10581058expect(mocks.routeReply).not.toHaveBeenCalled();
10591059expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
10601060expect(result.queuedFinal).toBe(false);
1061-const replyDispatchCall = hookMocks.runner.runReplyDispatch.mock.calls[0] as
1061+const replyDispatchCall = hookMocks.runner.runReplyDispatch.mock.calls.at(0) as
10621062| [
10631063{
10641064originatingChannel?: unknown;
@@ -1108,7 +1108,7 @@ describe("dispatchReplyFromConfig", () => {
11081108const replyResolver = async () => ({ text: "hi" }) satisfies ReplyPayload;
11091109await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
111011101111-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1111+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
11121112| { channel?: unknown; threadId?: unknown; to?: unknown }
11131113| undefined;
11141114expect(routeCall?.channel).toBe("discord");
@@ -1149,7 +1149,7 @@ describe("dispatchReplyFromConfig", () => {
11491149const replyResolver = async () => ({ text: "hi" }) satisfies ReplyPayload;
11501150await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
115111511152-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1152+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
11531153| { channel?: string; to?: string; threadId?: string | number }
11541154| undefined;
11551155expect(routeCall?.channel).toBe("mattermost");
@@ -1212,7 +1212,7 @@ describe("dispatchReplyFromConfig", () => {
12121212await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
1213121312141214expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
1215-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1215+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
12161216| { channel?: unknown; to?: unknown }
12171217| undefined;
12181218expect(routeCall?.channel).toBe("telegram");
@@ -1235,7 +1235,7 @@ describe("dispatchReplyFromConfig", () => {
12351235await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
1236123612371237expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
1238-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1238+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
12391239| { channel?: unknown; to?: unknown }
12401240| undefined;
12411241expect(routeCall?.channel).toBe("feishu");
@@ -1305,7 +1305,7 @@ describe("dispatchReplyFromConfig", () => {
13051305await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
1306130613071307expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
1308-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
1308+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
13091309| { channel?: unknown; policyConversationType?: unknown; to?: unknown }
13101310| undefined;
13111311expect(routeCall?.channel).toBe("imessage");
@@ -1348,7 +1348,7 @@ describe("dispatchReplyFromConfig", () => {
13481348expect(dispatcher.sendToolResult).not.toHaveBeenCalled();
13491349expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
13501350expect(mocks.routeReply).toHaveBeenCalledTimes(1);
1351-const routed = mocks.routeReply.mock.calls[0]?.[0] as { payload?: ReplyPayload } | undefined;
1351+const routed = mocks.routeReply.mock.calls.at(0)?.[0] as { payload?: ReplyPayload } | undefined;
13521352expect(routed?.payload?.mediaUrls).toEqual(["https://example.com/tts-routed.opus"]);
13531353expect(routed?.payload?.text).toBeUndefined();
13541354});
@@ -1570,7 +1570,9 @@ describe("dispatchReplyFromConfig", () => {
1570157015711571expect(dispatcher.sendToolResult).toHaveBeenCalledTimes(2);
15721572expect(firstToolResultPayload(dispatcher)?.text).toBe("🔧 tools/sessions_send");
1573-const sent = (dispatcher.sendToolResult as Mock).mock.calls[1]?.[0] as ReplyPayload | undefined;
1573+const sent = (dispatcher.sendToolResult as Mock).mock.calls.at(1)?.[0] as
1574+| ReplyPayload
1575+| undefined;
15741576expect(sent?.mediaUrl).toBe("https://example.com/tts-native.opus");
15751577expect(sent?.text).toBeUndefined();
15761578expect(dispatcher.sendFinalReply).toHaveBeenCalledTimes(1);
@@ -1615,7 +1617,7 @@ describe("dispatchReplyFromConfig", () => {
16151617expect(firstToolResultPayload(dispatcher)?.text).toBe(
16161618"Inspect code, patch it, run tests.\n\n1. Inspect code\n2. Patch code\n3. Run tests",
16171619);
1618-const secondToolPayload = (dispatcher.sendToolResult as Mock).mock.calls[1]?.[0] as
1620+const secondToolPayload = (dispatcher.sendToolResult as Mock).mock.calls.at(1)?.[0] as
16191621| ReplyPayload
16201622| undefined;
16211623expect(secondToolPayload?.text).toBe("Working: awaiting approval: pnpm test");
@@ -2055,7 +2057,7 @@ describe("dispatchReplyFromConfig", () => {
20552057await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
2056205820572059expect(replyResolver).not.toHaveBeenCalled();
2058-const ensureSessionOptions = runtime.ensureSession.mock.calls[0]?.[0] as
2060+const ensureSessionOptions = runtime.ensureSession.mock.calls.at(0)?.[0] as
20592061| { agent?: unknown; mode?: unknown; sessionKey?: unknown }
20602062| undefined;
20612063expect(ensureSessionOptions?.sessionKey).toBe("agent:codex-acp:session-1");
@@ -2066,7 +2068,7 @@ describe("dispatchReplyFromConfig", () => {
20662068const streamedText = blockCalls.map((call) => (call[0] as ReplyPayload).text ?? "").join("");
20672069expect(streamedText).toContain("hello");
20682070expect(streamedText).toContain("world");
2069-const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as
2071+const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as
20702072| ReplyPayload
20712073| undefined;
20722074expect(finalPayload?.text).toBe("hello world");
@@ -2401,7 +2403,7 @@ describe("dispatchReplyFromConfig", () => {
2401240324022404await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
240324052404-const bindingLookup = sessionBindingMocks.resolveByConversation.mock.calls[0]?.[0];
2406+const bindingLookup = sessionBindingMocks.resolveByConversation.mock.calls.at(0)?.[0];
24052407expect(bindingLookup?.channel).toBe("discord");
24062408expect(bindingLookup?.accountId).toBe("work");
24072409expect(bindingLookup?.conversationId).toBe("thread-1");
@@ -2486,15 +2488,15 @@ describe("dispatchReplyFromConfig", () => {
24862488conversationId: "C123",
24872489});
24882490expect(sessionBindingMocks.touch).toHaveBeenCalledWith("binding-acp-current");
2489-const ensureSessionOptions = runtime.ensureSession.mock.calls[0]?.[0] as
2491+const ensureSessionOptions = runtime.ensureSession.mock.calls.at(0)?.[0] as
24902492| { agent?: unknown; sessionKey?: unknown }
24912493| undefined;
24922494expect(ensureSessionOptions?.sessionKey).toBe(boundSessionKey);
24932495expect(ensureSessionOptions?.agent).toBe("opencode");
2494-const runTurnOptions = runtime.runTurn.mock.calls[0]?.[0] as { text?: unknown } | undefined;
2496+const runTurnOptions = runtime.runTurn.mock.calls.at(0)?.[0] as { text?: unknown } | undefined;
24952497expect(runTurnOptions?.text).toBe("continue");
24962498expect(replyResolver).not.toHaveBeenCalled();
2497-const blockPayload = (dispatcher.sendBlockReply as Mock).mock.calls[0]?.[0] as
2499+const blockPayload = (dispatcher.sendBlockReply as Mock).mock.calls.at(0)?.[0] as
24982500| ReplyPayload
24992501| undefined;
25002502expect(blockPayload?.text).toBe("Bound ACP reply");
@@ -2557,7 +2559,7 @@ describe("dispatchReplyFromConfig", () => {
25572559}
25582560}
25592561expect(blockTexts).toEqual(["What do you want to work on?"]);
2560-const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as
2562+const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as
25612563| ReplyPayload
25622564| undefined;
25632565expect(finalPayload?.text).toBe("What do you want to work on?");
@@ -2642,7 +2644,7 @@ describe("dispatchReplyFromConfig", () => {
26422644const normalizerOptions = replyMediaPathMocks.createReplyMediaPathNormalizer.mock
26432645.calls[0]?.[0] as { messageProvider?: unknown } | undefined;
26442646expect(normalizerOptions?.messageProvider).toBe("feishu");
2645-const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as
2647+const finalPayload = (dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as
26462648| ReplyPayload
26472649| undefined;
26482650expect(finalPayload?.mediaUrl).toBe("/tmp/openclaw-media/normalized-tts.ogg");
@@ -2690,7 +2692,7 @@ describe("dispatchReplyFromConfig", () => {
2690269226912693await dispatchReplyFromConfig({ ctx, cfg, dispatcher });
269226942693-const closeOptions = runtime.close.mock.calls[0]?.[0] as { reason?: unknown } | undefined;
2695+const closeOptions = runtime.close.mock.calls.at(0)?.[0] as { reason?: unknown } | undefined;
26942696expect(closeOptions?.reason).toBe("oneshot-complete");
26952697});
26962698@@ -2799,7 +2801,7 @@ describe("dispatchReplyFromConfig", () => {
2799280128002802expect(firstToolResultPayload(dispatcher)?.text).toBe("Approval required.");
28012803expect(
2802-((dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as ReplyPayload | undefined)?.text,
2804+((dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as ReplyPayload | undefined)?.text,
28032805).toBe("done");
28042806});
28052807@@ -2849,7 +2851,8 @@ describe("dispatchReplyFromConfig", () => {
2849285128502852expect(dispatcher.sendToolResult).not.toHaveBeenCalled();
28512853expect(
2852-((dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as ReplyPayload | undefined)?.text,
2854+((dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as ReplyPayload | undefined)
2855+?.text,
28532856).toBe("done");
28542857} finally {
28552858await reporter.stop();
@@ -2915,7 +2918,7 @@ describe("dispatchReplyFromConfig", () => {
29152918const replyResolver = async () => ({ text: "hi" }) satisfies ReplyPayload;
29162919await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
291729202918-const [event, hookContext] = hookMocks.runner.runMessageReceived.mock.calls[0] as
2921+const [event, hookContext] = hookMocks.runner.runMessageReceived.mock.calls.at(0) as
29192922| [
29202923{
29212924content?: unknown;
@@ -2976,7 +2979,7 @@ describe("dispatchReplyFromConfig", () => {
2976297929772980expect(result).toEqual({ queuedFinal: true, counts: { tool: 0, block: 0, final: 0 } });
29782981expect(hookMocks.runner.runInboundClaim).not.toHaveBeenCalled();
2979-const [event, hookContext] = hookMocks.runner.runMessageReceived.mock.calls[0] as
2982+const [event, hookContext] = hookMocks.runner.runMessageReceived.mock.calls.at(0) as
29802983| [
29812984{ content?: unknown; from?: unknown; metadata?: Record<string, unknown> },
29822985{ accountId?: unknown; channelId?: unknown; conversationId?: unknown },
@@ -3003,7 +3006,7 @@ describe("dispatchReplyFromConfig", () => {
30033006expect(internalHookEvent?.sessionKey).toBe("agent:main:hook-test");
30043007expect(replyResolver).toHaveBeenCalledTimes(1);
30053008expect(
3006-((dispatcher.sendFinalReply as Mock).mock.calls[0]?.[0] as ReplyPayload | undefined)?.text,
3009+((dispatcher.sendFinalReply as Mock).mock.calls.at(0)?.[0] as ReplyPayload | undefined)?.text,
30073010).toBe("core reply");
30083011});
30093012@@ -3024,7 +3027,7 @@ describe("dispatchReplyFromConfig", () => {
30243027const replyResolver = async () => ({ text: "hi" }) satisfies ReplyPayload;
30253028await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
302630293027-const createHookCall = internalHookMocks.createInternalHookEvent.mock.calls[0] as
3030+const createHookCall = internalHookMocks.createInternalHookEvent.mock.calls.at(0) as
30283031| [
30293032unknown,
30303033unknown,
@@ -3084,7 +3087,7 @@ describe("dispatchReplyFromConfig", () => {
30843087const replyResolver = async () => ({ text: "reply" }) satisfies ReplyPayload;
30853088await dispatchReplyFromConfig({ ctx, cfg, dispatcher, replyResolver });
308630893087-const createHookCall = internalHookMocks.createInternalHookEvent.mock.calls[0] as
3090+const createHookCall = internalHookMocks.createInternalHookEvent.mock.calls.at(0) as
30883091| [unknown, unknown, unknown, { content?: unknown; messageId?: unknown }]
30893092| undefined;
30903093expect(createHookCall?.[0]).toBe("message");
@@ -3116,7 +3119,7 @@ describe("dispatchReplyFromConfig", () => {
31163119state: "processing",
31173120reason: "message_start",
31183121});
3119-const processedEvent = diagnosticMocks.logMessageProcessed.mock.calls[0]?.[0] as
3122+const processedEvent = diagnosticMocks.logMessageProcessed.mock.calls.at(0)?.[0] as
31203123| { channel?: unknown; outcome?: unknown; sessionKey?: unknown }
31213124| undefined;
31223125expect(processedEvent?.channel).toBe("slack");
@@ -3559,7 +3562,7 @@ describe("dispatchReplyFromConfig", () => {
35593562 replyResolver,
35603563});
356135643562-const notice = (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls[0]?.[0] as
3565+const notice = (dispatcher.sendToolResult as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0] as
35633566| ReplyPayload
35643567| undefined;
35653568expect(notice?.text).toContain("is not currently loaded.");
@@ -4155,7 +4158,7 @@ describe("before_dispatch hook", () => {
4155415841564159const result = await dispatchReplyFromConfig({ ctx, cfg: emptyConfig, dispatcher });
415741604158-const beforeDispatchCall = hookMocks.runner.runBeforeDispatch.mock.calls[0] as
4161+const beforeDispatchCall = hookMocks.runner.runBeforeDispatch.mock.calls.at(0) as
41594162| [
41604163{
41614164body?: unknown;
@@ -4177,7 +4180,7 @@ describe("before_dispatch hook", () => {
41774180expect(beforeDispatchCall?.[1]?.channelId).toBe("telegram");
41784181expect(beforeDispatchCall?.[1]?.senderId).toBe("signal:user:alice");
41794182expect(dispatcher.sendFinalReply).not.toHaveBeenCalled();
4180-const routeCall = mocks.routeReply.mock.calls[0]?.[0] as
4183+const routeCall = mocks.routeReply.mock.calls.at(0)?.[0] as
41814184| { channel?: unknown; payload?: ReplyPayload; to?: unknown }
41824185| undefined;
41834186expect(routeCall?.channel).toBe("telegram");
@@ -4836,9 +4839,9 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
4836483948374840expect(replyResolver).toHaveBeenCalledTimes(1);
48384841expect(result.queuedFinal).toBe(true);
4839-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
4840-"visible direct reply",
4841-);
4842+expect(
4843+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
4844+).toBe("visible direct reply");
48424845});
4843484648444847it("uses harness defaults for direct source delivery when config is unset", async () => {
@@ -4898,9 +4901,9 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
4898490148994902expect(replyResolver).toHaveBeenCalledTimes(1);
49004903expect(result.queuedFinal).toBe(true);
4901-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
4902-"visible fallback",
4903-);
4904+expect(
4905+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
4906+).toBe("visible fallback");
49044907});
4905490849064909it("falls back to automatic group/channel delivery when group tools remove the message tool", async () => {
@@ -4934,9 +4937,9 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
4934493749354938expect(replyResolver).toHaveBeenCalledTimes(1);
49364939expect(result.queuedFinal).toBe(true);
4937-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
4938-"group policy fallback",
4939-);
4940+expect(
4941+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
4942+).toBe("group policy fallback");
49404943});
4941494449424945it("falls back when a channel precomputed message-tool-only delivery but the message tool is unavailable", async () => {
@@ -4962,9 +4965,9 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
4962496549634966expect(replyResolver).toHaveBeenCalledTimes(1);
49644967expect(result.queuedFinal).toBe(true);
4965-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
4966-"requested fallback",
4967-);
4968+expect(
4969+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
4970+).toBe("requested fallback");
49684971});
4969497249704973it("keeps native command replies visible in group/channel turns", async () => {
@@ -4991,9 +4994,9 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
4991499449924995expect(replyResolver).toHaveBeenCalledTimes(1);
49934996expect(result.queuedFinal).toBe(true);
4994-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
4995-"status reply",
4996-);
4997+expect(
4998+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
4999+).toBe("status reply");
49975000});
4998500149995002it("allows config to keep group/channel source delivery automatic", async () => {
@@ -5017,8 +5020,8 @@ describe("sendPolicy deny — suppress delivery, not processing (#53328)", () =>
5017502050185021expect(replyResolver).toHaveBeenCalledTimes(1);
50195022expect(result.queuedFinal).toBe(true);
5020-expect((dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls[0]?.[0]?.text).toBe(
5021-"final reply",
5022-);
5023+expect(
5024+(dispatcher.sendFinalReply as ReturnType<typeof vi.fn>).mock.calls.at(0)?.[0]?.text,
5025+).toBe("final reply");
50235026});
50245027});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。