mirror of
https://github.com/danielmiessler/fabric.git
synced 2026-09-10 07:36:44 -04:00
fix: Address copilot review comments
This commit is contained in:
parent
283a548e05
commit
103493206e
|
|
@ -173,7 +173,7 @@ fabric --youtube "https://youtube.com/watch?v=example" --model us.anthropic.clau
|
|||
curl -s https://example.com/article | fabric --model gpt-4o --pattern summarize
|
||||
|
||||
# Create content from a prompt (Vertex AI)
|
||||
fabric --model gemini-1.5-pro --pattern write_essay --stream
|
||||
fabric --model gemini-1.5-pro --pattern write_essay
|
||||
```
|
||||
|
||||
### Switching Between Backends
|
||||
|
|
@ -327,10 +327,10 @@ Fabric configuration is stored in `~/.config/fabric/.env`. Manual editing is sup
|
|||
|
||||
```bash
|
||||
# Example configuration
|
||||
AZURE_AI_GATEWAY_BACKEND=bedrock
|
||||
AZURE_AI_GATEWAY_GATEWAY_URL=https://gateway.company.com
|
||||
AZURE_AI_GATEWAY_SUBSCRIPTION_KEY=your-key-here
|
||||
AZURE_AI_GATEWAY_API_VERSION=2025-04-01-preview
|
||||
AZUREAIGATEWAY_BACKEND=bedrock
|
||||
AZUREAIGATEWAY_GATEWAY_URL=https://gateway.company.com
|
||||
AZUREAIGATEWAY_SUBSCRIPTION_KEY=your-key-here
|
||||
AZUREAIGATEWAY_API_VERSION=2025-04-01-preview
|
||||
```
|
||||
|
||||
## Support
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "ungültige Gateway-URL: %w",
|
||||
"azureaigateway_no_valid_messages": "keine gültigen Nachrichten nach Filterung leerer Inhalte",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: Antwort zu groß (>%d Bytes)",
|
||||
"azureaigateway_subscription_key_question": "Geben Sie Ihren Azure APIM-Abonnementschlüssel ein",
|
||||
"azureaigateway_subscription_key_required": "Azure APIM-Abonnementschlüssel ist erforderlich",
|
||||
"azureaigateway_unsupported_backend": "nicht unterstütztes Backend: %s (gültige Optionen: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "invalid gateway URL: %w",
|
||||
"azureaigateway_no_valid_messages": "no valid messages after filtering empty content",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: response too large (>%d bytes)",
|
||||
"azureaigateway_subscription_key_question": "Enter your Azure APIM subscription key",
|
||||
"azureaigateway_subscription_key_required": "azure APIM subscription key is required",
|
||||
"azureaigateway_unsupported_backend": "unsupported backend: %s (valid options: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "URL de gateway inválida: %w",
|
||||
"azureaigateway_no_valid_messages": "sin mensajes válidos después de filtrar contenido vacío",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: respuesta demasiado grande (>%d bytes)",
|
||||
"azureaigateway_subscription_key_question": "Ingrese su clave de suscripción de Azure APIM",
|
||||
"azureaigateway_subscription_key_required": "se requiere la clave de suscripción de Azure APIM",
|
||||
"azureaigateway_unsupported_backend": "backend no soportado: %s (opciones válidas: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "آدرس Gateway نامعتبر: %w",
|
||||
"azureaigateway_no_valid_messages": "هیچ پیام معتبری پس از فیلتر کردن محتوای خالی وجود ندارد",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: پاسخ خیلی بزرگ است (>%d بایت)",
|
||||
"azureaigateway_subscription_key_question": "کلید اشتراک Azure APIM خود را وارد کنید",
|
||||
"azureaigateway_subscription_key_required": "کلید اشتراک Azure APIM الزامی است",
|
||||
"azureaigateway_unsupported_backend": "بکاند پشتیبانی نشده: %s (گزینههای معتبر: bedrock، azure-openai، vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "URL du gateway invalide : %w",
|
||||
"azureaigateway_no_valid_messages": "aucun message valide après filtrage du contenu vide",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway : %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway : réponse trop volumineuse (>%d octets)",
|
||||
"azureaigateway_subscription_key_question": "Entrez votre clé d'abonnement Azure APIM",
|
||||
"azureaigateway_subscription_key_required": "la clé d'abonnement Azure APIM est requise",
|
||||
"azureaigateway_unsupported_backend": "backend non pris en charge : %s (options valides : bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "URL del gateway non valido: %w",
|
||||
"azureaigateway_no_valid_messages": "nessun messaggio valido dopo il filtraggio del contenuto vuoto",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: risposta troppo grande (>%d byte)",
|
||||
"azureaigateway_subscription_key_question": "Inserire la propria chiave di sottoscrizione Azure APIM",
|
||||
"azureaigateway_subscription_key_required": "la chiave di sottoscrizione Azure APIM è obbligatoria",
|
||||
"azureaigateway_unsupported_backend": "backend non supportato: %s (opzioni valide: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "無効なゲートウェイURL: %w",
|
||||
"azureaigateway_no_valid_messages": "空のコンテンツをフィルタリングした後、有効なメッセージがありません",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: レスポンスが大きすぎます (>%dバイト)",
|
||||
"azureaigateway_subscription_key_question": "Azure APIMサブスクリプションキーを入力してください",
|
||||
"azureaigateway_subscription_key_required": "Azure APIMサブスクリプションキーは必須です",
|
||||
"azureaigateway_unsupported_backend": "サポートされていないバックエンド: %s(有効なオプション: bedrock、azure-openai、vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "URL do gateway inválida: %w",
|
||||
"azureaigateway_no_valid_messages": "sem mensagens válidas após filtrar conteúdo vazio",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: resposta muito grande (>%d bytes)",
|
||||
"azureaigateway_subscription_key_question": "Insira sua chave de assinatura do Azure APIM",
|
||||
"azureaigateway_subscription_key_required": "a chave de assinatura do Azure APIM é obrigatória",
|
||||
"azureaigateway_unsupported_backend": "backend não suportado: %s (opções válidas: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "URL do gateway inválido: %w",
|
||||
"azureaigateway_no_valid_messages": "sem mensagens válidas após filtragem de conteúdo vazio",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: resposta demasiado grande (>%d bytes)",
|
||||
"azureaigateway_subscription_key_question": "Introduza a sua chave de subscrição do Azure APIM",
|
||||
"azureaigateway_subscription_key_required": "a chave de subscrição do Azure APIM é obrigatória",
|
||||
"azureaigateway_unsupported_backend": "backend não suportado: %s (opções válidas: bedrock, azure-openai, vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
"azureaigateway_invalid_gateway_url": "无效的网关 URL: %w",
|
||||
"azureaigateway_no_valid_messages": "过滤空内容后没有有效消息",
|
||||
"azureaigateway_prepare_request_failed": "AzureAIGateway: %w",
|
||||
"azureaigateway_response_too_large": "AzureAIGateway: 响应太大 (>%d字节)",
|
||||
"azureaigateway_subscription_key_question": "输入您的 Azure APIM 订阅密钥",
|
||||
"azureaigateway_subscription_key_required": "Azure APIM 订阅密钥是必需的",
|
||||
"azureaigateway_unsupported_backend": "不支持的后端: %s(有效选项: bedrock、azure-openai、vertex-ai)",
|
||||
|
|
|
|||
|
|
@ -169,12 +169,16 @@ func (c *Client) Send(ctx context.Context, msgs []*chat.ChatCompletionMessage, o
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Limit response body size to 10MB to prevent memory exhaustion
|
||||
limitedBody := io.LimitReader(resp.Body, 10*1024*1024)
|
||||
// Read up to 10MB+1 byte to detect truncation
|
||||
const maxResponseSize = 10 * 1024 * 1024
|
||||
limitedBody := io.LimitReader(resp.Body, maxResponseSize+1)
|
||||
respBody, err := io.ReadAll(limitedBody)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(i18n.T("azureaigateway_failed_read_response"), err)
|
||||
}
|
||||
if len(respBody) > maxResponseSize {
|
||||
return "", fmt.Errorf(i18n.T("azureaigateway_response_too_large"), maxResponseSize)
|
||||
}
|
||||
|
||||
debuglog.Debug(debuglog.Detailed, "AzureAIGateway response status: %d\n", resp.StatusCode)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,16 +3,29 @@ package azureaigateway
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/danielmiessler/fabric/internal/chat"
|
||||
"github.com/danielmiessler/fabric/internal/domain"
|
||||
"github.com/danielmiessler/fabric/internal/i18n"
|
||||
)
|
||||
|
||||
// TestMain pins the locale to English so that i18n.T() assertions
|
||||
// are deterministic regardless of the CI machine's system locale.
|
||||
func TestMain(m *testing.M) {
|
||||
if _, err := i18n.Init("en"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to init i18n: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
// --- Bedrock Backend Tests ---
|
||||
|
||||
func TestBedrockBuildEndpoint(t *testing.T) {
|
||||
|
|
@ -732,13 +745,20 @@ func TestSendModelNotFoundError(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// failingRoundTripper always returns an error, simulating a network failure.
|
||||
type failingRoundTripper struct{}
|
||||
|
||||
func (f *failingRoundTripper) RoundTrip(*http.Request) (*http.Response, error) {
|
||||
return nil, fmt.Errorf("connection refused")
|
||||
}
|
||||
|
||||
func TestSendNetworkError(t *testing.T) {
|
||||
// ISC-C17: Test unreachable gateway URL → connection error
|
||||
// ISC-C17: Test network failure → connection error (deterministic, no real DNS)
|
||||
c := NewClient()
|
||||
c.GatewayURL.Value = "https://non-existent-gateway-12345.invalid"
|
||||
c.GatewayURL.Value = "https://gateway.example.com"
|
||||
c.SubscriptionKey.Value = "test-key"
|
||||
c.BackendType.Value = "bedrock"
|
||||
c.httpClient = &http.Client{Timeout: gatewayTimeout}
|
||||
c.httpClient = &http.Client{Transport: &failingRoundTripper{}}
|
||||
c.backend = NewBedrockBackend("test-key")
|
||||
|
||||
msgs := []*chat.ChatCompletionMessage{
|
||||
|
|
@ -752,7 +772,7 @@ func TestSendNetworkError(t *testing.T) {
|
|||
|
||||
_, err := c.Send(context.Background(), msgs, opts)
|
||||
if err == nil {
|
||||
t.Fatal("Send() expected error for unreachable gateway")
|
||||
t.Fatal("Send() expected error for network failure")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "HTTP request failed") {
|
||||
t.Errorf("error should mention HTTP request failure: %v", err)
|
||||
|
|
@ -903,11 +923,11 @@ func TestSendStreamFallback(t *testing.T) {
|
|||
// --- ISC-C18: API Version Compatibility Test ---
|
||||
|
||||
func TestAzureOpenAIAPIVersionCompatibility(t *testing.T) {
|
||||
// ISC-C18: Azure OpenAI API version 2025-04-01-preview compatibility with Azure APIM Gateway
|
||||
// ISC-C18: Azure OpenAI API version compatibility with Azure APIM Gateway
|
||||
// Reference: https://learn.microsoft.com/en-us/azure/ai-services/openai/api-version-deprecation
|
||||
// This test verifies that the API version in the endpoint is compatible with Azure APIM Gateway.
|
||||
// The version 2024-10-21 is currently used, which is compatible with APIM gateways.
|
||||
// When updating to 2025-04-01-preview, ensure APIM gateway supports the new version.
|
||||
// This test verifies that the default API version in the endpoint (currently 2025-04-01-preview)
|
||||
// is explicitly set and is compatible with Azure APIM Gateway. When changing the default API
|
||||
// version in the backend, ensure that APIM gateways are updated to support the new version.
|
||||
|
||||
b := NewAzureOpenAIBackend("key", "")
|
||||
endpoint := b.BuildEndpoint("https://gw.example.com", "gpt-4")
|
||||
|
|
|
|||
Loading…
Reference in a new issue