• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eliashaeussler / typo3-solver / 13271925856

11 Feb 2025 08:29PM UTC coverage: 81.979% (-6.2%) from 88.153%
13271925856

Pull #295

github

web-flow
Merge 140b2a87d into dc3a40050
Pull Request #295: [FEATURE] Add Gemini as additional solution provider

8 of 90 new or added lines in 7 files covered. (8.89%)

1 existing line in 1 file now uncovered.

878 of 1071 relevant lines covered (81.98%)

2.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.05
/Classes/ProblemSolving/Solution/Model/CompletionResponse.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "solver".
7
 *
8
 * Copyright (C) 2023-2025 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\Typo3Solver\ProblemSolving\Solution\Model;
25

26
use GeminiAPI\Enums;
27
use GeminiAPI\Resources;
28
use OpenAI\Responses;
29

30
/**
31
 * CompletionResponse
32
 *
33
 * @author Elias Häußler <elias@haeussler.dev>
34
 * @license GPL-2.0-or-later
35
 *
36
 * @phpstan-import-type MessageArray from Message
37
 * @phpstan-type CompletionResponseArray array{index: int, message: MessageArray, finishReason: string|null}
38
 */
39
final class CompletionResponse implements \JsonSerializable
40
{
41
    public function __construct(
7✔
42
        public readonly int $index,
43
        public readonly Message $message,
44
        public readonly ?string $finishReason = null,
45
    ) {}
7✔
46

47
    public static function fromOpenAIChoice(
2✔
48
        Responses\Chat\CreateResponseChoice|Responses\Chat\CreateStreamedResponseChoice $choice,
49
    ): self {
50
        if ($choice instanceof Responses\Chat\CreateStreamedResponseChoice) {
2✔
51
            $role = (string)$choice->delta->role;
1✔
52
            $content = $choice->delta->content;
1✔
53
        } else {
54
            $role = $choice->message->role;
1✔
55
            $content = $choice->message->content;
1✔
56
        }
57

58
        return new self($choice->index, new Message($role, $content), $choice->finishReason);
2✔
59
    }
60

NEW
61
    public static function fromGeminiCandidate(Resources\Candidate $candidate): self
×
62
    {
NEW
63
        return new self(
×
NEW
64
            $candidate->index,
×
NEW
65
            new Message(Enums\Role::Model->value, $candidate->content->parts[0]->text),
×
NEW
66
            $candidate->finishReason?->value,
×
NEW
67
        );
×
68
    }
69

70
    /**
71
     * @param array{index?: int, message?: array{role?: string, content?: string|null}, finishReason?: string|null} $response
72
     */
73
    public static function fromArray(array $response): self
1✔
74
    {
75
        $message = $response['message'] ?? [];
1✔
76
        $message['role'] ??= '';
1✔
77
        $message['content'] ??= null;
1✔
78

79
        return new self(
1✔
80
            $response['index'] ?? 0,
1✔
81
            new Message($message['role'], $message['content']),
1✔
82
            $response['finishReason'] ?? null,
1✔
83
        );
1✔
84
    }
85

86
    public function merge(self $other): self
1✔
87
    {
88
        return new self(
1✔
89
            $this->index,
1✔
90
            new Message(
1✔
91
                $other->message->role,
1✔
92
                $this->message->content . $other->message->content,
1✔
93
            ),
1✔
94
            $other->finishReason,
1✔
95
        );
1✔
96
    }
97

98
    public function isFinished(): bool
1✔
99
    {
100
        return $this->finishReason !== null;
1✔
101
    }
102

103
    /**
104
     * @return CompletionResponseArray
105
     */
106
    public function toArray(): array
2✔
107
    {
108
        return [
2✔
109
            'index' => $this->index,
2✔
110
            'message' => $this->message->toArray(),
2✔
111
            'finishReason' => $this->finishReason,
2✔
112
        ];
2✔
113
    }
114

115
    /**
116
     * @return CompletionResponseArray
117
     */
118
    public function jsonSerialize(): array
1✔
119
    {
120
        return $this->toArray();
1✔
121
    }
122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc