Summary
Plugin tools lacked support for structured responses and real-time streaming metadata, preventing advanced features like background tasks with progress updates.
Problem
When building a plugin to support background tasks, we encountered limitations:
1. No Structured Response Support
Plugin tools could only return plain strings. Any metadata (tool counts, status, progress) was lost because fromPlugin always returned metadata: {}.
Impact: Background tasks couldn't display tool counts, subagent types, or progress updates.
2. No Streaming During Execution
Long-running operations (file searches, API calls, subagent tasks) had no way to emit progress updates. The UI showed a static "Running..." state until completion.
Impact: Poor UX for multi-step operations with no feedback.
Solution
PR #6544 adds:
ToolResult interface - Structured response type with title, metadata, output
ctx.metadata() method - Real-time streaming updates during tool execution
- Registry handling - Proper propagation of structured results
- Backward compatibility - Plain string returns still work
Example: Background Task with Progress
Before (limited metadata):
async execute(args, ctx) {
return "3 files found" // Just a string
}
After (rich metadata + streaming):
async execute(args, ctx) {
ctx.metadata({ title: "Searching...", metadata: { current: 1, total: 5 } })
// ... search ...
ctx.metadata({ title: "Analyzing...", metadata: { current: 2, total: 5 } })
return {
title: "Complete",
metadata: { toolsUsed: 3, duration: "2.3s" },
output: "3 files found",
}
}
Related
- Plugin SDK:
packages/plugin/src/tool.ts
- Registry:
packages/opencode/src/tool/registry.ts
- Core types:
packages/opencode/src/tool/tool.ts
Future Work
- Attachments: The
attachments field was added for alignment with core Tool.Result types, but attachment propagation was not tested. Future work could enable plugins to return images, PDFs, or other file types.
Summary
Plugin tools lacked support for structured responses and real-time streaming metadata, preventing advanced features like background tasks with progress updates.
Problem
When building a plugin to support background tasks, we encountered limitations:
1. No Structured Response Support
Plugin tools could only return plain strings. Any metadata (tool counts, status, progress) was lost because
fromPluginalways returnedmetadata: {}.Impact: Background tasks couldn't display tool counts, subagent types, or progress updates.
2. No Streaming During Execution
Long-running operations (file searches, API calls, subagent tasks) had no way to emit progress updates. The UI showed a static "Running..." state until completion.
Impact: Poor UX for multi-step operations with no feedback.
Solution
PR #6544 adds:
ToolResultinterface - Structured response type with title, metadata, outputctx.metadata()method - Real-time streaming updates during tool executionExample: Background Task with Progress
Before (limited metadata):
After (rich metadata + streaming):
Related
packages/plugin/src/tool.tspackages/opencode/src/tool/registry.tspackages/opencode/src/tool/tool.tsFuture Work
attachmentsfield was added for alignment with coreTool.Resulttypes, but attachment propagation was not tested. Future work could enable plugins to return images, PDFs, or other file types.