SurfSense/surfsense_web/components/assistant-ui/token-usage-context.tsx
DESKTOP-RTLN3BA\$punk 656e061f84
Some checks are pending
Build and Push Docker Images / tag_release (push) Waiting to run
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (backend, surfsense-backend) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (web, surfsense-web) (push) Blocked by required conditions
feat: add processing mode support for document uploads and ETL pipeline, improded error handling ux
- Introduced a `ProcessingMode` enum to differentiate between basic and premium processing modes.
- Updated `EtlRequest` to include a `processing_mode` field, defaulting to basic.
- Enhanced ETL pipeline services to utilize the selected processing mode for Azure Document Intelligence and LlamaCloud parsing.
- Modified various routes and services to handle processing mode, affecting document upload and indexing tasks.
- Improved error handling and logging to include processing mode details.
- Added tests to validate processing mode functionality and its impact on ETL operations.
2026-04-14 21:26:00 -07:00

93 lines
2.3 KiB
TypeScript

"use client";
import {
createContext,
type FC,
type ReactNode,
useCallback,
useContext,
useSyncExternalStore,
} from "react";
export interface TokenUsageData {
prompt_tokens: number;
completion_tokens: number;
total_tokens: number;
usage?: Record<
string,
{ prompt_tokens: number; completion_tokens: number; total_tokens: number }
>;
model_breakdown?: Record<
string,
{ prompt_tokens: number; completion_tokens: number; total_tokens: number }
>;
}
type Listener = () => void;
class TokenUsageStore {
private data = new Map<string, TokenUsageData>();
private listeners = new Set<Listener>();
get(messageId: string): TokenUsageData | undefined {
return this.data.get(messageId);
}
set(messageId: string, usage: TokenUsageData): void {
this.data.set(messageId, usage);
this.notify();
}
rename(oldId: string, newId: string): void {
const usage = this.data.get(oldId);
if (usage) {
this.data.delete(oldId);
this.data.set(newId, usage);
this.notify();
}
}
clear(): void {
this.data.clear();
this.notify();
}
subscribe = (listener: Listener): (() => void) => {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
};
private notify(): void {
for (const l of this.listeners) l();
}
}
const TokenUsageContext = createContext<TokenUsageStore | null>(null);
export const TokenUsageProvider: FC<{ store: TokenUsageStore; children: ReactNode }> = ({
store,
children,
}) => <TokenUsageContext.Provider value={store}>{children}</TokenUsageContext.Provider>;
export function useTokenUsageStore(): TokenUsageStore {
const store = useContext(TokenUsageContext);
if (!store) throw new Error("useTokenUsageStore must be used within TokenUsageProvider");
return store;
}
export function useTokenUsage(messageId: string | undefined): TokenUsageData | undefined {
const store = useContext(TokenUsageContext);
const getSnapshot = useCallback(
() => (store && messageId ? store.get(messageId) : undefined),
[store, messageId]
);
const subscribe = useCallback(
(onStoreChange: () => void) => (store ? store.subscribe(onStoreChange) : () => {}),
[store]
);
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
}
export function createTokenUsageStore(): TokenUsageStore {
return new TokenUsageStore();
}