You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.6 KiB
Markdown
193 lines
5.6 KiB
Markdown
# GraphTool Package
|
|
|
|
This package provides utilities for wrapping Eino's composition types (`compose.Graph`, `compose.Chain`, `compose.Workflow`) as agent tools. It enables you to expose complex multi-step processing pipelines as single tools that can be used by `ChatModelAgent`.
|
|
|
|
## Overview
|
|
|
|
The package provides two main tool types:
|
|
|
|
| Tool Type | Interface | Use Case |
|
|
|-----------|-----------|----------|
|
|
| `InvokableGraphTool` | `tool.InvokableTool` | Standard request-response tools |
|
|
| `StreamableGraphTool` | `tool.StreamableTool` | Tools that stream output incrementally |
|
|
|
|
Both tools support:
|
|
- Any `Compilable` type (`compose.Graph`, `compose.Chain`, `compose.Workflow`)
|
|
- Interrupt/Resume for human-in-the-loop workflows
|
|
- Checkpoint-based state persistence
|
|
|
|
## Installation
|
|
|
|
```go
|
|
import "github.com/cloudwego/eino-examples/adk/common/tool/graphtool"
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### InvokableGraphTool
|
|
|
|
Wrap a composition as a standard invokable tool:
|
|
|
|
```go
|
|
// Define input/output types
|
|
type MyInput struct {
|
|
Query string `json:"query" jsonschema_description:"The query to process"`
|
|
}
|
|
|
|
type MyOutput struct {
|
|
Result string `json:"result"`
|
|
}
|
|
|
|
// Create a chain/graph/workflow
|
|
chain := compose.NewChain[*MyInput, *MyOutput]()
|
|
chain.AppendLambda(compose.InvokableLambda(func(ctx context.Context, input *MyInput) (*MyOutput, error) {
|
|
return &MyOutput{Result: "Processed: " + input.Query}, nil
|
|
}))
|
|
|
|
// Wrap as tool
|
|
tool, err := graphtool.NewInvokableGraphTool[*MyInput, *MyOutput](
|
|
chain,
|
|
"my_tool",
|
|
"Description of what this tool does",
|
|
)
|
|
```
|
|
|
|
### StreamableGraphTool
|
|
|
|
Wrap a composition as a streaming tool (useful when the final node streams output):
|
|
|
|
```go
|
|
// Graph that outputs streaming messages
|
|
graph := compose.NewGraph[*MyInput, *schema.Message]()
|
|
graph.AddChatModelNode("llm", chatModel)
|
|
// ... add edges ...
|
|
|
|
// Wrap as streaming tool
|
|
tool, err := graphtool.NewStreamableGraphTool[*MyInput, *schema.Message](
|
|
graph,
|
|
"streaming_tool",
|
|
"A tool that streams its response",
|
|
)
|
|
|
|
// Use with ReturnDirectly for direct streaming to user
|
|
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
|
|
// ...
|
|
ToolsConfig: adk.ToolsConfig{
|
|
ToolsNodeConfig: compose.ToolsNodeConfig{
|
|
Tools: []tool.BaseTool{tool},
|
|
},
|
|
ReturnDirectly: map[string]bool{
|
|
"streaming_tool": true,
|
|
},
|
|
},
|
|
})
|
|
```
|
|
|
|
## Compilable Interface
|
|
|
|
Both tool types accept any type implementing the `Compilable` interface:
|
|
|
|
```go
|
|
type Compilable[I, O any] interface {
|
|
Compile(ctx context.Context, opts ...compose.GraphCompileOption) (compose.Runnable[I, O], error)
|
|
}
|
|
```
|
|
|
|
This includes:
|
|
- `compose.Graph[I, O]`
|
|
- `compose.Chain[I, O]`
|
|
- `compose.Workflow[I, O]`
|
|
|
|
## Interrupt/Resume Support
|
|
|
|
GraphTools fully support Eino's interrupt/resume mechanism for human-in-the-loop workflows:
|
|
|
|
```go
|
|
// Inside a workflow node
|
|
if needsApproval {
|
|
return nil, compose.StatefulInterrupt(ctx, &ApprovalInfo{
|
|
Message: "Approval required",
|
|
}, currentState)
|
|
}
|
|
```
|
|
|
|
The tool automatically:
|
|
1. Captures checkpoint state when interrupted
|
|
2. Wraps the interrupt with `CompositeInterrupt` for proper propagation
|
|
3. Restores state and resumes execution when `runner.ResumeWithParams` is called
|
|
|
|
### Composable Tool Wrappers
|
|
|
|
GraphTools implement standard `tool.InvokableTool` or `tool.StreamableTool` interfaces, making them compatible with any tool wrapper in the ecosystem. Examples of wrappers you can use:
|
|
|
|
- **`InvokableApprovableTool`**: Adds human approval before tool execution
|
|
- **`InvokableReviewEditTool`**: Allows users to review and edit tool arguments
|
|
- **`FollowUpTool`**: Asks users follow-up questions during execution
|
|
- Custom wrappers you create
|
|
|
|
### Nested Interrupts
|
|
|
|
When a GraphTool with internal interrupts is wrapped by another interrupt-based wrapper (e.g., `InvokableApprovableTool`), both interrupt layers work independently:
|
|
|
|
1. **Outer interrupt**: Wrapper-level interrupt (e.g., approval via `InvokableApprovableTool`)
|
|
2. **Inner interrupt**: Workflow-level interrupt (via `StatefulInterrupt` inside graph nodes)
|
|
|
|
This works because each layer uses distinct interrupt state types, preventing conflicts.
|
|
|
|
## Tool Options
|
|
|
|
Pass compose options to the underlying runnable:
|
|
|
|
```go
|
|
result, err := tool.InvokableRun(ctx, argsJSON,
|
|
graphtool.WithGraphToolOption(
|
|
compose.WithCallbacks(myCallback),
|
|
),
|
|
)
|
|
```
|
|
|
|
## Examples
|
|
|
|
See the [examples](./examples) directory for complete working examples:
|
|
|
|
| Example | Description |
|
|
|---------|-------------|
|
|
| [1_chain_summarize](./examples/1_chain_summarize) | Document summarization using `compose.Chain` |
|
|
| [2_graph_research](./examples/2_graph_research) | Multi-source research with `compose.Graph` + streaming |
|
|
| [3_workflow_order](./examples/3_workflow_order) | Order processing with `compose.Workflow` + approval |
|
|
| [4_nested_interrupt](./examples/4_nested_interrupt) | Nested interrupts (outer approval + inner risk check) |
|
|
|
|
## API Reference
|
|
|
|
### NewInvokableGraphTool
|
|
|
|
```go
|
|
func NewInvokableGraphTool[I, O any](
|
|
compilable Compilable[I, O],
|
|
name, desc string,
|
|
opts ...compose.GraphCompileOption,
|
|
) (*InvokableGraphTool[I, O], error)
|
|
```
|
|
|
|
Creates a new invokable tool from a compilable composition.
|
|
|
|
### NewStreamableGraphTool
|
|
|
|
```go
|
|
func NewStreamableGraphTool[I, O any](
|
|
compilable Compilable[I, O],
|
|
name, desc string,
|
|
opts ...compose.GraphCompileOption,
|
|
) (*StreamableGraphTool[I, O], error)
|
|
```
|
|
|
|
Creates a new streaming tool from a compilable composition.
|
|
|
|
### WithGraphToolOption
|
|
|
|
```go
|
|
func WithGraphToolOption(opts ...compose.Option) tool.Option
|
|
```
|
|
|
|
Wraps compose options as tool options for passing to `InvokableRun` or `StreamableRun`.
|