(t *testing.T)
| 2141 | } |
| 2142 | |
| 2143 | func TestToolRejectionWithReason(t *testing.T) { |
| 2144 | t.Parallel() |
| 2145 | |
| 2146 | // Test that rejection reasons are included in the tool error response |
| 2147 | agentTools := []tools.Tool{{ |
| 2148 | Name: "shell", |
| 2149 | Parameters: map[string]any{}, |
| 2150 | Handler: func(_ context.Context, _ tools.ToolCall) (*tools.ToolCallResult, error) { |
| 2151 | t.Fatal("tool should not be executed when rejected") |
| 2152 | return nil, nil |
| 2153 | }, |
| 2154 | }} |
| 2155 | |
| 2156 | prov := &mockProvider{id: "test/mock-model", stream: &mockStream{}} |
| 2157 | root := agent.New("root", "You are a test agent", |
| 2158 | agent.WithModel(prov), |
| 2159 | agent.WithToolSets(newStubToolSet(nil, agentTools, nil)), |
| 2160 | ) |
| 2161 | tm := team.New(team.WithAgents(root)) |
| 2162 | |
| 2163 | rt, err := NewLocalRuntime(t.Context(), tm, WithSessionCompaction(false), WithModelStore(mockModelStore{})) |
| 2164 | require.NoError(t, err) |
| 2165 | |
| 2166 | sess := session.New(session.WithUserMessage("Test")) |
| 2167 | require.False(t, sess.ToolsApproved) // No --yolo |
| 2168 | |
| 2169 | calls := []tools.ToolCall{{ |
| 2170 | ID: "call_1", |
| 2171 | Type: "function", |
| 2172 | Function: tools.FunctionCall{Name: "shell", Arguments: "{}"}, |
| 2173 | }} |
| 2174 | |
| 2175 | events := make(chan Event, 10) |
| 2176 | |
| 2177 | // Run in goroutine since it will block waiting for confirmation |
| 2178 | go func() { |
| 2179 | rt.processToolCalls(t.Context(), sess, calls, agentTools, NewChannelSink(events)) |
| 2180 | close(events) |
| 2181 | }() |
| 2182 | |
| 2183 | // Wait for confirmation request and then reject with a reason |
| 2184 | var toolResponse *ToolCallResponseEvent |
| 2185 | for ev := range events { |
| 2186 | if _, ok := ev.(*ToolCallConfirmationEvent); ok { |
| 2187 | // Send rejection with a specific reason |
| 2188 | rt.resumeChan <- ResumeReject("The arguments provided are incorrect.") |
| 2189 | } |
| 2190 | if resp, ok := ev.(*ToolCallResponseEvent); ok { |
| 2191 | toolResponse = resp |
| 2192 | } |
| 2193 | } |
| 2194 | |
| 2195 | require.NotNil(t, toolResponse, "expected a tool response event") |
| 2196 | require.True(t, toolResponse.Result.IsError, "expected tool result to be an error") |
| 2197 | require.Contains(t, toolResponse.Response, "The user rejected the tool call.") |
| 2198 | require.Contains(t, toolResponse.Response, "Reason: The arguments provided are incorrect.") |
| 2199 | } |
| 2200 |
nothing calls this directly
no test coverage detected