Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 9 additions & 14 deletions internal/llminternal/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
package llminternal

import (
"time"

"google.golang.org/genai"

"google.golang.org/adk/agent"
Expand Down Expand Up @@ -78,18 +76,15 @@ func generateRequestConfirmationEvent(
return nil
}

return &session.Event{
InvocationID: invocationContext.InvocationID(),
Author: invocationContext.Agent().Name(),
Branch: invocationContext.Branch(),
LLMResponse: model.LLMResponse{
Content: &genai.Content{
Parts: parts,
Role: genai.RoleModel,
},
ev := session.NewEvent(invocationContext.InvocationID())
ev.Author = invocationContext.Agent().Name()
ev.Branch = invocationContext.Branch()
ev.LLMResponse = model.LLMResponse{
Content: &genai.Content{
Parts: parts,
Role: genai.RoleModel,
},
Timestamp: time.Now(),
LongRunningToolIDs: longRunningToolIDs,
Actions: session.EventActions{},
}
ev.LongRunningToolIDs = longRunningToolIDs
return ev
}
62 changes: 62 additions & 0 deletions internal/llminternal/functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ func TestGenerateRequestConfirmationEvent(t *testing.T) {
InvocationID: "inv_1",
Author: "agent_1",
Branch: "main",
Actions: session.EventActions{
StateDelta: map[string]any{},
},
LLMResponse: model.LLMResponse{
Content: &genai.Content{
Role: genai.RoleModel,
Expand Down Expand Up @@ -189,3 +192,62 @@ func TestGenerateRequestConfirmationEvent(t *testing.T) {
})
}
}

// TestGenerateRequestConfirmationEventHasID verifies that the event returned
// by generateRequestConfirmationEvent always has a non-empty ID.
//
// In Python ADK, every Event gets a UUID via model_post_init:
//
// def model_post_init(self, __context):
// if not self.id:
// self.id = Event.new_id() # str(uuid.uuid4())
//
// In Go ADK, events must be created with session.NewEvent() to get an ID.
// A raw &session.Event{} literal leaves ID as "" which breaks features
// that rely on event IDs (e.g. time-travel restart_from_event_id).
func TestGenerateRequestConfirmationEventHasID(t *testing.T) {
confirmingFunctionCall := &genai.FunctionCall{
ID: "call_1",
Name: "test_tool",
Args: map[string]any{"arg": "val"},
}

ctx := &mockInvocationContext{
invocationID: "inv_1",
agentName: "agent_1",
branch: "main",
}

functionCallEvent := &session.Event{
LLMResponse: model.LLMResponse{
Content: &genai.Content{
Parts: []*genai.Part{
{FunctionCall: confirmingFunctionCall},
},
},
},
}

functionResponseEvent := &session.Event{
Actions: session.EventActions{
RequestedToolConfirmations: map[string]toolconfirmation.ToolConfirmation{
"call_1": {
Hint: "Are you sure?",
},
},
},
}

got := generateRequestConfirmationEvent(ctx, functionCallEvent, functionResponseEvent)
if got == nil {
t.Fatal("expected non-nil event")
}

if got.ID == "" {
t.Error("event ID is empty; events must have a UUID for time-travel and session lookup")
}

if got.InvocationID != "inv_1" {
t.Errorf("expected InvocationID=\"inv_1\", got %q", got.InvocationID)
}
}