micro/go-micro · error

agent: StreamAsk unsupported by implementation

Error message

agent: StreamAsk unsupported by implementation

What it means

StreamAsk is a helper that streams agent responses only when the underlying Agent implementation also implements a StreamAsk(context.Context, string) (AgentStream, error) method via an anonymous interface check. If the agent does not support streaming, this sentinel error is returned instead of a stream. It exists to let callers opt into streaming without requiring every Agent to implement it.

Solutions

  1. Use an agent implementation that supports streaming (e.g. the library's agentImpl)
  2. Check support first with a type assertion to interface{ StreamAsk(context.Context, string) (AgentStream, error) } and fall back to Ask
  3. Wrap custom agent types to forward StreamAsk to the inner agent

Example fix

// before
stream, err := agent.StreamAsk(ctx, myWrapper{inner: ag}, "hi")
// after
streamer, ok := ag.(interface{ StreamAsk(context.Context, string) (AgentStream, error) })
if !ok {
    resp, err := agent.Ask(ctx, ag, "hi") // fallback
} else {
    stream, err := streamer.StreamAsk(ctx, "hi")
}
Defensive patterns

Strategy: type-guard

Validate before calling

streamer, ok := ag.(interface{ StreamAsk(context.Context, string) (AgentStream, error) })
if !ok { /* fallback to Ask */ }

Type guard

func supportsStreamAsk(ag agent.Agent) bool {
    _, ok := ag.(interface{ StreamAsk(context.Context, string) (AgentStream, error) })
    return ok
}

Try / catch

stream, err := agent.StreamAsk(ctx, ag, msg)
if err != nil && strings.Contains(err.Error(), "unsupported by implementation") {
    resp, err := agent.Ask(ctx, ag, msg) // non-streaming fallback
}

Prevention

When it happens

Trigger: Calling agent.StreamAsk(ctx, ag, message) where ag is an Agent whose concrete type does not define a StreamAsk method (only plain Ask).

Common situations: Wrapping or decorating an agent with a custom type that forwards Ask but not StreamAsk; using an older or custom agent implementation predating streaming support; passing a mock/stub agent in tests.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/2f73b7f6b20fb69b. Report an issue: GitHub.

Appendix: source

Thrown at agent/stream.go:53

	Result   ai.ToolResult
	Response *Response
}

// AgentStream is a stream of tool execution events followed by final-answer chunks.
type AgentStream interface {
	Recv() (*StreamEvent, error)
	Close() error
}

// StreamAsk runs an agent Ask turn with tool start/end events and streams the final answer.
// It is additive for callers that hold the public Agent interface; concrete agents also
// expose the same method directly.
func StreamAsk(ctx context.Context, ag Agent, message string) (AgentStream, error) {
	streamer, ok := ag.(interface {
		StreamAsk(context.Context, string) (AgentStream, error)
	})
	if !ok {
		return nil, errors.New("agent: StreamAsk unsupported by implementation")
	}
	return streamer.StreamAsk(ctx, message)
}

// ResumeStreamAsk resumes a checkpointed agent run and emits the same event
// shape as StreamAsk. Completed runs are streamed from the persisted response;
// unfinished runs continue from their checkpoint and emit tool events for any
// work that still needs to run. Tool calls already recorded as done in the
// checkpoint are reused by the agent checkpoint wrapper and are not re-executed.
func ResumeStreamAsk(ctx context.Context, ag Agent, runID string) (AgentStream, error) {
	a, ok := ag.(*agentImpl)
	if !ok {
		return nil, errors.New("agent: ResumeStreamAsk unsupported by implementation")
	}
	return a.resumeStreamAsk(ctx, runID)
}

// StreamAsk runs tools like Ask, emits ToolStart/ToolEnd events as they execute,

View on GitHub (pinned to 24529f1404)