-
Notifications
You must be signed in to change notification settings - Fork 406
fix: Add filter_id support and v1 filter resolution #1666
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b051ffc
669a490
2a64b38
c5d163e
c74b66d
ca07bf1
f562f46
a3ac69b
8224191
3936dd9
cd96701
14b0805
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
|
|
||
| import type { OpenRAGClient } from "./client"; | ||
| import type { | ||
| DeleteDocumentOptions, | ||
| DeleteDocumentResponse, | ||
| IngestResponse, | ||
| IngestTaskStatus, | ||
|
|
@@ -144,33 +145,57 @@ export class DocumentsClient { | |
| } | ||
|
|
||
| /** | ||
| * Delete a document from the knowledge base. | ||
| * Delete document(s) from the knowledge base. | ||
| * | ||
| * Provide exactly one of: | ||
| * - filename: a single filename, or | ||
| * - { filename } / { filterId }: an options object. | ||
| * | ||
| * @param filename - Name of the file to delete. | ||
| * @returns DeleteDocumentResponse with deleted chunk count. | ||
| */ | ||
| async delete(filename: string): Promise<DeleteDocumentResponse> { | ||
| async delete( | ||
| arg: string | DeleteDocumentOptions | ||
| ): Promise<DeleteDocumentResponse> { | ||
| const opts: DeleteDocumentOptions = | ||
| typeof arg === "string" ? { filename: arg } : arg; | ||
|
|
||
| if (!opts.filename === !opts.filterId) { | ||
| throw new Error( | ||
| "Provide exactly one of `filename` or `filterId`" | ||
| ); | ||
| } | ||
|
|
||
| const body: Record<string, string> = {}; | ||
| if (opts.filename) body.filename = opts.filename; | ||
| if (opts.filterId) body.filter_id = opts.filterId; | ||
|
Comment on lines
+162
to
+170
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enforce selector exclusivity using normalized values. Current truthy checks allow edge cases like Suggested fix- if (!opts.filename === !opts.filterId) {
+ const filename = opts.filename?.trim();
+ const filterId = opts.filterId?.trim();
+ const hasFilename = Boolean(filename);
+ const hasFilterId = Boolean(filterId);
+
+ if (hasFilename === hasFilterId) {
throw new Error(
"Provide exactly one of `filename` or `filterId`"
);
}
const body: Record<string, string> = {};
- if (opts.filename) body.filename = opts.filename;
- if (opts.filterId) body.filter_id = opts.filterId;
+ if (hasFilename) body.filename = filename!;
+ if (hasFilterId) body.filter_id = filterId!;
@@
- opts.filename &&
+ hasFilename &&
(error as NotFoundError)?.statusCode === 404
) {
return {
success: false,
deleted_chunks: 0,
- filename: opts.filename,
+ filename: filename!,Also applies to: 192-193 🤖 Prompt for AI Agents |
||
|
|
||
| try { | ||
| const response = await this.client._request("DELETE", "/api/v1/documents", { | ||
| body: JSON.stringify({ filename }), | ||
| body: JSON.stringify(body), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
| return { | ||
| success: data.success ?? false, | ||
| deleted_chunks: data.deleted_chunks ?? 0, | ||
| filename: data.filename ?? filename, | ||
| filename: data.filename ?? opts.filename ?? null, | ||
| message: data.message ?? null, | ||
| error: data.error ?? null, | ||
| filenames: data.filenames ?? null, | ||
| filter_id: data.filter_id ?? null, | ||
| per_file: data.per_file ?? null, | ||
| }; | ||
| } catch (error) { | ||
| // Delete is idempotent: if no chunks match, backend may return 404. | ||
| // Surface this as a non-throwing "nothing deleted" response. | ||
| if ((error as NotFoundError)?.statusCode === 404) { | ||
| // Filename delete stays idempotent (404 -> success:false). Filter-id 404s | ||
| // are caller errors (bad filter id) and should propagate. | ||
| if ( | ||
| opts.filename && | ||
| (error as NotFoundError)?.statusCode === 404 | ||
| ) { | ||
| return { | ||
| success: false, | ||
| deleted_chunks: 0, | ||
| filename, | ||
| filename: opts.filename, | ||
| message: null, | ||
| error: (error as Error)?.message ?? "Resource not found", | ||
| }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normalize selector validation and payload construction consistently.
Line 148 validates by truthiness, but Lines 152-155/167 branch on
is not None. This letsfilename=""+filter_id="..."bypass the exclusivity check, send both keys, and potentially misclassify a filter 404 as idempotent filename delete.Suggested fix
Also applies to: 167-167
🤖 Prompt for AI Agents