|
11 | 11 | public class ClaudeService {
|
12 | 12 |
|
13 | 13 | @Value("${anthropic.api.key}")
|
14 |
| - private String apiKey; |
| 14 | + private String anthropicApiKey; |
| 15 | + |
| 16 | + private final RestTemplate restTemplate = new RestTemplate(); |
| 17 | + |
| 18 | + public String reply(String type, Map<String, Object> input) { |
| 19 | + try { |
| 20 | + String name = input.getOrDefault("name", "inconnu").toString(); |
| 21 | + String rawStyle = input.getOrDefault("style", "neutral").toString(); |
| 22 | + String rawLength = input.getOrDefault("length", "medium").toString(); |
| 23 | + |
| 24 | + String style = styleMap.getOrDefault(rawStyle, styleMap.get("neutral")); |
| 25 | + String length = lengthMap.getOrDefault(rawLength, lengthMap.get("medium")); |
| 26 | + |
| 27 | + String prompt; |
| 28 | + if ("summary".equals(type)) { |
| 29 | + prompt = String.format("Fais un résumé du film \"%s\" avec un style %s, %s.", name, style, length); |
| 30 | + } else { |
| 31 | + prompt = String.format("Écris une biographie de %s avec un style %s, %s.", name, style, length); |
| 32 | + } |
| 33 | + |
| 34 | + HttpHeaders headers = new HttpHeaders(); |
| 35 | + headers.setContentType(MediaType.APPLICATION_JSON); |
| 36 | + headers.set("x-api-key", anthropicApiKey); |
| 37 | + headers.set("anthropic-version", "2023-06-01"); |
| 38 | + |
| 39 | + String body = """ |
| 40 | + { |
| 41 | + "model": "claude-3-5-sonnet-20240620", |
| 42 | + "max_tokens": 1000, |
| 43 | + "messages": [ |
| 44 | + { "role": "user", "content": "%s" } |
| 45 | + ] |
| 46 | + } |
| 47 | + """.formatted(prompt.replace("\"", "\\\"")); |
| 48 | + |
| 49 | + HttpEntity<String> request = new HttpEntity<>(body, headers); |
| 50 | + |
| 51 | + ResponseEntity<Map> response = restTemplate.postForEntity( |
| 52 | + "https://api.anthropic.com/v1/messages", |
| 53 | + request, |
| 54 | + Map.class |
| 55 | + ); |
| 56 | + |
| 57 | + if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) { |
| 58 | + Object content = ((Map<?, ?>) ((java.util.List<?>) response.getBody().get("content")).get(0)).get("text"); |
| 59 | + return content != null ? content.toString().trim() : "Réponse vide de Claude."; |
| 60 | + } else { |
| 61 | + return "Erreur Claude (" + response.getStatusCode().value() + ") : " + response.getBody(); |
| 62 | + } |
| 63 | + |
| 64 | + } catch (Exception e) { |
| 65 | + System.err.println("❌ ClaudeService error: " + e.getMessage()); |
| 66 | + return "Erreur lors de l’appel à l’API Claude."; |
| 67 | + } |
| 68 | + } |
15 | 69 |
|
16 | 70 | private static final Map<String, String> styleMap = Map.ofEntries(
|
17 | 71 | Map.entry("neutral", "neutre, objectif, informatif sans émotion"),
|
@@ -39,50 +93,95 @@ public class ClaudeService {
|
39 | 93 | "medium", "environ 60 mots, réponse équilibrée",
|
40 | 94 | "long", "environ 100 mots, réponse développée mais synthétique"
|
41 | 95 | );
|
| 96 | +} |
42 | 97 |
|
43 |
| - public String reply(String type, Map<String, Object> input) { |
44 |
| - try { |
45 |
| - String name = (String) input.getOrDefault("name", "inconnu"); |
46 |
| - String rawStyle = (String) input.getOrDefault("style", "neutral"); |
47 |
| - String rawLength = (String) input.getOrDefault("length", "medium"); |
48 |
| - |
49 |
| - String style = styleMap.getOrDefault(rawStyle, styleMap.get("neutral")); |
50 |
| - String length = lengthMap.getOrDefault(rawLength, lengthMap.get("medium")); |
51 |
| - |
52 |
| - String prompt = type.equals("summary") |
53 |
| - ? String.format("Fais un résumé du film \"%s\" avec un style %s, %s.", name, style, length) |
54 |
| - : String.format("Écris une biographie de %s avec un style %s, %s.", name, style, length); |
55 |
| - |
56 |
| - RestTemplate restTemplate = new RestTemplate(); |
57 |
| - |
58 |
| - HttpHeaders headers = new HttpHeaders(); |
59 |
| - headers.setContentType(MediaType.APPLICATION_JSON); |
60 |
| - headers.set("x-api-key", apiKey); |
61 |
| - headers.set("anthropic-version", "2023-06-01"); |
62 |
| - |
63 |
| - String body = String.format( |
64 |
| - """ |
65 |
| - { |
66 |
| - "model": "claude-3-5-sonnet-20240620", |
67 |
| - "max_tokens": 1000, |
68 |
| - "messages": [{ "role": "user", "content": "%s" }] |
69 |
| - } |
70 |
| - """, |
71 |
| - prompt.replace("\"", "\\\"") |
72 |
| - ); |
73 |
| - |
74 |
| - HttpEntity<String> entity = new HttpEntity<>(body, headers); |
75 |
| - ResponseEntity<Map> response = restTemplate.postForEntity("https://api.anthropic.com/v1/messages", entity, Map.class); |
76 | 98 |
|
77 |
| - if (response.getStatusCode() == HttpStatus.OK) { |
78 |
| - Object content = ((Map<?, ?>) ((java.util.List<?>) response.getBody().get("content")).get(0)).get("text"); |
79 |
| - return content != null ? content.toString().trim() : "Réponse vide de Claude."; |
80 |
| - } else { |
81 |
| - return "Erreur Claude (" + response.getStatusCodeValue() + ") : " + response.getBody(); |
82 |
| - } |
83 | 99 |
|
84 |
| - } catch (Exception e) { |
85 |
| - return "Erreur Claude : " + e.getMessage(); |
86 |
| - } |
87 |
| - } |
88 |
| -} |
| 100 | +//package com.angular.ai.service.llm; |
| 101 | +// |
| 102 | +//import org.springframework.beans.factory.annotation.Value; |
| 103 | +//import org.springframework.http.*; |
| 104 | +//import org.springframework.stereotype.Service; |
| 105 | +//import org.springframework.web.client.RestTemplate; |
| 106 | +// |
| 107 | +//import java.util.Map; |
| 108 | +// |
| 109 | +//@Service |
| 110 | +//public class ClaudeService { |
| 111 | +// |
| 112 | +// @Value("${anthropic.api.key}") |
| 113 | +// private String apiKey; |
| 114 | +// |
| 115 | +// private static final Map<String, String> styleMap = Map.ofEntries( |
| 116 | +// Map.entry("neutral", "neutre, objectif, informatif sans émotion"), |
| 117 | +// Map.entry("casual", "décontracté, langage simple et familier"), |
| 118 | +// Map.entry("technical", "axé sur les faits techniques et professionnels"), |
| 119 | +// Map.entry("narrative", "raconté comme une histoire avec du rythme"), |
| 120 | +// Map.entry("press", "journalistique, structuré comme un article de presse"), |
| 121 | +// Map.entry("humorous", "humoristique, ton léger et amusant"), |
| 122 | +// Map.entry("poetic", "poétique, style littéraire et imagé"), |
| 123 | +// Map.entry("dramatic", "dramatique, avec tension et intensité émotionnelle"), |
| 124 | +// Map.entry("emotional", "émotionnel, centré sur les sentiments et l’empathie"), |
| 125 | +// Map.entry("cinematic", "cinématographique, ambiance visuelle et descriptive comme un film"), |
| 126 | +// Map.entry("historical", "historique, avec mise en contexte chronologique"), |
| 127 | +// Map.entry("marketing", "marketing, valorisant avec un ton accrocheur"), |
| 128 | +// Map.entry("scientific", "scientifique, ton analytique et factuel"), |
| 129 | +// Map.entry("satirical", "satirique, critique subtile et ironique"), |
| 130 | +// Map.entry("inspirational", "inspirant, motivant avec des citations et une mise en valeur"), |
| 131 | +// Map.entry("minimal", "très court, phrases simples et dépouillées"), |
| 132 | +// Map.entry("dialog", "rédigé sous forme de dialogue entre deux personnes"), |
| 133 | +// Map.entry("interview", "présenté comme une interview fictive, questions-réponses") |
| 134 | +// ); |
| 135 | +// |
| 136 | +// private static final Map<String, String> lengthMap = Map.of( |
| 137 | +// "short", "environ 30 mots, réponse très concise", |
| 138 | +// "medium", "environ 60 mots, réponse équilibrée", |
| 139 | +// "long", "environ 100 mots, réponse développée mais synthétique" |
| 140 | +// ); |
| 141 | +// |
| 142 | +// public String reply(String type, Map<String, Object> input) { |
| 143 | +// try { |
| 144 | +// String name = (String) input.getOrDefault("name", "inconnu"); |
| 145 | +// String rawStyle = (String) input.getOrDefault("style", "neutral"); |
| 146 | +// String rawLength = (String) input.getOrDefault("length", "medium"); |
| 147 | +// |
| 148 | +// String style = styleMap.getOrDefault(rawStyle, styleMap.get("neutral")); |
| 149 | +// String length = lengthMap.getOrDefault(rawLength, lengthMap.get("medium")); |
| 150 | +// |
| 151 | +// String prompt = type.equals("summary") |
| 152 | +// ? String.format("Fais un résumé du film \"%s\" avec un style %s, %s.", name, style, length) |
| 153 | +// : String.format("Écris une biographie de %s avec un style %s, %s.", name, style, length); |
| 154 | +// |
| 155 | +// RestTemplate restTemplate = new RestTemplate(); |
| 156 | +// |
| 157 | +// HttpHeaders headers = new HttpHeaders(); |
| 158 | +// headers.setContentType(MediaType.APPLICATION_JSON); |
| 159 | +// headers.set("x-api-key", apiKey); |
| 160 | +// headers.set("anthropic-version", "2023-06-01"); |
| 161 | +// |
| 162 | +// String body = String.format( |
| 163 | +// """ |
| 164 | +// { |
| 165 | +// "model": "claude-3-5-sonnet-20240620", |
| 166 | +// "max_tokens": 1000, |
| 167 | +// "messages": [{ "role": "user", "content": "%s" }] |
| 168 | +// } |
| 169 | +// """, |
| 170 | +// prompt.replace("\"", "\\\"") |
| 171 | +// ); |
| 172 | +// |
| 173 | +// HttpEntity<String> entity = new HttpEntity<>(body, headers); |
| 174 | +// ResponseEntity<Map> response = restTemplate.postForEntity("https://api.anthropic.com/v1/messages", entity, Map.class); |
| 175 | +// |
| 176 | +// if (response.getStatusCode() == HttpStatus.OK) { |
| 177 | +// Object content = ((Map<?, ?>) ((java.util.List<?>) response.getBody().get("content")).get(0)).get("text"); |
| 178 | +// return content != null ? content.toString().trim() : "Réponse vide de Claude."; |
| 179 | +// } else { |
| 180 | +// return "Erreur Claude (" + response.getStatusCodeValue() + ") : " + response.getBody(); |
| 181 | +// } |
| 182 | +// |
| 183 | +// } catch (Exception e) { |
| 184 | +// return "Erreur Claude : " + e.getMessage(); |
| 185 | +// } |
| 186 | +// } |
| 187 | +//} |
0 commit comments