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

Code before:
		}
	}
}

func (f *baseFlow) finalizeModelResponseEvent(parentCtx *adk.InvocationContext, resp *adk.LLMResponse) *adk.Event {
	// FunctionCall & FunctionResponse matching algorithm assumes non-empty function call IDs
	// but function call ID is optional in genai API and some models do not use the field.
	// Generate function call ids. (see functions.populate_client_function_call_id in python SDK)
	populateClientFunctionCallID(resp.Content)

	ev := adk.NewEvent(parentCtx.InvocationID)
	ev.Author = parentCtx.Agent.Name()
	ev.Branch = parentCtx.Branch
	ev.LLMResponse = resp

	// TODO: populate ev.LongRunningToolIDs (see BaseLlmFlow._finalize_model_response_event)

	return ev
}

func (f *baseFlow) preprocess(ctx context.Context, parentCtx *adk.InvocationContext, req *adk.LLMRequest) error {
	llmAgent := asLLMAgent(parentCtx.Agent)
	if llmAgent == nil {
		return nil
	}
	// apply request processor functions to the request in the configured order.
	for _, processor := range f.RequestProcessors {
		if err := processor(ctx, parentCtx, req); err != nil {
			return err
		}
	}
	// run processors for tools.
	for _, t := range llmAgent.Tools {
		toolCtx := &adk.ToolContext{
			InvocationContext: parentCtx, // TODO: how to prevent mutation on this?
			EventActions:      &adk.EventActions{},
		}
		if err := t.ProcessRequest(ctx, toolCtx, req); err != nil {
			return err
		}
	}
	return nil
}

func (f *baseFlow) callLLM(ctx context.Context, parentCtx *adk.InvocationContext, req *adk.LLMRequest) adk.LLMResponseStream {
	return func(yield func(*adk.LLMResponse, error) bool) {

		// TODO: run BeforeModelCallback if exists.
		//   if f.BeforeModelCallback != nil {
		//      resp, err := f.BeforeModelCallback(...)
		//      yield(resp, err)

Review comment (suggestion):
```suggestion
	// run processors for tools.
	// TODO: check feasibility of running this concurrently
```

Code after:
	// but function call ID is optional in genai API and some models do not use the field.
	// Generate function call ids. (see functions.populate_client_function_call_id in python SDK)
	populateClientFunctionCallID(resp.Content)

	ev := adk.NewEvent(parentCtx.InvocationID)
	ev.Author = parentCtx.Agent.Name()
	ev.Branch = parentCtx.Branch
	ev.LLMResponse = resp

	// TODO: populate ev.LongRunningToolIDs (see BaseLlmFlow._finalize_model_response_event)

	return ev
}

func (f *baseFlow) preprocess(ctx context.Context, parentCtx *adk.InvocationContext, req *adk.LLMRequest) error {
	llmAgent := asLLMAgent(parentCtx.Agent)
	if llmAgent == nil {
		return nil
	}
	// apply request processor functions to the request in the configured order.
	for _, processor := range f.RequestProcessors {
		if err := processor(ctx, parentCtx, req); err != nil {
			return err
		}
	}
	// run processors for tools.
	// TODO: check need/feasibility of running this concurrently.
	for _, t := range llmAgent.Tools {
		toolCtx := &adk.ToolContext{
			InvocationContext: parentCtx, // TODO: how to prevent mutation on this?
			EventActions:      &adk.EventActions{},
		}
		if err := t.ProcessRequest(ctx, toolCtx, req); err != nil {
			return err
		}
	}
	return nil
}

func (f *baseFlow) callLLM(ctx context.Context, parentCtx *adk.InvocationContext, req *adk.LLMRequest) adk.LLMResponseStream {
	return func(yield func(*adk.LLMResponse, error) bool) {

		// TODO: run BeforeModelCallback if exists.
		//   if f.BeforeModelCallback != nil {
		//      resp, err := f.BeforeModelCallback(...)
		//      yield(resp, err)
		//      return
		//   }

		// TODO: Set _ADK_AGENT_NAME_LABEL_KEY in req.GenerateConfig.Labels
		// to help with slicing the billing reports on a per-agent basis.