chat: remove Pi runner — route all chat/pipeline/channels through Claude

Stage 1 of removing Pi (Claude-only). Cuts the non-Claude branches in the chat
WS handler, pipeline executor, and channel send-and-await; deletes the Pi
sidecar, its ecosystem entry, pi-bridge, and the Pi model-listing spawn (now a
static Claude tier list). Adds a guard coercing any legacy non-claude-code model
preference to the Claude default so old settings don't break chat or jobs.
Removes the dead no-op session-save REST route and stale Pi docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 09:03:44 +00:00
co-authored by Claude Opus 4.8
parent fcdf5f0117
commit 63819fc25e
17 changed files with 55 additions and 3140 deletions
+1 -17
View File
@@ -1,7 +1,6 @@
import type { Context } from 'hono';
import { createRouter } from '../../create-router';
import * as storage from './storage';
import { readLocalProviders } from '../server-settings/pi-mono';
import { readSttConfig } from '../server-settings/stt';
import { listPiModels } from './list-models';
import { getHomeDirForRole } from '../../data-path';
@@ -12,19 +11,12 @@ import { getUserSettings } from 'officerdb';
export const piRestRouter = createRouter();
/**
* GET /api/pi/models
* GET /api/pi/models — Claude tiers only.
*/
piRestRouter.get('/pi/models', async (ctx: Context) => {
try {
const models = await listPiModels();
const providerNames: Record<string, string> = { 'claude-code': 'Claude Code' };
const localProviders = await readLocalProviders();
for (const lp of localProviders) {
providerNames[`officer-local-${lp.id}`] = lp.name;
}
logger.info('Models endpoint', { count: models.length, providers: [...new Set(models.map((m) => m.provider))] });
return ctx.json({ models, providerNames, hostHome: process.env.HOME ?? '' });
} catch (err) {
logger.error('Failed to list models', { error: String(err) });
@@ -57,14 +49,6 @@ piRestRouter.get('/pi/sessions/:sessionId', async (ctx: Context) => {
}
});
/**
* PUT /api/pi/sessions/:sessionId/messages
* No-op — sessions are persisted server-side via WebSocket events
*/
piRestRouter.put('/pi/sessions/:sessionId/messages', async (ctx: Context) => {
return ctx.json({ success: true });
});
/**
* POST /api/pi/stt
*/