zbendhiba opened a new pull request, #9374:
URL: https://github.com/apache/camel-quarkus/pull/9374

   …assistants
   
   Fixes #9370. Follow-up to #8706 / #9336, which shipped the built-in skills 
and the Dev MCP tools.
   
   ### The problem
   
   An assistant asked for a Camel Quarkus route answers from training data. It 
guesses endpoint options, invents configuration properties, and has no idea 
which version the project uses. We already ship a skill that teaches the right 
patterns, but the 334 extension reference pages, with their configuration 
tables and their Dev Services behaviour, were not reachable.
   
   The Quarkus Agent MCP server already serves the core Quarkus guides through 
`quarkus_searchDocs`. This PR puts our pages in there too.
   
   ### What it does
   
   ```
   docs/modules/ROOT/pages/reference/extensions/*.adoc   (334 generated pages)
           |
           |  quarkus-documentation-rag-maven-plugin, run once
           |  by the new documentation-rag module
           v
   camel-quarkus-documentation-rag.jar                   (1000 chunks, 5.68 MB 
SQL)
           ^
           |  META-INF/quarkus-rag-artifact.properties
           |
   camel-quarkus-*-deployment.jar  -->  Quarkus Agent MCP server
   ```
   
   Each deployment JAR carries a 2 line pointer naming the artifact. The server 
reads it, resolves that artifact at the version of the extension that carried 
the pointer, downloads it once, and loads the embeddings. No coordinate of ours 
is compiled into the server, and users declare nothing.
   
   ### Why one shared artifact
   
   The plugin supports three mechanisms. Only the third fits a repository with 
334 extensions.
   
   | Mechanism | Verdict |
   |---|---|
   | Inline `META-INF/quarkus-rag.sql` in every deployment JAR | Works. 
Implemented and measured first. 271 SQL files, 4.8 MB spread over the extension 
JARs, and +29.3 s on the full reactor. |
   | Central aggregated artifact | Impossible. The server resolves aggregates 
only under the hardcoded coordinate 
`io.quarkus:quarkus-documentation-core-rag`. |
   | Pointer to a separate artifact | Chosen. One artifact, one generation, 
nothing added to the extension JARs beyond the pointer. |
   
   How upstream does it, for context:
   
   - **Quarkiverse** (`quarkiverse-parent` PR #235) declares the plugin in the 
parent and has each deployment pom opt in with `<quarkus-rag.guide>`, behind an 
opt-in `-Drag` profile.
   - **Quarkus core** uses a central `devtools/extension-rag` module gated on 
the `release` profile, publishing the aggregated artifact.
   
   We are closer to the Quarkus core shape, one module producing one artifact, 
but with a pointer instead of the hardcoded coordinate we cannot use.
   
   ### Build cost
   
   Generation runs in one module instead of 334. That module goes from 9.3 s to 
24.8 s, so +15.5 s on a full build. It is skipped by `-Dquickly`, like the rest 
of the documentation tooling.
   
   ### The `:extensions:` attribute
   
   `update-extension-doc-page` now writes one line per page:
   
   ```asciidoc
   :extensions: org.apache.camel.quarkus:camel-quarkus-kafka
   ```
   
   It is in the FreeMarker template, so a new extension gets it for free, and 
the 334 page changes in this PR are regenerated output.
   
   It is required twice over, and the second reason is the decisive one:
   
   1. Without it, the plugin names the source after the file name, which yields 
`quarkus-core`, `quarkus-jolokia` and other real core Quarkus source names. The 
server deletes a source before reloading it, so we would wipe genuine Quarkus 
documentation.
   2. The server rewrites each row's source to the artifactId of the dependency 
that pointed at the artifact, unless the row declares its own extension in the 
same groupId. That declaration is what the attribute produces. Without it, all 
1000 chunks collapse onto a single source.
   
   This is also the upstream convention, not a workaround of ours. Both forms 
coexist in `quarkus-documentation-core-rag`: `kafka-getting-started.adoc` is 
published as `quarkus-messaging-kafka` from the attribute, `all-config.adoc` as 
`quarkus-all-config` from the file name.
   
   ### Minimum server version
   
   `quarkus-agent-mcp` 1.2.8 or newer. Pointer support starts at 1.1.5, but 
versions below 1.2.8 track a single source per artifact and purge with a 
hardcoded `DELETE ... = 'quarkus-documentation'` that matches nothing, so the 
shared artifact would duplicate every chunk on reload. 1.2.8 added 
`extractSources` and `DELETE ... = ANY(?)`.
   
   Documented directly, since the agent side is not released yet.
   
   ### What I verified
   
   - 334/334 pages carry the attribute. The artifact has 334 distinct 
`camel-quarkus-*` sources and zero `quarkus-*`.
   - Deployment JARs carry the pointer only, no inline SQL. `-Dquickly` skips 
generation.
   - End to end against the real 1.2.12 `RagSqlLoader`: 122 transitive 
dependencies resolved, pointer read from `camel-quarkus-kafka-deployment`, 
artifact resolved in 35 ms, 334 sources reported. Deduplication means it is 
resolved once per project, not 334 times.
   - No BOM entry is needed, and the module has to sit in the root `<modules>` 
rather than the `standard-build` profile, which is disabled during a release.
   
   ### One bug found along the way, not a blocker here
   
   End to end search kept returning nothing of ours, while an exact vector 
search ranked our chunks first (kafka 0.9041, jms 0.8749, ftp 0.8757). The 
cause is on the server side: the `ivfflat` index is queried with the pgvector 
default `ivfflat.probes = 1`, which searches one cluster.
   
   | probes | recall@10 | latency |
   |---|---|---|
   | 1 | 54.4% | 1 ms |
   | 10 | 87.5% | 2 ms |
   | 50 | 100% | ~5 ms |
   
   Measured over 16 queries. One core Quarkus query ("configure logging 
categories and levels") scored 0/10. This affects core Quarkus documentation as 
much as ours, and is still present in 1.2.12. To be reported upstream, with 
these numbers.
   
   ### Documentation
   
   - New contributor guide page, `contributor-guide/documentation-rag.adoc`: 
the pipeline, source naming, the module, the pointer, a walkthrough of an 
assistant adding Camel to a project that has none, how the server finds and 
downloads the artifact, local build and inspection commands, and the known 
limitations.
   - `user-guide/quarkus-agent-mcp.adoc`: what users get and the minimum 
version.
   
   ### Open for discussion
   
   - **Gating.** Generation runs on `!quickly`, so a normal build produces it. 
Both upstream projects gate it off by default instead. Should we follow them 
and only build it on release?
   - **Upstream.** Worth proposing a `sourceNamePrefix` parameter on the 
plugin, so the file name fallback yields `camel-quarkus-<file>` instead of 
`quarkus-<file>`. Three lines in `RagPipeline.resolveSourceName`. We do not 
need it, but it removes a collision trap for the next project in our position.
   - **Scope.** The whole reference corpus is loaded as soon as one Camel 
Quarkus extension is on the class path. Per extension artifacts would scope it 
tighter, at the price of 334 artifacts. Worth revisiting once recall is fixed.
   - Other approaches welcome. I am not attached to this one, it is the one 
that works with the server as it is today.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to