Skip to content
Source
Sign inSign up
Open History to see the last commit

thread-provider-instance.ts

68 lines2.7 KB

1import { useMemo } from "react";
2​
3import type { EnvironmentThreadShell } from "@t3tools/client-runtime/state/shell";
4import {
5 normalizeProviderAccentColor,
6 resolveProviderInstanceDisplayName,
7 shouldShowInstanceBadge,
8} from "@t3tools/client-runtime/state/provider-instance-display";
9import type { EnvironmentId, ProviderDriverKind } from "@t3tools/contracts";
10​
11import type { ThreadListProvider } from "../../state/thread-list-environments";
12export interface ThreadRowProviderInstance {
13 readonly driverKind: ProviderDriverKind;
14 readonly displayName: string;
15 readonly accentColor?: string | undefined;
16 readonly showBadge: boolean;
18​
19/** Scope by environment; default instance ids name different accounts on different servers. */
20export function resolveThreadProviderInstance(
21 providers: ReadonlyArray<ThreadListProvider> | undefined,
22 thread: EnvironmentThreadShell,
23): ThreadRowProviderInstance | null {
24 if (providers === undefined) return null;
25 const instanceId = thread.runtime?.providerInstanceId ?? thread.modelSelection.instanceId;
26 const snapshot = providers.find((provider) => provider.instanceId === instanceId);
27 if (!snapshot) return null;
28 const entry = {
29 driverKind: snapshot.driver,
30 displayName: resolveProviderInstanceDisplayName(snapshot),
31 accentColor: normalizeProviderAccentColor(snapshot.accentColor),
32 };
33 return {
34 ...entry,
35 showBadge: shouldShowInstanceBadge(
36 { ...entry, enabled: snapshot.enabled },
37 providers.map((provider) => ({ driverKind: provider.driver, enabled: provider.enabled })),
38 ),
39 };
41​
42/** Cache per provider-list generation so fresh resolver objects cannot invalidate every memoized row. */
43export function createThreadRowProviderInstanceResolver(
44 providersByEnvironmentId: ReadonlyMap<EnvironmentId, ReadonlyArray<ThreadListProvider>>,
45): (thread: EnvironmentThreadShell) => ThreadRowProviderInstance | null {
46 const cache = new Map<string, ThreadRowProviderInstance | null>();
47 return (thread) => {
48 const instanceId = thread.runtime?.providerInstanceId ?? thread.modelSelection.instanceId;
49 const cacheKey = `${thread.environmentId}|${instanceId ?? ""}`;
50 const cached = cache.get(cacheKey);
51 if (cached !== undefined) return cached;
52 const resolved = resolveThreadProviderInstance(
53 providersByEnvironmentId.get(thread.environmentId),
54 thread,
55 );
56 cache.set(cacheKey, resolved);
57 return resolved;
58 };
60​
61export function useThreadRowProviderInstanceResolver(
62 providersByEnvironmentId: ReadonlyMap<EnvironmentId, ReadonlyArray<ThreadListProvider>>,
63): (thread: EnvironmentThreadShell) => ThreadRowProviderInstance | null {
64 return useMemo(
65 () => createThreadRowProviderInstanceResolver(providersByEnvironmentId),
66 [providersByEnvironmentId],
67 );