Files

1 line
4.1 KiB
JSON

{"repo": "candy2004/miniclaw", "files": {"src/main/java/com/example/miniclaw/llm/DeepSeekProvider.java": {"833bfadb9503fe814113b7bbcd74dc80b7a0a9ba": {"t": 1785745662.7106934, "n": 3797, "h": "8174fb4c9801ddd1", "c": "package com.example.miniclaw.llm;\n\nimport java.io.IOException;\nimport java.net.URI;\nimport java.net.http.HttpClient;\nimport java.net.http.HttpRequest;\nimport java.net.http.HttpResponse;\nimport java.nio.charset.StandardCharsets;\nimport java.time.Duration;\n\nimport com.example.miniclaw.model.LlmRequest;\nimport com.example.miniclaw.model.LlmResponse;\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.node.ArrayNode;\nimport com.fasterxml.jackson.databind.node.ObjectNode;\n\npublic class DeepSeekProvider implements LlmProvider {\n private static final String DEFAULT_ENDPOINT = \"https://api.deepseek.com/chat/completions\";\n private static final String DEFAULT_MODEL = \"deepseek-chat\";\n\n private final HttpClient httpClient = HttpClient.newBuilder()\n .connectTimeout(Duration.ofSeconds(10))\n .build();\n private final ObjectMapper objectMapper = new ObjectMapper();\n\n @Override\n public String name() {\n return \"deepseek\";\n }\n\n @Override\n public LlmResponse chat(LlmRequest request) {\n String apiKey = System.getenv(\"DEEPSEEK_API_KEY\");\n if (apiKey == null || apiKey.trim().isEmpty()) {\n return new LlmResponse(name(), \"DeepSeek API key is missing. Please set DEEPSEEK_API_KEY.\");\n }\n\n try {\n ObjectNode payload = objectMapper.createObjectNode();\n payload.put(\"model\", envOrDefault(\"DEEPSEEK_MODEL\", DEFAULT_MODEL));\n ArrayNode messages = payload.putArray(\"messages\");\n messages.add(message(\"system\", \"You are MiniClaw's core LLM. Answer concisely in English.\"));\n messages.add(message(\"user\", request.getMessage()));\n payload.put(\"temperature\", 0.2);\n\n HttpRequest httpRequest = HttpRequest.newBuilder()\n .uri(URI.create(envOrDefault(\"DEEPSEEK_ENDPOINT\", DEFAULT_ENDPOINT)))\n .timeout(Duration.ofSeconds(30))\n .header(\"Content-Type\", \"application/json\")\n .header(\"Authorization\", \"Bearer \" + apiKey)\n .POST(HttpRequest.BodyPublishers.ofString(objectMapper.writeValueAsString(payload),\n StandardCharsets.UTF_8))\n .build();\n\n HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());\n if (response.statusCode() < 200 || response.statusCode() >= 300) {\n return new LlmResponse(name(), \"DeepSeek call failed, HTTP \" + response.statusCode() + \": \"\n + response.body());\n }\n\n JsonNode root = objectMapper.readTree(response.body());\n String content = root.path(\"choices\").path(0).path(\"message\").path(\"content\").asText();\n if (content == null || content.trim().isEmpty()) {\n content = \"DeepSeek returned an empty response: \" + response.body();\n }\n return new LlmResponse(name(), content);\n } catch (IOException e) {\n return new LlmResponse(name(), \"DeepSeek IO error: \" + e.getMessage());\n } catch (InterruptedException e) {\n Thread.currentThread().interrupt();\n return new LlmResponse(name(), \"DeepSeek call interrupted: \" + e.getMessage());\n }\n }\n\n private ObjectNode message(String role, String content) {\n ObjectNode message = objectMapper.createObjectNode();\n message.put(\"role\", role);\n message.put(\"content\", content);\n return message;\n }\n\n private String envOrDefault(String key, String fallback) {\n String value = System.getenv(key);\n return value == null || value.trim().isEmpty() ? fallback : value;\n }\n}\n"}}}}