ui: Stores architecture improvements (#26910)

* refactor: Stores barrel imports + SSR gates

* refactor: Drop agenticStore wrapper exports

* refactor: Drop chatStore wrapper exports

* refactor: Drop modelsStore wrapper exports

* refactor: Drop serverStore wrapper exports

* refactor: Drop unused mcpStore wrapper exports

* refactor: Drop mcpResourceStore wrapper exports

* refactor: Drop conversationsStore wrapper exports + move buildConversationTree to utils

* refactor: Drop settingsStore wrapper exports

* refactor: Drop unused toolsStore wrapper exports

* refactor: Fix lint errors from store wrapper removal

* fix: Missing change

* refactor: Cleanup

* refactor: Context Stats store
This commit is contained in:
Aleksander Grygier
2026-08-13 08:11:30 +02:00
committed by GitHub
parent a6040c925c
commit 094e53db1c
116 changed files with 937 additions and 945 deletions
+41 -72
View File
@@ -42,11 +42,12 @@ import { ChatService } from '$lib/services';
import { ReadMediaService } from '$lib/services/read-media.service';
import { SandboxService } from '$lib/services/sandbox.service';
import { ToolsService } from '$lib/services/tools.service';
// direct imports between stores, not via the barrel, to avoid circular deps
import { conversationsStore } from '$lib/stores/conversations.svelte';
import { mcpStore } from '$lib/stores/mcp.svelte';
import { modelsStore } from '$lib/stores/models.svelte';
import { permissionsStore } from '$lib/stores/permissions.svelte';
import { config } from '$lib/stores/settings.svelte';
import { settingsStore } from '$lib/stores/settings.svelte';
import { toolsStore } from '$lib/stores/tools.svelte';
import type {
AgenticConfig,
@@ -89,8 +90,10 @@ function createDefaultSession(): AgenticSession {
return {
currentTurn: 0,
executingToolCallId: null,
flowRootMessageId: null,
isRunning: false,
lastError: null,
liveLlm: null,
pendingPermissionRequest: null,
streamingToolCall: null,
totalToolCalls: 0
@@ -206,6 +209,16 @@ class AgenticStore {
return this._sessions.get(conversationId)?.isRunning ?? false;
}
// read-only: safe to call from derivations, unlike getSession
getLiveLlmTotals(conversationId: string): AgenticSession['liveLlm'] {
return this._sessions.get(conversationId)?.liveLlm ?? null;
}
// read-only: safe to call from derivations, unlike getSession
getFlowRootMessageId(conversationId: string): string | null {
return this._sessions.get(conversationId)?.flowRootMessageId ?? null;
}
currentTurn(conversationId: string): number {
return this._sessions.get(conversationId)?.currentTurn ?? 0;
}
@@ -419,7 +432,15 @@ class AgenticStore {
}
async runAgenticFlow(params: AgenticFlowParams): Promise<AgenticFlowResult> {
const { callbacks, conversationId, messages, options = {}, perChatOverrides, signal } = params;
const {
callbacks,
conversationId,
flowRootMessageId,
messages,
options = {},
perChatOverrides,
signal
} = params;
// Clear any pending permissions/continue requests for this conversation when starting a new flow
this._pendingPermissions.set(conversationId, null);
@@ -433,7 +454,7 @@ class AgenticStore {
await toolsStore.fetchBuiltinTools();
}
const agenticConfig = this.getConfig(config(), perChatOverrides);
const agenticConfig = this.getConfig(settingsStore.config, perChatOverrides);
if (!agenticConfig.enabled) return { handled: false };
@@ -478,8 +499,10 @@ class AgenticStore {
this.updateSession(conversationId, {
currentTurn: 0,
flowRootMessageId: flowRootMessageId ?? null,
isRunning: true,
lastError: null,
liveLlm: null,
totalToolCalls: 0
});
@@ -505,7 +528,11 @@ class AgenticStore {
return { error: normalizedError, handled: true };
} finally {
this.updateSession(conversationId, { isRunning: false });
this.updateSession(conversationId, {
flowRootMessageId: null,
isRunning: false,
liveLlm: null
});
if (hasMcpServers) {
await mcpStore
@@ -633,6 +660,16 @@ class AgenticStore {
if (timings) {
capturedTimings = timings;
turnTimings = timings;
// completed turns + in-flight turn live counts
this.updateSession(conversationId, {
liveLlm: {
predicted_ms: agenticTimings.llm.predicted_ms + (timings.predicted_ms ?? 0),
predicted_n: agenticTimings.llm.predicted_n + (timings.predicted_n ?? 0),
prompt_ms: agenticTimings.llm.prompt_ms + (timings.prompt_ms ?? 0),
prompt_n: agenticTimings.llm.prompt_n + (timings.prompt_n ?? 0)
}
});
}
},
onToolCallChunk: (serialized: string) => {
@@ -1157,71 +1194,3 @@ class AgenticStore {
}
export const agenticStore = new AgenticStore();
export function agenticIsRunning(conversationId: string) {
return agenticStore.isRunning(conversationId);
}
export function agenticCurrentTurn(conversationId: string) {
return agenticStore.currentTurn(conversationId);
}
export function agenticTotalToolCalls(conversationId: string) {
return agenticStore.totalToolCalls(conversationId);
}
export function agenticLastError(conversationId: string) {
return agenticStore.lastError(conversationId);
}
export function agenticStreamingToolCall(conversationId: string) {
return agenticStore.streamingToolCall(conversationId);
}
export function agenticPendingPermissionRequest(conversationId: string) {
return agenticStore.pendingPermissionRequest(conversationId);
}
export function agenticResolvePermission(conversationId: string, decision: ToolPermissionDecision) {
agenticStore.resolvePermission(conversationId, decision);
}
export function agenticPendingContinueRequest(conversationId: string) {
return agenticStore.pendingContinueRequest(conversationId);
}
export function agenticResolveContinue(conversationId: string, shouldContinue: boolean) {
agenticStore.resolveContinue(conversationId, shouldContinue);
}
export function agenticHasPendingSteeringMessage(conversationId: string) {
return agenticStore.hasPendingSteeringMessage(conversationId);
}
export function agenticInjectSteeringMessage(
conversationId: string,
content: string,
extras?: DatabaseMessageExtra[]
) {
agenticStore.injectSteeringMessage(conversationId, content, extras);
}
export function agenticPendingSteeringMessageContent(conversationId: string) {
return agenticStore.pendingSteeringMessageContent(conversationId);
}
export function agenticPendingSteeringMessageExtras(conversationId: string) {
return agenticStore.pendingSteeringMessageExtras(conversationId);
}
export function agenticClearSteeringMessage(conversationId: string) {
agenticStore.clearSteeringMessage(conversationId);
}
export function agenticIsAnyRunning() {
return agenticStore.isAnyRunning;
}
export function agenticExecutingToolCallId(conversationId: string) {
return agenticStore.executingToolCallId(conversationId);
}