diff --git a/src/features/context-injector/index.ts b/src/features/context-injector/index.ts index 51e3045c9..e719d3bd7 100644 --- a/src/features/context-injector/index.ts +++ b/src/features/context-injector/index.ts @@ -1,7 +1,5 @@ export { ContextCollector, contextCollector } from "./collector" export { - injectPendingContext, - createContextInjectorHook, createContextInjectorMessagesTransformHook, } from "./injector" export type { diff --git a/src/features/context-injector/injector.test.ts b/src/features/context-injector/injector.test.ts index 752cbf9fe..b518c48ef 100644 --- a/src/features/context-injector/injector.test.ts +++ b/src/features/context-injector/injector.test.ts @@ -1,181 +1,9 @@ import { describe, it, expect, beforeEach } from "bun:test" import { ContextCollector } from "./collector" import { - injectPendingContext, - createContextInjectorHook, createContextInjectorMessagesTransformHook, } from "./injector" -describe("injectPendingContext", () => { - let collector: ContextCollector - - beforeEach(() => { - collector = new ContextCollector() - }) - - describe("when parts have text content", () => { - it("prepends context to first text part", () => { - // #given - const sessionID = "ses_inject1" - collector.register(sessionID, { - id: "ulw", - source: "keyword-detector", - content: "Ultrawork mode activated", - }) - const parts = [{ type: "text", text: "User message" }] - - // #when - const result = injectPendingContext(collector, sessionID, parts) - - // #then - expect(result.injected).toBe(true) - expect(parts[0].text).toContain("Ultrawork mode activated") - expect(parts[0].text).toContain("User message") - }) - - it("uses separator between context and original message", () => { - // #given - const sessionID = "ses_inject2" - collector.register(sessionID, { - id: "ctx", - source: "keyword-detector", - content: "Context content", - }) - const parts = [{ type: "text", text: "Original message" }] - - // #when - injectPendingContext(collector, sessionID, parts) - - // #then - expect(parts[0].text).toBe("Context content\n\n---\n\nOriginal message") - }) - - it("consumes context after injection", () => { - // #given - const sessionID = "ses_inject3" - collector.register(sessionID, { - id: "ctx", - source: "keyword-detector", - content: "Context", - }) - const parts = [{ type: "text", text: "Message" }] - - // #when - injectPendingContext(collector, sessionID, parts) - - // #then - expect(collector.hasPending(sessionID)).toBe(false) - }) - - it("returns injected=false when no pending context", () => { - // #given - const sessionID = "ses_empty" - const parts = [{ type: "text", text: "Message" }] - - // #when - const result = injectPendingContext(collector, sessionID, parts) - - // #then - expect(result.injected).toBe(false) - expect(parts[0].text).toBe("Message") - }) - }) - - describe("when parts have no text content", () => { - it("does not inject and preserves context", () => { - // #given - const sessionID = "ses_notext" - collector.register(sessionID, { - id: "ctx", - source: "keyword-detector", - content: "Context", - }) - const parts = [{ type: "image", url: "https://example.com/img.png" }] - - // #when - const result = injectPendingContext(collector, sessionID, parts) - - // #then - expect(result.injected).toBe(false) - expect(collector.hasPending(sessionID)).toBe(true) - }) - }) - - describe("with multiple text parts", () => { - it("injects into first text part only", () => { - // #given - const sessionID = "ses_multi" - collector.register(sessionID, { - id: "ctx", - source: "keyword-detector", - content: "Context", - }) - const parts = [ - { type: "text", text: "First" }, - { type: "text", text: "Second" }, - ] - - // #when - injectPendingContext(collector, sessionID, parts) - - // #then - expect(parts[0].text).toContain("Context") - expect(parts[1].text).toBe("Second") - }) - }) -}) - -describe("createContextInjectorHook", () => { - let collector: ContextCollector - - beforeEach(() => { - collector = new ContextCollector() - }) - - describe("chat.message handler", () => { - it("injects pending context into output parts", async () => { - // #given - const hook = createContextInjectorHook(collector) - const sessionID = "ses_hook1" - collector.register(sessionID, { - id: "ctx", - source: "keyword-detector", - content: "Hook context", - }) - const input = { sessionID } - const output = { - message: {}, - parts: [{ type: "text", text: "User message" }], - } - - // #when - await hook["chat.message"](input, output) - - // #then - expect(output.parts[0].text).toContain("Hook context") - expect(output.parts[0].text).toContain("User message") - expect(collector.hasPending(sessionID)).toBe(false) - }) - - it("does nothing when no pending context", async () => { - // #given - const hook = createContextInjectorHook(collector) - const sessionID = "ses_hook2" - const input = { sessionID } - const output = { - message: {}, - parts: [{ type: "text", text: "User message" }], - } - - // #when - await hook["chat.message"](input, output) - - // #then - expect(output.parts[0].text).toBe("User message") - }) - }) -}) - describe("createContextInjectorMessagesTransformHook", () => { let collector: ContextCollector