Skip to content

Commit 4c72522

Browse files
authored
Merge pull request #1045 from quarkiverse/#1044
Improve model download progress logging
2 parents adf9f0d + b476e73 commit 4c72522

File tree

5 files changed

+453
-3
lines changed

5 files changed

+453
-3
lines changed

core/deployment/src/main/java/io/quarkiverse/langchain4j/deployment/devservice/DevServicesOllamaProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private void handleModels(List<DevServicesChatModelRequiredBuildItem> devService
9393
for (String model : modelsToPull) {
9494
// we pull one model at a time and provide progress updates to the user via logging
9595
LOGGER.info("Pulling model " + model);
96+
AtomicReference<Long> LAST_UPDATE_REF = new AtomicReference<>();
9697

9798
CompletableFuture<Void> cf = new CompletableFuture<>();
9899
client.pullAsync(model).subscribe(new Flow.Subscriber<>() {
@@ -109,18 +110,39 @@ public void onNext(OllamaClient.PullAsyncLine line) {
109110
clientThreadName.compareAndSet(null, Thread.currentThread().getName());
110111
if ((line.total() != null) && (line.completed() != null) && (line.status() != null)
111112
&& line.status().contains("pulling")) {
113+
if (!logUpdate(LAST_UPDATE_REF.get())) {
114+
return;
115+
}
116+
117+
LAST_UPDATE_REF.set(System.nanoTime());
112118
BigDecimal percentage = new BigDecimal(line.completed()).divide(new BigDecimal(line.total()), 4,
113119
RoundingMode.HALF_DOWN).multiply(ONE_HUNDRED);
114120
BigDecimal progress = percentage.setScale(2, RoundingMode.HALF_DOWN);
115121
if (progress.compareTo(ONE_HUNDRED) >= 0) {
116122
// avoid showing 100% for too long
117123
LOGGER.infof("Verifying and cleaning up\n", progress);
118124
} else {
119-
LOGGER.infof("Progress: %s%%\n", progress);
125+
LOGGER.infof("%s - Progress: %s%%\n", model, progress);
120126
}
121127
}
122128
}
123129

130+
/**
131+
* @param lastUpdate The last update time in nanoseconds
132+
* Determines whether we should log an update.
133+
* This is done in order to not overwhelm the console with updates which might make
134+
* canceling the download difficult. See
135+
* <a href="https://github.com/quarkiverse/quarkus-langchain4j/issues/1044">this</a>
136+
*/
137+
private boolean logUpdate(Long lastUpdate) {
138+
if (lastUpdate == null) {
139+
return true;
140+
} else {
141+
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime())
142+
- TimeUnit.NANOSECONDS.toMillis(lastUpdate) > 1_000;
143+
}
144+
}
145+
124146
@Override
125147
public void onError(Throwable throwable) {
126148
cf.completeExceptionally(throwable);

docs/modules/ROOT/pages/includes/quarkus-langchain4j-tavily.adoc

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,193 @@ a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-exclude-domains]] [.p
185185
A list of domains to specifically exclude from the search results. Default is ++[]++, which doesn't exclude any domains.
186186

187187

188+
ifdef::add-copy-button-to-env-var[]
189+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_EXCLUDE_DOMAINS+++[]
190+
endif::add-copy-button-to-env-var[]
191+
ifndef::add-copy-button-to-env-var[]
192+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_EXCLUDE_DOMAINS+++`
193+
endif::add-copy-button-to-env-var[]
194+
--
195+
|list of string
196+
|`[]`
197+
198+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-base-url]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-base-url[`quarkus.langchain4j.tavily.base-url`]##
199+
200+
[.description]
201+
--
202+
Base URL of the Tavily API
203+
204+
205+
ifdef::add-copy-button-to-env-var[]
206+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_BASE_URL+++[]
207+
endif::add-copy-button-to-env-var[]
208+
ifndef::add-copy-button-to-env-var[]
209+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_BASE_URL+++`
210+
endif::add-copy-button-to-env-var[]
211+
--
212+
|string
213+
|`https://api.tavily.com`
214+
215+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-api-key]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-api-key[`quarkus.langchain4j.tavily.api-key`]##
216+
217+
[.description]
218+
--
219+
API key for the Tavily API
220+
221+
222+
ifdef::add-copy-button-to-env-var[]
223+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_API_KEY+++[]
224+
endif::add-copy-button-to-env-var[]
225+
ifndef::add-copy-button-to-env-var[]
226+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_API_KEY+++`
227+
endif::add-copy-button-to-env-var[]
228+
--
229+
|string
230+
|required icon:exclamation-circle[title=Configuration property is required]
231+
232+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-max-results]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-max-results[`quarkus.langchain4j.tavily.max-results`]##
233+
234+
[.description]
235+
--
236+
Maximum number of results to return
237+
238+
239+
ifdef::add-copy-button-to-env-var[]
240+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_MAX_RESULTS+++[]
241+
endif::add-copy-button-to-env-var[]
242+
ifndef::add-copy-button-to-env-var[]
243+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_MAX_RESULTS+++`
244+
endif::add-copy-button-to-env-var[]
245+
--
246+
|int
247+
|`5`
248+
249+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-timeout]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-timeout[`quarkus.langchain4j.tavily.timeout`]##
250+
251+
[.description]
252+
--
253+
The timeout duration for Tavily requests.
254+
255+
256+
ifdef::add-copy-button-to-env-var[]
257+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_TIMEOUT+++[]
258+
endif::add-copy-button-to-env-var[]
259+
ifndef::add-copy-button-to-env-var[]
260+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_TIMEOUT+++`
261+
endif::add-copy-button-to-env-var[]
262+
--
263+
|link:https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Duration.html[Duration] link:#duration-note-anchor-{summaryTableId}[icon:question-circle[title=More information about the Duration format]]
264+
|`60S`
265+
266+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-log-requests]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-log-requests[`quarkus.langchain4j.tavily.log-requests`]##
267+
268+
[.description]
269+
--
270+
Whether requests to Tavily should be logged
271+
272+
273+
ifdef::add-copy-button-to-env-var[]
274+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_LOG_REQUESTS+++[]
275+
endif::add-copy-button-to-env-var[]
276+
ifndef::add-copy-button-to-env-var[]
277+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_LOG_REQUESTS+++`
278+
endif::add-copy-button-to-env-var[]
279+
--
280+
|boolean
281+
|`false`
282+
283+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-log-responses]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-log-responses[`quarkus.langchain4j.tavily.log-responses`]##
284+
285+
[.description]
286+
--
287+
Whether responses from Tavily should be logged
288+
289+
290+
ifdef::add-copy-button-to-env-var[]
291+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_LOG_RESPONSES+++[]
292+
endif::add-copy-button-to-env-var[]
293+
ifndef::add-copy-button-to-env-var[]
294+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_LOG_RESPONSES+++`
295+
endif::add-copy-button-to-env-var[]
296+
--
297+
|boolean
298+
|`false`
299+
300+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-search-depth]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-search-depth[`quarkus.langchain4j.tavily.search-depth`]##
301+
302+
[.description]
303+
--
304+
The search depth to use. This can be "basic" or "advanced". Basic is the default.
305+
306+
307+
ifdef::add-copy-button-to-env-var[]
308+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_SEARCH_DEPTH+++[]
309+
endif::add-copy-button-to-env-var[]
310+
ifndef::add-copy-button-to-env-var[]
311+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_SEARCH_DEPTH+++`
312+
endif::add-copy-button-to-env-var[]
313+
--
314+
a|SearchDepth
315+
|`basic`
316+
317+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-answer]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-answer[`quarkus.langchain4j.tavily.include-answer`]##
318+
319+
[.description]
320+
--
321+
Include a short answer to original query. Default is false.
322+
323+
324+
ifdef::add-copy-button-to-env-var[]
325+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_ANSWER+++[]
326+
endif::add-copy-button-to-env-var[]
327+
ifndef::add-copy-button-to-env-var[]
328+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_ANSWER+++`
329+
endif::add-copy-button-to-env-var[]
330+
--
331+
|boolean
332+
|`false`
333+
334+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-raw-content]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-raw-content[`quarkus.langchain4j.tavily.include-raw-content`]##
335+
336+
[.description]
337+
--
338+
Include the cleaned and parsed HTML content of each search result. Default is false.
339+
340+
341+
ifdef::add-copy-button-to-env-var[]
342+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_RAW_CONTENT+++[]
343+
endif::add-copy-button-to-env-var[]
344+
ifndef::add-copy-button-to-env-var[]
345+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_RAW_CONTENT+++`
346+
endif::add-copy-button-to-env-var[]
347+
--
348+
|boolean
349+
|`false`
350+
351+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-domains]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-include-domains[`quarkus.langchain4j.tavily.include-domains`]##
352+
353+
[.description]
354+
--
355+
A list of domains to specifically include in the search results. Default is ++[]++, which includes all domains.
356+
357+
358+
ifdef::add-copy-button-to-env-var[]
359+
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_DOMAINS+++[]
360+
endif::add-copy-button-to-env-var[]
361+
ifndef::add-copy-button-to-env-var[]
362+
Environment variable: `+++QUARKUS_LANGCHAIN4J_TAVILY_INCLUDE_DOMAINS+++`
363+
endif::add-copy-button-to-env-var[]
364+
--
365+
|list of string
366+
|`[]`
367+
368+
a| [[quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-exclude-domains]] [.property-path]##link:#quarkus-langchain4j-tavily_quarkus-langchain4j-tavily-exclude-domains[`quarkus.langchain4j.tavily.exclude-domains`]##
369+
370+
[.description]
371+
--
372+
A list of domains to specifically exclude from the search results. Default is ++[]++, which doesn't exclude any domains.
373+
374+
188375
ifdef::add-copy-button-to-env-var[]
189376
Environment variable: env_var_with_copy_button:+++QUARKUS_LANGCHAIN4J_TAVILY_EXCLUDE_DOMAINS+++[]
190377
endif::add-copy-button-to-env-var[]

0 commit comments

Comments
 (0)