diff --git a/backend/internal/llm/openai_skill_live_test.go b/backend/internal/llm/openai_skill_live_test.go index f99db170..803705a2 100644 --- a/backend/internal/llm/openai_skill_live_test.go +++ b/backend/internal/llm/openai_skill_live_test.go @@ -114,7 +114,7 @@ func runLiveSkillProtocol(t *testing.T, provider *OpenAIProvider, model string) return fmt.Errorf("stage=final_answer expected one choice; response=%s", liveResponseSummary(final)) } choice := final.Choices[0] - if choice.FinishReason != "stop" || len(choice.Message.ToolCalls) != 0 || strings.TrimSpace(choice.Message.Content) != liveAnswer { + if choice.FinishReason != "stop" || len(choice.Message.ToolCalls) != 0 || choice.Message.Content != liveAnswer { return fmt.Errorf("stage=final_answer contract mismatch; response=%s", liveResponseSummary(final)) } return nil @@ -159,6 +159,9 @@ func oneLiveToolCall(response *ChatResponse, expected string) (*ToolCall, error) return nil, fmt.Errorf("expected finish_reason=tool_calls and exactly one %s call", expected) } call := &choice.Message.ToolCalls[0] + if call.ID == "" { + return nil, fmt.Errorf("expected non-empty tool call ID") + } if call.Type != "function" || call.Function.Name != expected { return nil, fmt.Errorf("expected tool=%s, got type=%s name=%s", expected, safeToken(call.Type), safeToken(call.Function.Name)) }