chat: rename the pi chat transport + model list to chat (Stage 4b/1)

Pure rename, no behavior change. Moves the misnamed "pi" chat harness into the
chat namespace:

- api/pi/{websocket,session-manager,types,logger,list-models} → api/chat/
- merge api/pi/rest.ts into api/chat/chat.ts (/pi/models → /chat/models,
  /pi/stt → /chat/stt); drop the piRestRouter mount
- PiEvent → ChatEvent, piWebsocket → chatWebsocket, listPiModels → listChatModels
- WS route /api/pi/chat/ws → /api/chat/ws, provider tag 'pi' → 'chat'
- frontend: useChat/useAudioRecording URLs, usePiModels→useModels /
  useVisiblePiModels→useVisibleModels / useEnabledPiModels→useEnabledModels,
  'PI_MODELS' query key → 'CHAT_MODELS', attachments provider 'pi-mono' → 'chat'

The /pi-mono provider/harness settings router is renamed separately (next commit).
Note: the WS route change requires the mobile app to point at /api/chat/ws.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 15:47:40 +00:00
co-authored by Claude Opus 4.8
parent 70555c8d71
commit 49df1c0b0c
31 changed files with 119 additions and 129 deletions
@@ -22,7 +22,7 @@ export function useAttachments(params?: UseAttachmentsParams) {
const res = await client.post<{ url: string; title: string; content: string; attachmentId: string }>('/scrape', {
url,
...(params?.sessionId ? { sessionId: params.sessionId } : {}),
provider: 'pi-mono',
provider: 'chat',
});
setAttachments((prev) =>
prev.map((a, i) =>
@@ -48,7 +48,7 @@ export function useAttachments(params?: UseAttachmentsParams) {
const formData = new FormData();
formData.append('file', file);
if (params?.sessionId) formData.append('sessionId', params.sessionId);
formData.append('provider', 'pi-mono');
formData.append('provider', 'chat');
const res = await client.post<{ filename: string; dataUrl: string; attachmentId: string }>('/upload', formData);
setAttachments((prev) =>
@@ -47,7 +47,7 @@ export function useAudioRecording(onTranscription: (text: string) => void) {
formData.append('response_format', 'json');
const token = localStorage.getItem('BEARER_TOKEN') ?? sessionStorage.getItem('BEARER_TOKEN');
const res = await fetch('/api/pi/stt', {
const res = await fetch('/api/chat/stt', {
method: 'POST',
body: formData,
headers: token ? { Authorization: `Bearer ${token}` } : {},
@@ -80,7 +80,7 @@ export function useChat(initialSessionId?: string, initialModel?: string | null,
const token = localStorage.getItem('BEARER_TOKEN');
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const wsUrl = `${protocol}//${window.location.host}/api/pi/chat/ws?token=${token}`;
const wsUrl = `${protocol}//${window.location.host}/api/chat/chat/ws?token=${token}`;
function flushStreaming() {
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
+1 -1
View File
@@ -2,7 +2,7 @@ export { useSettings, DEFAULT_SETTINGS } from './useSettings';
export type { UseSettingsType, UserSettings, UserState } from './useSettings';
export { useUserState } from './useUserState';
export { useDashboardState } from './useDashboardState';
export { usePiModels, useVisiblePiModels, useUserVisibleModels, useEnabledPiModels, modelKey } from './useModels';
export { useModels, useVisibleModels, useUserVisibleModels, useEnabledModels, modelKey } from './useModels';
export type { ModelOption } from './useModels';
export { useAccessPolicy } from './useAccessPolicy';
export { useClaudeSessions, useChatPwds } from './useClaudeSessions';
+9 -9
View File
@@ -23,19 +23,19 @@ export function getHostHome(): string {
return globalHostHome;
}
export function usePiModels() {
export function useModels() {
const client = useClient();
const { isAuthenticated } = useAuth();
const { data: models = [] } = useQuery<ModelOption[]>({
queryKey: ['PI_MODELS'],
queryKey: ['CHAT_MODELS'],
enabled: isAuthenticated,
queryFn: async () => {
const data = await client.get<{
models: ModelOption[];
providerNames?: Record<string, string>;
hostHome?: string;
}>('/pi/models');
}>('/chat/models');
if (data.providerNames) {
globalProviderNames = data.providerNames;
@@ -54,8 +54,8 @@ export function usePiModels() {
}
/** Filter models by system-wide access policy. New providers pass through. */
export function useVisiblePiModels() {
const models = usePiModels();
export function useVisibleModels() {
const models = useModels();
const { policy } = useAccessPolicy();
const allowed = policy.allowedModels;
@@ -74,8 +74,8 @@ export function useVisiblePiModels() {
/** Models visible to the current user: system policy (members) or all (admins), minus per-user hidden. */
export function useUserVisibleModels() {
const allModels = usePiModels();
const policyModels = useVisiblePiModels();
const allModels = useModels();
const policyModels = useVisibleModels();
const { user } = useAuth();
const { settings } = useSettings();
@@ -90,8 +90,8 @@ export function useUserVisibleModels() {
}
/** Strict filtering — only explicitly allowed models, no "new provider" passthrough. */
export function useEnabledPiModels() {
const models = usePiModels();
export function useEnabledModels() {
const models = useModels();
const { policy } = useAccessPolicy();
const allowed = policy.allowedModels;