Skip to content

Commit 85b3895

Browse files
committed
Fix javadoc build error + reduce warnings on new classes
The release packaging job (mvn package, release profile) runs maven-javadoc-plugin's attach-javadocs which treats Javadoc tool errors as build failures. PR #188 introduced one such error: TokenLogprob.java had a </p> with no matching <p> (the prose was already enclosed by an outer <p>...</p>, and the inner </p> was stray). Fix the error and bring my new public APIs up to a clean shape: - TokenLogprob: rebalance the <p>/</p> HTML and add @return / @param to public getters and constructor. - Timings, Usage, ServerMetrics, ChatMessage, CancellationToken, Session, LlamaOutput: add @return / @param tags with a leading one-line description (the "no main description" warning fires on bare /** @return ... */ blocks). - LlamaModel: restore the doc comment for complete(params, token) that was accidentally stripped during an earlier edit, and add one for getMetricsTyped(); remove a stray orphan doc block. Local verification: mvn clean javadoc:jar -DskipTests=true -Dgpg.skip=true mvn -P release -Dmaven.test.skip=true -Dgpg.skip=true package Both: BUILD SUCCESS (was: BUILD FAILURE, 1 error, 100 warnings). 60 warnings remain, all from pre-existing files outside this PR. Document the verification command and the failure categories (errors vs warnings) in CLAUDE.md under "Javadoc — must build cleanly before mvn package". https://claude.ai/code/session_01R4ZrEy3ptJDLuUgUKuM4Gy
1 parent e3b9043 commit 85b3895

10 files changed

Lines changed: 256 additions & 35 deletions

File tree

