- Java 17, Maven, JDK java.net.http.HttpClient, Jackson 2.x - ForgeClient (builder), records for RunResult / FileToken / AppToken / HealthStatus - ApiException / AuthException / TransportException all extend ForgeException (RuntimeException) — checked exceptions feel un-modern in Java 17 - Multipart upload streams from disk via BodyPublishers.ofByteArrays - 14 JUnit 5 tests against in-process com.sun.net.httpserver — zero test deps beyond JUnit - mvn package / mvn test / mvn javadoc:javadoc clean - snake_case wire format mapped to camelCase Java accessors via @JsonProperty
79 lines
3.3 KiB
Java
79 lines
3.3 KiB
Java
// SPDX-License-Identifier: MIT
|
|
//
|
|
// Build & run from clients/java/:
|
|
// mvn -q package
|
|
// javac -cp target/clawdforge-client-0.1.0.jar:$(ls ~/.m2/repository/com/fasterxml/jackson/core/jackson-databind/*/jackson-databind-*.jar | head -1):$(ls ~/.m2/repository/com/fasterxml/jackson/core/jackson-core/*/jackson-core-*.jar | head -1):$(ls ~/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/*/jackson-annotations-*.jar | head -1) -d /tmp/cf-example examples/Basic.java
|
|
// java -cp /tmp/cf-example:target/classes:<jackson jars> Basic
|
|
//
|
|
// Or just import the jar into your own project and run from there.
|
|
|
|
import com.clawdforge.AppToken;
|
|
import com.clawdforge.FileToken;
|
|
import com.clawdforge.ForgeClient;
|
|
import com.clawdforge.HealthStatus;
|
|
import com.clawdforge.RunRequest;
|
|
import com.clawdforge.RunResult;
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import java.nio.file.Path;
|
|
import java.util.List;
|
|
|
|
public class Basic {
|
|
public static void main(String[] args) {
|
|
String baseUrl = System.getenv().getOrDefault("CLAWDFORGE_URL", "http://localhost:8800");
|
|
String token = System.getenv("CLAWDFORGE_TOKEN");
|
|
if (token == null || token.isBlank()) {
|
|
System.err.println("set CLAWDFORGE_TOKEN");
|
|
System.exit(2);
|
|
}
|
|
|
|
ForgeClient client = ForgeClient.builder()
|
|
.baseUrl(baseUrl)
|
|
.token(token)
|
|
.build();
|
|
|
|
// 1. health
|
|
HealthStatus h = client.healthz();
|
|
System.out.printf("ok=%s claude_present=%s version=%s%n",
|
|
h.ok(), h.claudePresent(), h.claudeVersion());
|
|
|
|
// 2. run a prompt asking for JSON
|
|
RunResult res = client.run(RunRequest.builder()
|
|
.prompt("Reply with JSON: {\"hello\": \"world\"}")
|
|
.model("sonnet")
|
|
.timeoutSecs(60)
|
|
.build());
|
|
|
|
System.out.printf("duration=%dms stop_reason=%s%n", res.durationMs(), res.stopReason());
|
|
JsonNode r = res.result();
|
|
if (r.isObject() && r.has("hello")) {
|
|
System.out.println("hello -> " + r.get("hello").asText());
|
|
} else if (r.isTextual()) {
|
|
System.out.println("text -> " + r.asText());
|
|
} else {
|
|
System.out.println("raw -> " + r);
|
|
}
|
|
|
|
// 3. (optional) upload + reference a file
|
|
String filePath = System.getenv("CLAWDFORGE_FILE");
|
|
if (filePath != null && !filePath.isBlank()) {
|
|
FileToken ft = client.uploadFile(Path.of(filePath), 3600);
|
|
System.out.println("uploaded " + ft.fileToken() + " (" + ft.size() + " bytes)");
|
|
|
|
RunResult res2 = client.run(RunRequest.builder()
|
|
.prompt("Summarize the attached file in one sentence.")
|
|
.files(List.of(ft.fileToken()))
|
|
.build());
|
|
System.out.println("summary -> " + res2.result());
|
|
}
|
|
|
|
// 4. (admin) list tokens — only works with the admin bootstrap token
|
|
if (Boolean.parseBoolean(System.getenv().getOrDefault("CLAWDFORGE_ADMIN", "false"))) {
|
|
List<AppToken> tokens = client.listTokens();
|
|
for (AppToken t : tokens) {
|
|
System.out.printf("token name=%s created_at=%d ip_cidrs=%s%n",
|
|
t.name(), t.createdAt(), t.ipCidrs());
|
|
}
|
|
}
|
|
}
|
|
}
|