Files
ragflow/internal/harness/core/tool_contributor.go
Yingfeng 706e0d2d06 Refactor harness framework (#16271)
### What problem does this PR solve?

- Tools management
- Pregel engine wrapper for better usage
- UT race
- Coding style

### Type of change

- [x] Refactoring
2026-06-23 20:18:04 +08:00

89 lines
2.9 KiB
Go

package core
import (
"context"
"ragflow/internal/harness/core/schema"
)
// ToolContributor is an optional interface that middlewares can implement to
// contribute tools, tool infos, and return-directly entries to the agent.
//
// The agent loop collects contributions BEFORE calling BeforeAgent, ensuring
// that tools are available for both ToolsNode construction and BeforeAgent
// middleware processing. This replaces the unreliable pattern of modifying
// rc.Tools in BeforeAgent (which doesn't propagate to ToolsNode) and the
// timing-coupled BindToConfig pattern.
//
// Example:
//
// type myMiddleware struct {
// BaseMiddleware[M]
// }
//
// func (m *myMiddleware) ContributeTools(ctx context.Context) []Tool {
// return []Tool{NewBaseTool("my_tool", "Does something", myFunc)}
// }
type ToolContributor[M MessageType] interface {
// ContributeTools returns tools to add to the agent's tool set.
// Called once during agent build (before BeforeAgent).
ContributeTools(ctx context.Context) []Tool
// ContributeToolInfos returns structured ToolInfo entries to bind to the
// model. These are merged with auto-generated infos from ContributeTools.
// Use this for special entries that don't correspond to a Tool (e.g.,
// a meta-tool like "search_tools" for dynamic tool search).
ContributeToolInfos(ctx context.Context) []*schema.ToolInfo
// ContributeReturnDirectly returns tool names that should cause the agent
// to return immediately after execution. Merged with config-level
// ReturnDirectly.
ContributeReturnDirectly(ctx context.Context) map[string]bool
}
// ---- Collection helpers ----
// collectContributorTools returns tools contributed by all ToolContributor middlewares.
func collectContributorTools[M MessageType](ctx context.Context, middlewares []TypedReActMiddleware[M]) []Tool {
var all []Tool
for _, mw := range middlewares {
if mw == nil {
continue
}
if c, ok := mw.(ToolContributor[M]); ok {
all = append(all, c.ContributeTools(ctx)...)
}
}
return all
}
// collectContributorToolInfos returns tool infos contributed by all ToolContributor middlewares.
func collectContributorToolInfos[M MessageType](ctx context.Context, middlewares []TypedReActMiddleware[M]) []*schema.ToolInfo {
var all []*schema.ToolInfo
for _, mw := range middlewares {
if mw == nil {
continue
}
if c, ok := mw.(ToolContributor[M]); ok {
all = append(all, c.ContributeToolInfos(ctx)...)
}
}
return all
}
// collectContributorReturnDirectly merges return-directly entries from all ToolContributor middlewares.
func collectContributorReturnDirectly[M MessageType](ctx context.Context, middlewares []TypedReActMiddleware[M]) map[string]bool {
all := make(map[string]bool)
for _, mw := range middlewares {
if mw == nil {
continue
}
if c, ok := mw.(ToolContributor[M]); ok {
for k, v := range c.ContributeReturnDirectly(ctx) {
all[k] = v
}
}
}
return all
}