CLAUDE.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,52 @@ into `models/` out-of-band.
514514
clang-format -i src/main/cpp/*.cpp src/main/cpp/*.hpp # Format C++ code
515515
```
516516

517+
### Javadoc — must build cleanly before `mvn package`
518+
519+
The release packaging job runs `mvn package` with the `release` profile, which attaches
520+
a javadoc jar via `maven-javadoc-plugin`. The plugin treats Javadoc tool **errors** as
521+
build failures (warnings are tolerated). After changing any public/protected Java API,
522+
verify the javadoc build succeeds locally:
523+
524+
```bash
525+
mvn clean javadoc:jar -DskipTests=true -Dgpg.skip=true
526+
# expected: BUILD SUCCESS
527+
```
528+
529+
Common Javadoc errors that fail the build (not warnings):
530+
531+
- **Unbalanced HTML**: `</p>` without a matching `<p>`, mismatched `<ul>`/`<li>`, stray
532+
closing tags. Symptom: `error: unexpected end tag: </p>`.
533+
- **Invalid `{@link …}` targets**: typo'd class, method, or parameter name.
534+
- **Self-closing void HTML elements written as `<br>` inside `<pre>` blocks** in HTML5
535+
mode (rare but seen).
536+
537+
Common Javadoc *warnings* (do not fail the build, but should be cleaned up on new code):
538+
539+
- `no main description` — a doc comment containing only `@param`/`@return`/`@throws`
540+
tags with no leading prose. Fix: add a one-line description before the tags.
541+
- `no @return` / `no @param` — public method missing the tag. Fix: add it.
542+
- `no comment` — public method/field/enum constant has no doc comment at all.
543+
- `use of default constructor, which does not provide a comment` — public class with
544+
no explicit constructor (the synthetic default has no Javadoc). Fix: add an explicit
545+
no-arg constructor with a Javadoc comment.
546+
547+
Preferred doc-comment shapes for getters and small value types:
548+
549+
```java
550+
/**
551+
* Brief one-line description of the value.
552+
*
553+
* @return the value
554+
*/
555+
public T getThing() { ... }
556+
```
557+
558+
A bare `/** @return … */` triggers `no main description`; add a leading sentence.
559+
560+
If the local check passes (`BUILD SUCCESS`), the `mvn package` job in
561+
`.github/workflows/publish.yml` will pass the `attach-javadocs` step.
562+
517563
## Architecture
518564

519565
### Two-Layer Design

src/main/java/net/ladenthin/llama/CancellationToken.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,15 @@ public final class CancellationToken {
2424

2525
private volatile boolean cancelled;
2626

27+
/** Construct a fresh, not-cancelled token. */
2728
public CancellationToken() {
2829
// empty
2930
}
3031

31-
/** Returns {@code true} once {@link #cancel()} has been called and before {@link #reset()}. */
32+
/**
33+
* Cancellation flag accessor.
34+
* @return {@code true} once {@link #cancel()} has been called and before {@link #reset()}
35+
*/
3236
public boolean isCancelled() {
3337
return cancelled;
3438
}

src/main/java/net/ladenthin/llama/ChatMessage.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,29 @@ public final class ChatMessage {
1414
private final String role;
1515
private final String content;
1616

17+
/**
18+
* Construct a chat message.
19+
*
20+
* @param role the message role: {@code "user"}, {@code "assistant"}, or {@code "system"}
21+
* @param content the message text
22+
*/
1723
public ChatMessage(String role, String content) {
1824
this.role = role;
1925
this.content = content;
2026
}
2127

28+
/**
29+
* Message role accessor.
30+
* @return the message role string
31+
*/
2232
public String getRole() {
2333
return role;
2434
}
2535

36+
/**
37+
* Message content accessor.
38+
* @return the message text content
39+
*/
2640
public String getContent() {
2741
return content;
2842
}

src/main/java/net/ladenthin/llama/LlamaModel.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,16 @@ public CompletableFuture<String> chatCompleteTextAsync(InferenceParameters param
137137
return CompletableFuture.supplyAsync(() -> chatCompleteText(parameters));
138138
}
139139

140+
/**
141+
* Cancellable variant of {@link #complete(InferenceParameters)}. Runs in streaming mode
142+
* internally so the inference loop can observe a {@link CancellationToken#cancel()} call
143+
* from another thread between token boundaries and return early with whatever text was
144+
* accumulated so far.
145+
*
146+
* @param parameters the inference configuration (its {@code stream} flag is set to {@code true})
147+
* @param token cancellation handle observed at each token boundary
148+
* @return the text generated up to the point of stop or cancellation
149+
*/
140150
public String complete(InferenceParameters parameters, CancellationToken token) {
141151
token.reset();
142152
parameters.setStream(true);
@@ -453,14 +463,6 @@ public String getMetrics() {
453463
private static final com.fasterxml.jackson.databind.ObjectMapper OBJECT_MAPPER =
454464
new com.fasterxml.jackson.databind.ObjectMapper();
455465

456-
/**
457-
* Typed accessor for {@link #getMetrics()}. Parses the raw JSON into a
458-
* {@link ServerMetrics} view that exposes cumulative {@link Usage} and
459-
* {@link Timings}, slot counts, and a passthrough to the underlying JSON.
460-
*
461-
* @return parsed {@link ServerMetrics}
462-
* @throws LlamaException if the native call fails or the response cannot be parsed
463-
*/
464466
/**
465467
* Run {@link #complete(InferenceParameters)} constrained to the supplied JSON Schema
466468
* and deserialize the result into an instance of {@code type}. The schema is applied
@@ -506,6 +508,14 @@ public <T> T completeAsJson(Class<T> type, InferenceParameters parameters) throw
506508
}
507509
}
508510

511+
/**
512+
* Typed accessor for {@link #getMetrics()}. Parses the raw JSON into a
513+
* {@link ServerMetrics} view that exposes cumulative {@link Usage} and
514+
* {@link Timings}, slot counts, and a passthrough to the underlying JSON.
515+
*
516+
* @return parsed {@link ServerMetrics}
517+
* @throws LlamaException if the native call fails or the response cannot be parsed
518+
*/
509519
public ServerMetrics getMetricsTyped() throws LlamaException {
510520
try {
511521
return new ServerMetrics(OBJECT_MAPPER.readTree(getMetrics()));

src/main/java/net/ladenthin/llama/LlamaOutput.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,27 @@ public final class LlamaOutput {
5252
@NotNull
5353
public final StopReason stopReason;
5454

55+
/**
56+
* Backwards-compatible constructor that leaves {@link #logprobs} empty.
57+
*
58+
* @param text generated text fragment
59+
* @param probabilities token-to-probability map (may be empty)
60+
* @param stop whether this is the final token
61+
* @param stopReason the stop reason ({@link StopReason#NONE} on intermediate tokens)
62+
*/
5563
public LlamaOutput(@NotNull String text, @NotNull Map<String, Float> probabilities, boolean stop, @NotNull StopReason stopReason) {
5664
this(text, probabilities, Collections.<TokenLogprob>emptyList(), stop, stopReason);
5765
}
5866

67+
/**
68+
* Construct an output with typed per-token logprobs in addition to the flat probability map.
69+
*
70+
* @param text generated text fragment
71+
* @param probabilities token-to-probability map (may be empty)
72+
* @param logprobs typed per-token logprob entries (may be empty)
73+
* @param stop whether this is the final token
74+
* @param stopReason the stop reason ({@link StopReason#NONE} on intermediate tokens)
75+
*/
5976
public LlamaOutput(@NotNull String text, @NotNull Map<String, Float> probabilities,
6077
@NotNull List<TokenLogprob> logprobs, boolean stop, @NotNull StopReason stopReason) {
6178
this.text = text;

src/main/java/net/ladenthin/llama/ServerMetrics.java

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,39 +32,59 @@ public final class ServerMetrics {
3232
this.node = node;
3333
}
3434

35-
/** Number of slots currently idle. */
35+
/**
36+
* Idle slot count.
37+
* @return number of slots currently idle
38+
*/
3639
public int getIdleSlots() {
3740
return node.path("idle").asInt(0);
3841
}
3942

40-
/** Number of slots currently processing a task. */
43+
/**
44+
* Busy slot count.
45+
* @return number of slots currently processing a task
46+
*/
4147
public int getProcessingSlots() {
4248
return node.path("processing").asInt(0);
4349
}
4450

45-
/** Number of tasks waiting in the deferred queue. */
51+
/**
52+
* Backlog size.
53+
* @return number of tasks waiting in the deferred queue
54+
*/
4655
public int getDeferredTasks() {
4756
return node.path("deferred").asInt(0);
4857
}
4958

50-
/** Server start timestamp (millis since epoch as reported by llama.cpp). */
59+
/**
60+
* Server start timestamp.
61+
* @return millis since epoch as reported by llama.cpp
62+
*/
5163
public long getStartTimestamp() {
5264
return node.path("t_start").asLong(0L);
5365
}
5466

55-
/** Total decode invocations since server start. */
67+
/**
68+
* Lifetime decode counter.
69+
* @return total decode invocations since server start
70+
*/
5671
public long getDecodeTotal() {
5772
return node.path("n_decode_total").asLong(0L);
5873
}
5974

60-
/** Cumulative number of busy-slot ticks (1 per decode per busy slot). */
75+
/**
76+
* Lifetime busy-slot counter.
77+
* @return cumulative number of busy-slot ticks (1 per decode per busy slot)
78+
*/
6179
public long getBusySlotsTotal() {
6280
return node.path("n_busy_slots_total").asLong(0L);
6381
}
6482

6583
/**
6684
* Maximum number of tokens any active slot is configured to hold. Absent in the
6785
* upstream JSON when no slot has been used yet; this getter returns {@code 0} then.
86+
*
87+
* @return the slot token-budget ceiling, or {@code 0} when no slot has been active
6888
*/
6989
public int getTokensMax() {
7090
return node.path("n_tokens_max").asInt(0);
@@ -74,6 +94,8 @@ public int getTokensMax() {
7494
* Cumulative server-wide token usage since startup. Prompt tokens come from
7595
* {@code n_prompt_tokens_processed_total} and completion tokens from
7696
* {@code n_tokens_predicted_total}.
97+
*
98+
* @return cumulative {@link Usage} across all completions since server start
7799
*/
78100
public Usage getCumulativeUsage() {
79101
return new Usage(
@@ -82,8 +104,10 @@ public Usage getCumulativeUsage() {
82104
}
83105

84106
/**
85-
* Usage counters from the most recent measurement window (current bucket)
107+
* Usage counters from the most recent measurement window (current bucket) &mdash;
86108
* {@code n_prompt_tokens_processed} and {@code n_tokens_predicted}.
109+
*
110+
* @return per-window {@link Usage} since the previous metrics emission
87111
*/
88112
public Usage getWindowUsage() {
89113
return new Usage(
@@ -94,6 +118,8 @@ public Usage getWindowUsage() {
94118
/**
95119
* Cumulative throughput derived from the totals fields. Returns {@code 0.0} for
96120
* any rate where the corresponding ms total is zero.
121+
*
122+
* @return cumulative {@link Timings} aggregated from server-wide totals
97123
*/
98124
public Timings getCumulativeTimings() {
99125
long promptN = node.path("n_prompt_tokens_processed_total").asLong(0L);
@@ -106,12 +132,18 @@ public Timings getCumulativeTimings() {
106132
(int) predictedN, predictedMs, predictedPerSec, 0, 0);
107133
}
108134

109-
/** The {@code slots} array node, or a missing-node when no slots are reported. */
135+
/**
136+
* Slots array passthrough.
137+
* @return the {@code slots} array node, or a missing-node when no slots are reported
138+
*/
110139
public JsonNode getSlots() {
111140
return node.path("slots");
112141
}
113142

114-
/** Underlying JSON for direct access to fields not yet exposed by typed getters. */
143+
/**
144+
* Raw passthrough escape hatch.
145+
* @return underlying JSON for direct access to fields not yet exposed by typed getters
146+
*/
115147
public JsonNode asJson() {
116148
return node;
117149
}

src/main/java/net/ladenthin/llama/Session.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ public Session(LlamaModel model, int slotId, String systemMessage,
5858
this.paramsCustomizer = paramsCustomizer;
5959
}
6060

61-
/** Send a user message and return the assistant's text reply, appending both to the transcript. */
61+
/**
62+
* Send a user message and return the assistant's text reply, appending both to the transcript.
63+
*
64+
* @param userMessage the user turn to append before invoking the model
65+
* @return the assistant's reply text
66+
*/
6267
public String send(String userMessage) {
6368
turns.add(new Pair<String, String>("user", userMessage));
6469
InferenceParameters params = buildParams();
@@ -72,6 +77,9 @@ public String send(String userMessage) {
7277
* the assistant reply; consume it fully (or via try-with-resources) before calling
7378
* {@link #send(String)} again, because the assistant turn is only appended to the
7479
* transcript when the caller invokes {@link #commitStreamedReply(String)}.
80+
*
81+
* @param userMessage the user turn to append before starting the stream
82+
* @return a {@link LlamaIterable} that yields assistant reply chunks
7583
*/
7684
public LlamaIterable stream(String userMessage) {
7785
turns.add(new Pair<String, String>("user", userMessage));
@@ -81,22 +89,37 @@ public LlamaIterable stream(String userMessage) {
8189
/**
8290
* Record an assistant reply that was produced by a previous {@link #stream(String)}
8391
* call. Called by the caller after it has accumulated the streamed text.
92+
*
93+
* @param assistantText the assistant text accumulated from a prior {@link #stream(String)} call
8494
*/
8595
public void commitStreamedReply(String assistantText) {
8696
turns.add(new Pair<String, String>("assistant", assistantText));
8797
}
8898

89-
/** Save this session's slot KV cache to {@code filepath}. */
99+
/**
100+
* Save this session's slot KV cache to {@code filepath}.
101+
*
102+
* @param filepath destination file path passed to {@link LlamaModel#saveSlot(int, String)}
103+
* @return the JSON response from the native save action
104+
*/
90105
public String save(String filepath) {
91106
return model.saveSlot(slotId, filepath);
92107
}
93108

94-
/** Restore this session's slot KV cache from {@code filepath}. */
109+
/**
110+
* Restore this session's slot KV cache from {@code filepath}.
111+
*
112+
* @param filepath source file path passed to {@link LlamaModel#restoreSlot(int, String)}
113+
* @return the JSON response from the native restore action
114+
*/
95115
public String restore(String filepath) {
96116
return model.restoreSlot(slotId, filepath);
97117
}
98118

99-
/** The accumulated turns so far, in order. */
119+
/**
120+
* Transcript accessor.
121+
* @return the accumulated transcript so far, in order, including the system message if any
122+
*/
100123
public List<ChatMessage> getMessages() {
101124
List<ChatMessage> out = new ArrayList<ChatMessage>(turns.size() + 1);
102125
if (systemMessage != null && !systemMessage.isEmpty()) {

0 commit comments

Comments
 (0)