diff --git a/.infer/config.yaml b/.infer/config.yaml index 2e68489..a33f652 100644 --- a/.infer/config.yaml +++ b/.infer/config.yaml @@ -243,7 +243,6 @@ a2a: ttl: 300 task: status_poll_seconds: 5 - idle_timeout_sec: 60 polling_strategy: exponential initial_poll_interval_sec: 2 max_poll_interval_sec: 60 diff --git a/CONFIG.md b/CONFIG.md index e48c99c..0bf4870 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -159,7 +159,6 @@ a2a: # Task monitoring configuration task: status_poll_seconds: 5 - idle_timeout_sec: 60 polling_strategy: "exponential" initial_poll_interval_sec: 2 max_poll_interval_sec: 60 diff --git a/cmd/root.go b/cmd/root.go index a5ea0ae..098f63d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -68,7 +68,6 @@ func initConfig() { v.SetDefault("a2a.cache.enabled", defaults.A2A.Cache.Enabled) v.SetDefault("a2a.cache.ttl", defaults.A2A.Cache.TTL) v.SetDefault("a2a.task.status_poll_seconds", defaults.A2A.Task.StatusPollSeconds) - v.SetDefault("a2a.task.idle_timeout_sec", defaults.A2A.Task.IdleTimeoutSec) v.SetDefault("a2a.task.polling_strategy", defaults.A2A.Task.PollingStrategy) v.SetDefault("a2a.task.initial_poll_interval_sec", defaults.A2A.Task.InitialPollIntervalSec) v.SetDefault("a2a.task.max_poll_interval_sec", defaults.A2A.Task.MaxPollIntervalSec) diff --git a/config/config.go b/config/config.go index e53f08d..a29b505 100644 --- a/config/config.go +++ b/config/config.go @@ -360,7 +360,6 @@ type A2AAgentInfo struct { // A2ATaskConfig contains configuration for A2A task processing type A2ATaskConfig struct { StatusPollSeconds int `yaml:"status_poll_seconds" mapstructure:"status_poll_seconds"` - IdleTimeoutSec int `yaml:"idle_timeout_sec" mapstructure:"idle_timeout_sec"` PollingStrategy string `yaml:"polling_strategy" mapstructure:"polling_strategy"` InitialPollIntervalSec int `yaml:"initial_poll_interval_sec" mapstructure:"initial_poll_interval_sec"` MaxPollIntervalSec int `yaml:"max_poll_interval_sec" mapstructure:"max_poll_interval_sec"` @@ -643,7 +642,6 @@ Respond with ONLY the title, no quotes or explanation.`, }, Task: A2ATaskConfig{ StatusPollSeconds: 5, - IdleTimeoutSec: 60, PollingStrategy: "exponential", InitialPollIntervalSec: 2, MaxPollIntervalSec: 60, diff --git a/internal/services/tools/a2a_task.go b/internal/services/tools/a2a_task.go index f586e70..8f55a6d 100644 --- a/internal/services/tools/a2a_task.go +++ b/internal/services/tools/a2a_task.go @@ -24,16 +24,14 @@ type A2ASubmitTaskTool struct { // A2ASubmitTaskResult represents the result of an A2A task operation type A2ASubmitTaskResult struct { - TaskID string `json:"task_id"` - ContextID string `json:"context_id,omitempty"` - AgentURL string `json:"agent_url"` - State string `json:"state"` - Message string `json:"message"` - TaskResult string `json:"task_result,omitempty"` - Success bool `json:"success"` - WentIdle bool `json:"went_idle,omitempty"` - IdleTimeout time.Duration `json:"idle_timeout,omitempty"` - Task *adk.Task `json:"task,omitempty"` + TaskID string `json:"task_id"` + ContextID string `json:"context_id,omitempty"` + AgentURL string `json:"agent_url"` + State string `json:"state"` + Message string `json:"message"` + TaskResult string `json:"task_result,omitempty"` + Success bool `json:"success"` + Task *adk.Task `json:"task,omitempty"` } // NewA2ASubmitTaskTool creates a new A2A task tool @@ -291,13 +289,8 @@ func (t *A2ASubmitTaskTool) pollTaskInBackground( adkClient := t.getOrCreateClient(agentURL) strategy := t.config.A2A.Task.PollingStrategy - if strategy == "immediate_idle" { - t.handleImmediateIdle(agentURL, taskID, state) - t.stopPolling(taskID) - return - } - currentInterval, deadline := t.initializePollingStrategy(agentURL, taskID, strategy) + currentInterval := t.initializePollingStrategy(agentURL, taskID, strategy) state.CurrentInterval = currentInterval state.NextPollTime = time.Now().Add(currentInterval) @@ -321,16 +314,6 @@ func (t *A2ASubmitTaskTool) pollTaskInBackground( pollingDetails.WriteString(fmt.Sprintf("Poll #%d: interval=%v, elapsed=%v\n", pollAttempt, currentInterval, time.Since(state.StartedAt))) - shouldStop, stopResult := t.checkIdleConditions(agentURL, taskID, strategy, currentInterval, deadline, pollAttempt, state, pollingDetails.String()) - if shouldStop { - if stopResult != nil && state.ResultChan != nil { - state.ResultChan <- stopResult - time.Sleep(100 * time.Millisecond) - } - t.stopPolling(taskID) - return - } - state.LastPollAt = time.Now() currentTask, err := t.queryTask(ctx, adkClient, taskID) @@ -378,28 +361,7 @@ func (t *A2ASubmitTaskTool) getOrCreateClient(agentURL string) client.A2AClient return client.NewClient(agentURL) } -func (t *A2ASubmitTaskTool) handleImmediateIdle(agentURL, taskID string, state *domain.TaskPollingState) { - idleTimeout := time.Duration(t.config.A2A.Task.IdleTimeoutSec) * time.Second - result := &domain.ToolExecutionResult{ - ToolName: "A2A_SubmitTask", - Success: true, - Duration: time.Since(state.StartedAt), - Data: A2ASubmitTaskResult{ - TaskID: taskID, - AgentURL: agentURL, - State: string(adk.TaskStateWorking), - Success: true, - Message: "Task delegated and went idle immediately", - WentIdle: true, - IdleTimeout: idleTimeout, - }, - } - if state.ResultChan != nil { - state.ResultChan <- result - } -} - -func (t *A2ASubmitTaskTool) initializePollingStrategy(agentURL, taskID, strategy string) (time.Duration, time.Time) { +func (t *A2ASubmitTaskTool) initializePollingStrategy(agentURL, taskID, strategy string) time.Duration { var currentInterval time.Duration if strategy == "exponential" { @@ -408,53 +370,7 @@ func (t *A2ASubmitTaskTool) initializePollingStrategy(agentURL, taskID, strategy currentInterval = time.Duration(t.config.A2A.Task.StatusPollSeconds) * time.Second } - idleTimeout := time.Duration(t.config.A2A.Task.IdleTimeoutSec) * time.Second - deadline := time.Now().Add(idleTimeout) - - return currentInterval, deadline -} - -func (t *A2ASubmitTaskTool) checkIdleConditions(agentURL, taskID, strategy string, currentInterval time.Duration, deadline time.Time, pollAttempt int, state *domain.TaskPollingState, pollingDetails string) (bool, *domain.ToolExecutionResult) { - idleTimeout := time.Duration(t.config.A2A.Task.IdleTimeoutSec) * time.Second - - if strategy == "exponential" { - maxInterval := time.Duration(t.config.A2A.Task.MaxPollIntervalSec) * time.Second - if currentInterval >= maxInterval { - result := &domain.ToolExecutionResult{ - ToolName: "A2A_SubmitTask", - Success: true, - Duration: time.Since(state.StartedAt), - Data: A2ASubmitTaskResult{ - TaskID: taskID, - AgentURL: agentURL, - State: string(adk.TaskStateWorking), - Success: true, - Message: fmt.Sprintf("Task went idle after reaching max poll interval of %v", maxInterval), - WentIdle: true, - IdleTimeout: idleTimeout, - }, - } - return true, result - } - } else if time.Now().After(deadline) { - result := &domain.ToolExecutionResult{ - ToolName: "A2A_SubmitTask", - Success: true, - Duration: time.Since(state.StartedAt), - Data: A2ASubmitTaskResult{ - TaskID: taskID, - AgentURL: agentURL, - State: string(adk.TaskStateWorking), - Success: true, - Message: fmt.Sprintf("Task went idle after %v", idleTimeout), - WentIdle: true, - IdleTimeout: idleTimeout, - }, - } - return true, result - } - - return false, nil + return currentInterval } func (t *A2ASubmitTaskTool) queryTask(ctx context.Context, adkClient client.A2AClient, taskID string) (*adk.Task, error) { @@ -690,10 +606,6 @@ func (t *A2ASubmitTaskTool) FormatPreview(result *domain.ToolExecutionResult) st preview = data.Message } - if data.WentIdle { - return fmt.Sprintf("%s (went idle)", preview) - } - return preview } diff --git a/internal/services/tools/a2a_task_error_handling_test.go b/internal/services/tools/a2a_task_error_handling_test.go index 382edde..eb71d75 100644 --- a/internal/services/tools/a2a_task_error_handling_test.go +++ b/internal/services/tools/a2a_task_error_handling_test.go @@ -342,7 +342,6 @@ func TestA2ASubmitTaskTool_MultipleAgents(t *testing.T) { Enabled: true, Task: config.A2ATaskConfig{ StatusPollSeconds: 1, - IdleTimeoutSec: 5, }, Tools: config.A2AToolsConfig{ SubmitTask: config.SubmitTaskToolConfig{ @@ -427,7 +426,6 @@ func TestA2ASubmitTaskTool_NoExistingTask(t *testing.T) { Enabled: true, Task: config.A2ATaskConfig{ StatusPollSeconds: 1, - IdleTimeoutSec: 5, }, Tools: config.A2AToolsConfig{ SubmitTask: config.SubmitTaskToolConfig{ diff --git a/internal/ui/components/tool_call_renderer.go b/internal/ui/components/tool_call_renderer.go index c8147e4..0799cb9 100644 --- a/internal/ui/components/tool_call_renderer.go +++ b/internal/ui/components/tool_call_renderer.go @@ -295,9 +295,6 @@ func (r *ToolCallRenderer) renderToolCallContent(toolInfo ToolInfo, arguments, s case "executed", "completed", "complete": statusIcon = icons.CheckMark statusText = status - case "idle": - statusIcon = icons.CheckMark - statusText = "delegated" case "error", "failed": statusIcon = icons.CrossMark statusText = status