Repository: google/adk-go
File: tool.go (Go)

Code before:
	InvocationContext *InvocationContext

	// The function call id of the current tool call.
	// This id was returned in the function call event from LLM to identify
	// a function call. If LLM didn't return an id, ADK will assign one t it.
	// This id is used to map function call response to the original function call.
	FunctionCallID string

	// The event actions of the current tool call.
	EventActions *EventActions
}

// TODO: Implement an MCP client as a tool to validate whether
// a concrete type is sufficient for tool use.

// Tool is an ADK tool.
type Tool struct {
	Name        string
	Description string
	InputSchema *jsonschema.Schema

	rawHandler rawToolHandler
}

// Run executes the tool with the provided context and yields events.
func (t *Tool) Run(ctx context.Context, tc *ToolContext) EventStream {
	return t.rawHandler(ctx, tc)
}

// ToolHandler is the execution handler of a tool.
type ToolHandler[In, Out any] func(ctx context.Context, input In) (output Out, err error)

type rawToolHandler func(ctx context.Context, tc *ToolContext) EventStream

// NewTool creates a new tool with a name, description, and the provided handler.
// Input schema is automatically inferred from the input and output types.
func NewTool[In, Out any](name string, description string, handler ToolHandler[In, Out]) *Tool {
	// TODO(jbd): Add ToolOption as variadic arguments to NewTool.
	ischema, err := jsonschema.For[In]()
	if err != nil {
		panic(fmt.Errorf("NewTool(%q): %w", name, err))
	}
	rawHandler := func(ctx context.Context, tc *ToolContext) EventStream {
		panic("not yet implemented")
		// TODO: Handle function call request from tc.InvocationContext.
		// TODO: Unmarshal into input.
		// TODO: Make a call to handler.
		// TODO: Yield events with the output.
	}
	return &Tool{
		Name:        name,

Review comment (suggestion):
I guess this is going to be called in response to the LLM's FunctionCall response.
I noticed that Google `genai.FunctionCall` uses `map[string]any`  (https://github.com/googleapis/go-genai/blob/fcc623bc7644261b0393de54bb13c0754e730d4d/types.go#L633)
and `genai.FunctionResponse` also uses `map[string]any` (https://github.com/googleapis/go-genai/blob/fcc623bc7644261b0393de54bb13c0754e730d4d/types.go#L646).

I wonder if this will be more like  `Run(ctx context.Context, tc *ToolContext, args map[string]any) (map[string]any, error)`. 

We can reiterate this. 

Code after:
	InvocationContext *InvocationContext

	// The function call id of the current tool call.
	// This id was returned in the function call event from LLM to identify
	// a function call. If LLM didn't return an id, ADK will assign one t it.
	// This id is used to map function call response to the original function call.
	FunctionCallID string

	// The event actions of the current tool call.
	EventActions *EventActions
}

// TODO: Implement an MCP client as a tool to validate whether
// a concrete type is sufficient for tool use.

// Tool is an ADK tool.
type Tool struct {
	Name        string
	Description string
	InputSchema *jsonschema.Schema
	// TODO: OutputSchema

	rawHandler rawToolHandler
}

// Run executes the tool with the provided context and yields events.
func (t *Tool) Run(ctx context.Context, tc *ToolContext, args map[string]any) (map[string]any, error) {
	return t.rawHandler(ctx, tc, args)
}

// ToolHandler is the execution handler of a tool.
type ToolHandler[In, Out any] func(ctx context.Context, input In) (output Out, err error)

type rawToolHandler func(ctx context.Context, tc *ToolContext, args map[string]any) (map[string]any, error)

// NewTool creates a new tool with a name, description, and the provided handler.
// Input schema is automatically inferred from the input and output types.
func NewTool[In, Out any](name string, description string, handler ToolHandler[In, Out]) *Tool {
	// TODO(jbd): Add ToolOption as variadic arguments to NewTool.
	ischema, err := jsonschema.For[In]()
	if err != nil {
		panic(fmt.Errorf("NewTool(%q): %w", name, err))
	}
	rawHandler := func(ctx context.Context, tc *ToolContext, args map[string]any) (map[string]any, error) {
		panic("not yet implemented")
		// TODO: Handle function call request from tc.InvocationContext.
		// TODO: Unmarshal into input.
		// TODO: Make a call to handler.
		// TODO: Yield events with the output.
	}
	return &Tool{