Repository navigation
[FEATURE]: Silent Message Insertion API #3378
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Summary
Add ability to insert user messages into sessions without triggering AI inference. This enables plugins to inject context (like Anthropic's Agent Skills pattern) without generating AI responses.
Problem Statement
Current Limitation: The POST /session/{id}/message endpoint is architecturally coupled - it always triggers AI inference when creating a user message. There is no way to add context to a session without receiving an AssistantMessage response.
Impact on Plugins:
- Cannot replicate Anthropic's Agent Skills pattern
- Must use tool responses for context injection
- Tool responses may be purged from context automatically
- Unnecessary AI responses when only adding context
Current Workaround (from opencode-skills plugin):
async execute(args, toolCtx) {
// Can only return string as tool response
return `# ⚠️ SKILL EXECUTION INSTRUCTIONS ⚠️
**SKILL NAME:** ${skill.name}
**SKILL DIRECTORY:** ${skill.fullPath}/
## PATH RESOLUTION RULES:
All file paths mentioned below are relative to: ${skill.fullPath}/
---
${skill.content}
`
}Problems with Current Approach:
- ❌ Tool responses may be purged from context
- ❌ More verbose than needed
- ❌ Doesn't match Anthropic's clean pattern
- ❌ No control over message persistence
Use Case: Anthropic Agent Skills Pattern
Anthropic's Claude Code uses a clean pattern for skill execution:
1. Tool call to skills_klorpify
2. User message: "The 'klorpify' skill is running"
3. User message: "Base directory: /path\n\nContent..."
4. Tool response: "Launching skill: klorpify"
Key Characteristics:
- User messages inserted without triggering AI
- Multiple user messages in sequence
- Minimal tool response
- Clean, persistent context injection
This pattern is currently impossible in OpenCode because:
session.prompt()always triggers inference- No API exists for silent message insertion
- Plugins can only return strings from tools
- No internal API access from plugin context
Proposed Solution
Add a skipInference parameter to the existing POST /session/{id}/message endpoint.
Option A: skipInference Parameter
API Change:
POST /session/{id}/message
{
"skipInference": true, // ← NEW optional parameter
"parts": [{
"type": "text",
"text": "Context to inject without AI response"
}]
}Behavior When skipInference: true:
- Creates and stores UserMessage
- Publishes
message.updatedevent - Does NOT call
streamText() - Returns
{ message: UserMessage }(no AssistantMessage)
Plugin Usage Example:
async execute(args, toolCtx) {
const client = createOpencodeClient()
// Inject skill content as user message
await client.session.prompt({
path: { id: toolCtx.sessionID },
body: {
skipInference: true,
parts: [{
type: "text",
text: `Base directory: ${skill.fullPath}\n\n${skill.content}`,
}]
}
})
// Return minimal tool response
return `Launching skill: ${skill.name}`
}Advantages:
- ✅ Minimal code changes
- ✅ Backward compatible (default: false)
- ✅ Explicit and clear intent
- ✅ Works with existing SDK clients
- ✅ No new endpoint needed
Option B: New Endpoint (Alternative)
Create dedicated POST /session/{id}/context endpoint for context injection.
Advantages:
- ✅ Cleaner separation of concerns
- ✅ Explicit intent via endpoint name
- ✅ Doesn't modify existing endpoint semantics
Disadvantages:
- ❌ More code changes
- ❌ New API surface to maintain
- ❌ Requires SDK regeneration
Related Issues
- opencode-skills Issue #2
- Anthropic Agent Skills pattern compatibility
Questions for Discussion
- How should injected messages be rendered in the UI (hidden, visible)?
I'm happy to implement this feature if the approach is approved. Please let me know if you'd like me to open a PR with Option A (recommended) or if you'd prefer Option B (new endpoint).
Activity
rekram1-node commentedon Oct 24, 2025
how does this solve for tool call purges tho, thats a good point for this
malhashemi commentedon Oct 24, 2025
It would allow plugins to insert a message into context (in my case it is the SKILL.md content) as a user message (Exactly how anthropic is doing it at the moment) currently I am returning the file content as a tool response which could get purged.
If I simply use the current endpoint then it will trigger a new AI response. If the agent is already working it will be queued.
I know the team is busy and I think I have an idea of a minimal approach to allow this behaviour but would like to get your blessings before pulling any work/PR.
rekram1-node commentedon Oct 24, 2025
ah okay i see
rekram1-node commentedon Oct 24, 2025
Yeah i think that's fine then you just need to add it to prompt input, add early return after create User message call, and then regenerate typescript sdk
I don't love
skipInferencebut other names don't come to mindgregid commentedon Oct 24, 2025
Nice addition.
Some alternative names that come to mind:
malhashemi commentedon Oct 25, 2025
@gregid thanks for your comment I think I will go with
"mode": "context"with the default being "message", just in case someone might think of an addtional functionality in the future so they can simply expand with another mode. @rekram1-node what do you think?rekram1-node commentedon Oct 25, 2025
@malhashemi we already have other notions of "mode" and so do other tools, I'd prefer something more explicit and distinct
malhashemi commentedon Oct 25, 2025
@rekram1-node the only other option I can think of other than
skipInference: truewhich explains the functionality technically would becontextOnly: truethat one is focusing on the behaviour rather than what it technically does. Pick one :)rekram1-node commentedon Oct 25, 2025
I think either of those work fine I will leave it up to you, I will say that I do kinda like
noReplyit is pretty explicit and simple (but like i said u can decide :))malhashemi commentedon Oct 25, 2025
noReplyis actually nice I will go with that one! Thanksmalhashemi commentedon Oct 25, 2025
@rekram1-node ready for your review, I have added tests as well let me know if you would like to drop these, feel free to edit as you see fit. Thanks
malhashemi commentedon Oct 26, 2025
This is now resolved by #3433