chat: point OpenCode at a fixed pm2-managed server (fixes empty model picker)
The per-cwd `opencode serve` spawning is replaced by a single fixed server (http://127.0.0.1:4096, OPENCODE_SERVER_URL) managed by pm2 — added as `officer-opencode` in ecosystem.config.cjs (cwd = home). Root-cause fix for the empty model selector: list-models shelled out to `opencode models`, which failed at runtime on the deployed server (the picker got only Claude tiers). It now reads the fixed server's GET /config/providers over HTTP — 11ms and reliable — so the curated OpenCode models (Big Pickle, Claude Haiku) show up. - server-manager.ts — drops spawning; exposes OPENCODE_SERVER_URL + a health check. - client.ts — createSession no longer binds a directory (sessions live in the one server's project). - send-opencode.ts / opencode-sessions.ts / chat.ts — use the fixed server; drop the cwd/home plumbing. Session list/load/delete/rename now hit :4096. Verified end-to-end against the live server: model list, streaming turn, session list, and transcript load all work with no spawning. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import { ensureServer } from '@@/api/chat/opencode/server-manager';
|
||||
import { getConnection } from '@@/api/chat/opencode/client';
|
||||
import { createEventMapper } from '@@/api/chat/opencode/event-mapper';
|
||||
import { getOpenCodeSession, setOpenCodeSession } from '@@/api/chat/opencode/state';
|
||||
import { getHomeDirForRole } from '../data-path';
|
||||
|
||||
// The OpenCode analog of send-claude-code.ts's streaming path. Drives a turn against a warm
|
||||
// `opencode serve` over HTTP + SSE, mapping events to the shared ChatEvent contract.
|
||||
@@ -34,22 +33,19 @@ function splitModel(model: string): { providerID: string; modelID: string } {
|
||||
}
|
||||
|
||||
export async function sendOpenCodeStreaming(params: OpenCodeStreamingParams): Promise<OpenCodeStreamingHandle> {
|
||||
const home = getHomeDirForRole(params.email, params.role ?? '');
|
||||
const cwd = params.cwd || home;
|
||||
|
||||
logger.info('OpenCode streaming exec', { sessionKey: params.sessionKey, model: params.model });
|
||||
|
||||
const { baseUrl } = await ensureServer(cwd, home);
|
||||
const { baseUrl } = await ensureServer();
|
||||
const conn = getConnection(baseUrl);
|
||||
|
||||
// Resolve the OpenCode session: a known mapping, or — when resuming from history — the sessionKey is
|
||||
// itself the OpenCode session id (`ses_…`); otherwise create one bound to the cwd.
|
||||
// itself the OpenCode session id (`ses_…`); otherwise create a new one.
|
||||
let opencodeSessionId =
|
||||
getOpenCodeSession(params.sessionKey) ??
|
||||
(params.sessionKey.startsWith('ses_') ? params.sessionKey : undefined) ??
|
||||
params.resumeSessionId;
|
||||
if (!opencodeSessionId) {
|
||||
opencodeSessionId = await conn.createSession(cwd);
|
||||
opencodeSessionId = await conn.createSession();
|
||||
}
|
||||
setOpenCodeSession(params.sessionKey, opencodeSessionId);
|
||||
const sessionId = opencodeSessionId;
|
||||
|
||||
Reference in New Issue
Block a user