Files
discourse-ai/assets/javascripts/discourse/components/rag-upload-progress.gjs
Sam 5cbc9190eb FEATURE: RAG search within tools (#802)
This allows custom tools access to uploads and sophisticated searches using embedding.

It introduces:

 - A shared front end for listing and uploading files (shared with personas)
 -  Backend implementation of index.search function within a custom tool.

Custom tools now may search through uploaded files

function invoke(params) {
   return index.search(params.query)
}

This means that RAG implementers now may preload tools with knowledge and have high fidelity over
the search.

The search function support

    specifying max results
    specifying a subset of files to search (from uploads)

Also

 - Improved documentation for tools (when creating a tool a preamble explains all the functionality)
  - uploads were a bit finicky, fixed an edge case where the UI would not show them as updated
2024-09-30 17:27:50 +10:00

87 lines
2.3 KiB
Plaintext

import Component from "@glimmer/component";
import { tracked } from "@glimmer/tracking";
import { action } from "@ember/object";
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
import { inject as service } from "@ember/service";
import icon from "discourse-common/helpers/d-icon";
import { bind } from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
export default class RagUploadProgress extends Component {
@service messageBus;
@tracked updatedProgress = null;
willDestroy() {
super.willDestroy(...arguments);
this.messageBus.unsubscribe(`/discourse-ai/rag/${this.args.upload.id}`);
}
@action
trackProgress() {
this.messageBus.subscribe(
`/discourse-ai/rag/${this.args.upload.id}`,
this.onIndexingUpdate
);
}
@bind
onIndexingUpdate(data) {
// Order not guaranteed. Discard old updates.
if (
!this.updatedProgress ||
this.updatedProgress.left === 0 ||
this.updatedProgress.left > data.left ||
data.total === data.indexed
) {
this.updatedProgress = data;
}
}
get calculateProgress() {
if (this.progress.total === 0) {
return 0;
}
return Math.ceil((this.progress.indexed * 100) / this.progress.total);
}
get fullyIndexed() {
return (
this.progress && this.progress.total !== 0 && this.progress.left === 0
);
}
get progress() {
if (this.updatedProgress) {
return this.updatedProgress;
} else if (this.args.ragIndexingStatuses) {
return this.args.ragIndexingStatuses[this.args.upload.id];
} else {
return [];
}
}
<template>
<td class="rag-uploader__upload-status" {{didInsert this.trackProgress}}>
{{#if this.progress}}
{{#if this.fullyIndexed}}
<span class="indexed">
{{icon "check"}}
{{I18n.t "discourse_ai.rag.uploads.indexed"}}
</span>
{{else}}
<span class="indexing">
{{icon "robot"}}
{{I18n.t "discourse_ai.rag.uploads.indexing"}}
{{this.calculateProgress}}%
</span>
{{/if}}
{{else}}
<span class="uploaded">{{I18n.t
"discourse_ai.rag.uploads.uploaded"
}}</span>
{{/if}}
</td>
</template>
}