feat(core): display embedding progress (#10871)
Close [BS-2791](https://linear.app/affine-design/issue/BS-2791).
This commit is contained in:
@@ -61,6 +61,8 @@ export type ChatContextValue = {
|
|||||||
images: File[];
|
images: File[];
|
||||||
// chips of workspace doc or user uploaded file
|
// chips of workspace doc or user uploaded file
|
||||||
chips: ChatChip[];
|
chips: ChatChip[];
|
||||||
|
// the progress of the embedding
|
||||||
|
embeddingProgress: [number, number];
|
||||||
abortController: AbortController | null;
|
abortController: AbortController | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ const DEFAULT_CHAT_CONTEXT_VALUE: ChatContextValue = {
|
|||||||
status: 'idle',
|
status: 'idle',
|
||||||
error: null,
|
error: null,
|
||||||
markdown: '',
|
markdown: '',
|
||||||
|
embeddingProgress: [0, 0],
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ChatPanel extends SignalWatcher(
|
export class ChatPanel extends SignalWatcher(
|
||||||
@@ -192,12 +193,8 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
(a, b) =>
|
(a, b) =>
|
||||||
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
||||||
);
|
);
|
||||||
let allDone = true;
|
|
||||||
const chips: ChatChip[] = await Promise.all(
|
const chips: ChatChip[] = await Promise.all(
|
||||||
list.map(async item => {
|
list.map(async item => {
|
||||||
if (item.status === 'processing') {
|
|
||||||
allDone = false;
|
|
||||||
}
|
|
||||||
if (isDocContext(item)) {
|
if (isDocContext(item)) {
|
||||||
return {
|
return {
|
||||||
docId: item.id,
|
docId: item.id,
|
||||||
@@ -228,10 +225,10 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
...this.chatContextValue,
|
...this.chatContextValue,
|
||||||
chips,
|
chips,
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
if (!allDone) {
|
private readonly _initEmbeddingProgress = async () => {
|
||||||
await this._pollContextDocsAndFiles();
|
await this._pollContextDocsAndFiles();
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _getSessionId = async () => {
|
private readonly _getSessionId = async () => {
|
||||||
@@ -357,6 +354,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
await this._initChips();
|
await this._initChips();
|
||||||
|
await this._initEmbeddingProgress();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
@@ -367,8 +365,8 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this._pollAbortController) {
|
if (this._pollAbortController) {
|
||||||
// already polling, return
|
// already polling, reset timer
|
||||||
return;
|
this._abortPoll();
|
||||||
}
|
}
|
||||||
this._pollAbortController = new AbortController();
|
this._pollAbortController = new AbortController();
|
||||||
await AIProvider.context.pollContextDocsAndFiles(
|
await AIProvider.context.pollContextDocsAndFiles(
|
||||||
@@ -389,17 +387,18 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
}
|
}
|
||||||
const { docs = [], files = [] } = result;
|
const { docs = [], files = [] } = result;
|
||||||
const hashMap = new Map<string, CopilotContextDoc | CopilotContextFile>();
|
const hashMap = new Map<string, CopilotContextDoc | CopilotContextFile>();
|
||||||
let allDone = true;
|
const totalCount = docs.length + files.length;
|
||||||
|
let processingCount = 0;
|
||||||
docs.forEach(doc => {
|
docs.forEach(doc => {
|
||||||
hashMap.set(doc.id, doc);
|
hashMap.set(doc.id, doc);
|
||||||
if (doc.status === 'processing') {
|
if (doc.status === 'processing') {
|
||||||
allDone = false;
|
processingCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
hashMap.set(file.id, file);
|
hashMap.set(file.id, file);
|
||||||
if (file.status === 'processing') {
|
if (file.status === 'processing') {
|
||||||
allDone = false;
|
processingCount++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const nextChips = this.chatContextValue.chips.map(chip => {
|
const nextChips = this.chatContextValue.chips.map(chip => {
|
||||||
@@ -415,8 +414,9 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
});
|
});
|
||||||
this.updateContext({
|
this.updateContext({
|
||||||
chips: nextChips,
|
chips: nextChips,
|
||||||
|
embeddingProgress: [totalCount - processingCount, totalCount],
|
||||||
});
|
});
|
||||||
if (allDone) {
|
if (processingCount === 0) {
|
||||||
this._abortPoll();
|
this._abortPoll();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -544,10 +544,12 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
const style = styleMap({
|
const style = styleMap({
|
||||||
padding: width > 540 ? '8px 24px 0 24px' : '8px 12px 0 12px',
|
padding: width > 540 ? '8px 24px 0 24px' : '8px 12px 0 12px',
|
||||||
});
|
});
|
||||||
|
const [done, total] = this.chatContextValue.embeddingProgress;
|
||||||
|
const isEmbedding = total > 0 && done < total;
|
||||||
|
|
||||||
return html`<div class="chat-panel-container" style=${style}>
|
return html`<div class="chat-panel-container" style=${style}>
|
||||||
<div class="chat-panel-title">
|
<div class="chat-panel-title">
|
||||||
<div>AFFiNE AI</div>
|
<div>${isEmbedding ? `Embedding ${done}/${total}` : 'AFFiNE AI'}</div>
|
||||||
<div
|
<div
|
||||||
@click=${() => {
|
@click=${() => {
|
||||||
AIProvider.toggleGeneralAIOnboarding?.(true);
|
AIProvider.toggleGeneralAIOnboarding?.(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user