feat(plugin): add ToolResult type for structured tool responses #4596

Open
opened 2026-02-16 17:44:44 -05:00 by yindo · 0 comments
Owner

Originally created by @aryasaatvik on GitHub (Jan 10, 2026).

Originally assigned to: @thdxr on GitHub.

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:

  1. ToolResult interface - Structured response type with title, metadata, output
  2. ctx.metadata() method - Real-time streaming updates during tool execution
  3. Registry handling - Proper propagation of structured results
  4. 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.
Originally created by @aryasaatvik on GitHub (Jan 10, 2026). Originally assigned to: @thdxr on GitHub. ## 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: 1. **`ToolResult` interface** - Structured response type with title, metadata, output 2. **`ctx.metadata()` method** - Real-time streaming updates during tool execution 3. **Registry handling** - Proper propagation of structured results 4. **Backward compatibility** - Plain string returns still work ## Example: Background Task with Progress **Before** (limited metadata): ```typescript async execute(args, ctx) { return "3 files found" // Just a string } ``` **After** (rich metadata + streaming): ```typescript 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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#4596