Repository navigation
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Note on #17637: That issue requests user message text in
experimental.chat.system.transformfor targeted context injection. This issue is related but distinct — it requests that the already-firingchat.messagehook populate itspartsarray with actual prompt/output text, enabling telemetry and observability use cases (not system prompt manipulation). #17637 was closed as not planned, but the underlying need remains: plugins currently cannot access message bodies through any hook.
Describe the enhancement you want to request
Summary
The chat.message plugin hook fires correctly, but the runtime delivers an empty parts array in the payload. This prevents plugins from capturing prompt or assistant response text for telemetry, observability, and audit use cases — even though the hook itself is invoked and tool args/results flow through fine.
What we observed
We built a telemetry plugin that instruments all available hooks (chat.message, experimental.chat.messages.transform, experimental.text.complete) and added diagnostic shadow logging for chat.message payloads.
Across 4 systematic test passes:
chat.messagedoes fire — 3 shadow log entries confirmed- Payload shape:
{ sessionID, agent, model, messageID, variant }— metadata only partsis always an empty array (partsPreview: [])promptsCapturedandoutputsCapturedcounters stayed at 0 until we added fallback capture via assistant event metadata- No hook failures occurred — the plumbing works, but the content is withheld
- Tool args/results are available and rich via tool event hooks, confirming the plugin system itself is functional
What we want changed
Populate parts in the chat.message hook payload with the actual message content (user prompt text for user messages, assistant response text for assistant messages). This would allow plugins to:
- Capture prompt/output text for enterprise telemetry and audit trails
- Build observability dashboards that include conversation content (with plugin-side redaction)
- Implement content-aware plugin behaviors (summarization, compliance scanning, etc.)
Why this is different from #17637
| #17637 | This issue | |
|---|---|---|
| Hook | experimental.chat.system.transform |
chat.message |
| Goal | Inject context into system prompt based on user message | Capture message bodies for telemetry/audit |
| Timing | Needs content before LLM call | Content after hook fires is fine |
| Use case | Memory/RAG injection | Observability/telemetry |
Environment
- OpenCode version:
1.4.3 - Plugin API:
@opencode-ai/[email protected] - Tested in a real workspace session with a custom telemetry plugin across 4 diagnostic passes
Evidence available
We have sanitized shadow log payloads, collector metrics showing the empty-parts pattern, and a full diagnostic writeup. Happy to share if helpful.
Activity
github-actions commentedon Apr 16, 2026
This issue doesn't fully meet our contributing guidelines.
What needs to be fixed:
[FEATURE]:), or Question. This issue appears to be a bug report or feature request — pick the most appropriate template and fill in the required fields.Please edit this issue to address the above within 2 hours, or it will be automatically closed.
This issue might be a duplicate of or closely related to existing issues. Please check:
If you believe this was flagged incorrectly, please let a maintainer know.
[-]Plugin chat.message hook fires with empty parts, blocking prompt/output capture[/-][+][FEATURE]: Expose prompt/output message bodies to plugin chat.message hook[/+]github-actions commentedon Apr 16, 2026
Thanks for updating the issue! It now follows the contributing guidelines — the Feature Request template is properly filled out with a clear description, environment details, and evidence of testing. The
needs:compliancelabel has been removed.doobidoo commentedon May 23, 2026
We can confirm the empty-parts pattern from the plugin side. While building the MCP Memory Service plugin for OpenCode, we traced through the plugin loader source (
packages/opencode/src/plugin/index.ts) and found thatchat.messageis not triggered at all in some builds — thetrigger("chat.message", ...)call site doesn't exist in the session processor.Workaround: use the
eventhook with bus subscription to listen formessage.part.updatedbus events. These carry the full text content inevent.properties.part.textfor TextPart and ReasoningPart objects.Working plugin (820 lines, zero external deps): https://github.com/doobidoo/mcp-memory-service/blob/main/opencode/memory-plugin.js
Hooks we use:
event— catchesmessage.part.updated,session.created,session.deletedexperimental.chat.system.transform— memory injection into system promptexperimental.session.compacting— memory preservationAlso opened #29022 with more context.
github-actions commentedon Jul 23, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.
fix(memory-worth): read user text from event bus instead of empty out…
chore: sync baba prompt system