Skip to content

Fix: use chat.message hook for context injection#3

Open
niklas-r wants to merge 1 commit intomark-hingston:mainfrom
niklas-r:fix/chat-message-hook
Open

Fix: use chat.message hook for context injection#3
niklas-r wants to merge 1 commit intomark-hingston:mainfrom
niklas-r:fix/chat-message-hook

Conversation

@niklas-r
Copy link

Problem

ELF's context injection (golden rules, heuristics, past learnings into the system prompt) is not working against the current OpenCode (v1.2.6) plugin API.
Two issues with the current chat.params usage:

  1. Signature mismatch. OpenCode hooks use (input, output) — two separate arguments. The plugin uses async (params) and accesses params.input.message.text. Since params is the input object, params.input resolves to undefined, hitting the if (!userMessage) return bail-out on every call.
  2. Wrong hook for content injection. chat.params only exposes { temperature, topP, options } in its output — there is no systemPrompt or message text to modify. Per the current @opencode-ai/plugin type definitions, this hook is for tweaking LLM parameters, not injecting content.
    Symptoms:
  • elf metrics returns [] — no injection metrics recorded
  • All golden rules have hitCount: 0
  • No [ELF MEMORY] block visible in the agent's system prompt

Fix

Switch from chat.params to chat.message, which provides:

  • output.message.system — the mutable system prompt (UserMessage.system)
  • output.parts — the user's message as Part[] (filtered for TextPart)
"chat.message"?: (input: {
    sessionID: string;
    agent?: string;
    model?: { providerID: string; modelID: string };
    messageID?: string;
}, output: {
    message: UserMessage;  // has system?: string
    parts: Part[];         // TextPart has text: string
}) => Promise<void>;

Changes

  • src/index.ts — Replace chat.params with chat.message, fix signature to (input, output), read user text from output.parts, inject into output.message.system
  • package.json — Update declared hook from chat.params to chat.message
  • README.md — Update architecture diagram to reflect chat.message

Verified

After this fix, the [ELF MEMORY] block is correctly injected into the system prompt on every message, containing golden rules and any matched heuristics:

[ELF MEMORY]
Golden Rules:
- Always validate user inputs before processing to prevent security vulnerabilities
- Use TypeScript strict mode for better type safety and fewer runtime errors
...
Applicable Heuristics:
- When creating e2e tests: use Playwright with the page object pattern... [project]

chat.params receives (input, output) where output only exposes
{temperature, topP, options} — no system prompt or message text.
The plugin was treating the first arg as a wrapper object and
accessing params.input.message.text, which was always undefined,
causing context injection to silently bail on every message.

Switch to chat.message hook which provides output.message.system
(the system prompt) and output.parts (user message TextParts),
matching the OpenCode plugin API contract.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant