fix(rag): address Copilot review findings on the driver abstraction
Five review comments, all real:
- hybrid_search ran its vector and keyword legs sequentially after the
provider refactor; main ran them under tokio::join!. Restores the
concurrency while keeping the degrade-on-error keyword behaviour, so a
remote provider no longer pays two serial round trips per query.
- inject_rag_secrets derived a vault secret name by trimming braces, which
leaves a literal key untouched. A RAG holding a plaintext api_key therefore
looked the secret up by its own value and printed it to stderr on failure.
Parsing is now strict and a non-placeholder is skipped with a warning that
names no credential.
- validate() now refuses a driver_config.api_key that is not a {{NAME}}
placeholder, so a plaintext key cannot reach the RAG YAML at all.
- Rag::create's catch-all arm treated any unrecognised driver as yaml. A typo
built a yaml store, paid to embed the corpus, persisted the bad driver and
only failed on the next run. Unknown drivers now fail immediately.
- The qdrant arm's error was written for a developer; it now tells the user
that only attached collections are readable and points at .rag attach.
This commit is contained in:
+15
-5
@@ -19,7 +19,7 @@ use crate::config::AppConfig;
|
||||
use crate::config::Config;
|
||||
use crate::config::VAULT_DATA_FILE_NAME;
|
||||
use crate::config::paths;
|
||||
use crate::rag::RagData;
|
||||
use crate::rag::{RagData, placeholder_secret_name};
|
||||
use crate::sandbox::mcp_credentials::MCP_MIXIN_NAME;
|
||||
use crate::sandbox::mixins::DiscoveredMixin;
|
||||
use crate::utils::run_command_with_output;
|
||||
@@ -344,10 +344,20 @@ fn inject_rag_secrets(vault: &Vault, registered: &HashSet<String>) -> Result<()>
|
||||
if service_id.is_empty() || registered.contains(&service_id) {
|
||||
continue;
|
||||
}
|
||||
let secret_name = placeholder
|
||||
.trim_start_matches("{{")
|
||||
.trim_end_matches("}}")
|
||||
.trim();
|
||||
// A literal key must NOT be mistaken for a secret NAME. The trims that
|
||||
// used to stand here leave a non-placeholder value completely untouched,
|
||||
// so the vault lookup below would run with the credential as the "name"
|
||||
// and the warning would then print that credential to stderr.
|
||||
let Some(secret_name) = placeholder_secret_name(placeholder) else {
|
||||
eprintln!(
|
||||
"Warning: RAG '{stem}' has a driver_config.api_key that is not a \
|
||||
secret placeholder, so no credential can be provisioned to the \
|
||||
sandbox and queries to this RAG will fail inside it. Store the \
|
||||
key with `coyote --add-secret <NAME>`, then set api_key to the \
|
||||
matching placeholder in the RAG YAML."
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
match vault.get_secret(secret_name, false) {
|
||||
Ok(secret_value) => {
|
||||
|
||||
Reference in New Issue
Block a user