refactor(channels): dedupe plugin routing and channel helpers

This commit is contained in:
Peter Steinberger
2026-02-22 14:05:46 +00:00
parent 7abae052f9
commit 66f814a0af
57 changed files with 3744 additions and 2127 deletions

View File

@@ -357,56 +357,55 @@ describe("createStatusReactionController", () => {
},
] as const;
const createControllerAfterThinking = async () => {
const state = createEnabledController();
void state.controller.setThinking();
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
return state;
};
for (const testCase of stallCases) {
it(`should trigger ${testCase.name}`, async () => {
const { calls, controller } = createEnabledController();
void controller.setThinking();
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
const { calls } = await createControllerAfterThinking();
await vi.advanceTimersByTimeAsync(testCase.delayMs);
expect(calls).toContainEqual({ method: "set", emoji: testCase.expected });
});
}
it("should reset stall timers on phase change", async () => {
const { calls, controller } = createEnabledController();
const stallResetCases = [
{
name: "phase change",
runUpdate: (controller: ReturnType<typeof createStatusReactionController>) => {
void controller.setTool("exec");
return vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
},
},
{
name: "repeated same-phase updates",
runUpdate: (controller: ReturnType<typeof createStatusReactionController>) => {
void controller.setThinking();
return Promise.resolve();
},
},
] as const;
void controller.setThinking();
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
for (const testCase of stallResetCases) {
it(`should reset stall timers on ${testCase.name}`, async () => {
const { calls, controller } = await createControllerAfterThinking();
// Advance halfway to soft stall
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
// Advance halfway to soft stall.
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
// Change phase
void controller.setTool("exec");
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
await testCase.runUpdate(controller);
// Advance another halfway - should not trigger stall yet
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
// Advance another halfway - should not trigger stall yet.
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
const stallCalls = calls.filter((c) => c.emoji === DEFAULT_EMOJIS.stallSoft);
expect(stallCalls).toHaveLength(0);
});
it("should reset stall timers on repeated same-phase updates", async () => {
const { calls, controller } = createEnabledController();
void controller.setThinking();
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.debounceMs);
// Advance halfway to soft stall
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
// Re-affirm same phase (should reset timers)
void controller.setThinking();
// Advance another halfway - should not trigger stall yet
await vi.advanceTimersByTimeAsync(DEFAULT_TIMING.stallSoftMs / 2);
const stallCalls = calls.filter((c) => c.emoji === DEFAULT_EMOJIS.stallSoft);
expect(stallCalls).toHaveLength(0);
});
const stallCalls = calls.filter((c) => c.emoji === DEFAULT_EMOJIS.stallSoft);
expect(stallCalls).toHaveLength(0);
});
}
it("should call onError callback when adapter throws", async () => {
const onError = vi.fn();