Backup #405
| ID | 405 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Infrastructure/AI/AnthropicClient.php |
| Version | 2 |
| Typ |
modified |
| Größe | 4.7 KB |
| Hash | 3e7c99b79a2afb77577e3302a767425eee98884afc0b3ce8a0c60f7432df6fe8 |
| Datum | 2025-12-22 08:54:17 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
namespace Infrastructure\AI;
class AnthropicClient implements AIClientInterface
{
private string $apiKey;
private string $model;
private string $baseUrl;
private int $timeout;
private const PRICING = [
'claude-sonnet-4-20250514' => ['input' => 3.0, 'output' => 15.0],
'claude-opus-4-20250514' => ['input' => 15.0, 'output' => 75.0],
'claude-haiku-3-20250514' => ['input' => 0.25, 'output' => 1.25],
];
public function __construct(
string $apiKey = '',
string $model = 'claude-sonnet-4-20250514',
int $timeout = 120
) {
$this->apiKey = $apiKey !== '' ? $apiKey : $this->loadApiKey();
$this->model = $model;
$this->baseUrl = 'https://api.anthropic.com/v1';
$this->timeout = $timeout;
}
private function loadApiKey(): string
{
if (defined('ANTHROPIC_API_KEY')) {
return ANTHROPIC_API_KEY;
}
return \Infrastructure\Config\CredentialService::getAnthropicApiKey();
}
public function execute(string $prompt, array $options = []): AIResponse
{
if ($this->apiKey === '') {
return AIResponse::error('Anthropic API Key not configured', $this->model);
}
$model = $options['model'] ?? $this->model;
$startTime = microtime(true);
try {
$ch = curl_init($this->baseUrl . '/messages');
$messages = [
['role' => 'user', 'content' => $prompt],
];
$payload = [
'model' => $model,
'max_tokens' => $options['max_tokens'] ?? 4096,
'messages' => $messages,
];
if (isset($options['system'])) {
$payload['system'] = $options['system'];
}
if (isset($options['temperature'])) {
$payload['temperature'] = $options['temperature'];
}
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'x-api-key: ' . $this->apiKey,
'anthropic-version: 2023-06-01',
],
CURLOPT_TIMEOUT => $this->timeout,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
$durationMs = (int) ((microtime(true) - $startTime) * 1000);
if ($error !== '') {
return AIResponse::error("cURL Error: {$error}", $model);
}
$data = json_decode($response, true);
if ($httpCode !== 200) {
$errorMsg = $data['error']['message'] ?? "HTTP Error: {$httpCode}";
return AIResponse::error($errorMsg, $model);
}
if (!isset($data['content'][0]['text'])) {
return AIResponse::error('Invalid response format', $model);
}
$tokensInput = $data['usage']['input_tokens'] ?? null;
$tokensOutput = $data['usage']['output_tokens'] ?? null;
$cost = $this->calculateCost($model, $tokensInput, $tokensOutput);
return AIResponse::success(
$data['content'][0]['text'],
$tokensInput,
$tokensOutput,
$durationMs,
$model,
[
'stop_reason' => $data['stop_reason'] ?? null,
'cost_usd' => $cost,
]
);
} catch (\Exception $e) {
return AIResponse::error($e->getMessage(), $model);
}
}
public function isAvailable(): bool
{
return $this->apiKey !== '';
}
public function getClientName(): string
{
return 'anthropic_api';
}
public function getModelName(): string
{
return $this->model;
}
private function calculateCost(string $model, ?int $inputTokens, ?int $outputTokens): ?float
{
if ($inputTokens === null || $outputTokens === null) {
return null;
}
$pricing = self::PRICING[$model] ?? self::PRICING['claude-sonnet-4-20250514'];
$inputCost = ($inputTokens / 1_000_000) * $pricing['input'];
$outputCost = ($outputTokens / 1_000_000) * $pricing['output'];
return round($inputCost + $outputCost, 6);
}
public function setModel(string $model): self
{
$this->model = $model;
return $this;
}
public static function getAvailableModels(): array
{
return array_keys(self::PRICING);
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 1861 |
5 |
modified |
4.9 KB |
2025-12-27 23:48 |
| 1857 |
4 |
modified |
4.9 KB |
2025-12-27 23:47 |
| 756 |
3 |
modified |
4.8 KB |
2025-12-23 08:00 |
| 405 |
2 |
modified |
4.7 KB |
2025-12-22 08:54 |
| 43 |
1 |
modified |
5.0 KB |
2025-12-20 17:24 |
← Zurück zur Übersicht