consortium
Version:
Remote control and session sharing CLI for AI coding agents
1,279 lines (1,273 loc) • 54.4 kB
JavaScript
import { render } from 'ink';
import React from 'react';
import { randomUUID } from 'node:crypto';
import { join } from 'node:path';
import { homedir } from 'node:os';
import { readdir, stat, readFile } from 'node:fs/promises';
import axios from 'axios';
import { l as logger, h as connectionState, A as ApiClient, r as readSettings, c as configuration, p as projectPath } from './types-DETLaopx.mjs';
import { c as createSessionMetadata } from './createSessionMetadata-I6-IgJ9q.mjs';
import { i as initialMachineMetadata, n as notifyDaemonSessionStarted, l as startConsortiumServer, M as MessageQueue2, h as hashObject, p as parseSpecialCommand, f as MessageBuffer, R as RemoteModeDisplay, m as startCaffeinate, j as getProvider, o as findOpencodeProvider, k as getProviderKeyViaDaemon, r as registerKillSessionHandler, s as stopCaffeinate } from './index-DiNLHtkZ.mjs';
import { s as setupOfflineReconnection } from './setupOfflineReconnection-DaGfrqRS.mjs';
import { p as parseOptionsFromText, f as formatOptionsXml, h as hasIncompleteOptions } from './optionsParser-2TzGtgao.mjs';
import { A as AcpBackend, r as resolveCapability } from './capabilities-DXXQ85k4.mjs';
import { r as resolveConsortiumCodeBinarySync } from './cliRouting-Bdz0xbc-.mjs';
import { D as DriveClient, S as ScratchDir, n as normalizeAttachmentEnvelope, a as attachmentsKillSwitchOff, A as AttachmentResolver } from './killSwitch-4ZtkkeeR.mjs';
import { B as BasePermissionHandler } from './BasePermissionHandler-DT5te0lc.mjs';
import 'chalk';
import 'fs';
import 'node:fs';
import 'node:events';
import 'socket.io-client';
import 'zod';
import 'tweetnacl';
import 'child_process';
import 'util';
import 'fs/promises';
import 'crypto';
import 'path';
import 'url';
import 'os';
import 'node:child_process';
import 'node:module';
import 'node:util';
import 'expo-server-sdk';
import 'node:readline';
import 'node:url';
import 'ps-list';
import 'cross-spawn';
import 'tmp';
import 'qrcode-terminal';
import 'open';
import 'fastify';
import 'fastify-type-provider-zod';
import 'http';
import '@modelcontextprotocol/sdk/client/index.js';
import '@modelcontextprotocol/sdk/client/streamableHttp.js';
import 'readline';
import '@modelcontextprotocol/sdk/server/mcp.js';
import 'node:http';
import '@modelcontextprotocol/sdk/server/streamableHttp.js';
import '@agentclientprotocol/sdk';
import 'libsodium-wrappers';
const CONSORTIUM_CODE_TIMEOUTS = {
/** OpenCode boots fast, but first run performs a SQLite migration. 60s is safe. */
init: 6e4,
/** Standard tool call timeout */
toolCall: 12e4,
/** Idle detection after last message chunk */
idle: 500
};
const STDERR_NOISE_PATTERNS = [
"Performing one time database migration",
"sqlite-migration:done",
"Database migration complete",
"Shell cwd was reset"
];
const UNSUPPORTED_SESSION_UPDATE_VARIANTS = /* @__PURE__ */ new Set([
"usage_update",
"available_commands_update"
]);
class ConsortiumCodeTransport {
agentName = "consortium-code";
getInitTimeout() {
return CONSORTIUM_CODE_TIMEOUTS.init;
}
getIdleTimeout() {
return CONSORTIUM_CODE_TIMEOUTS.idle;
}
getToolCallTimeout() {
return CONSORTIUM_CODE_TIMEOUTS.toolCall;
}
/**
* Defensive stdout filter. With `--log-level ERROR --pure` OpenCode's stdout
* is clean ACP JSON-RPC, but we still drop any non-JSON lines as a safety net
* (matches the pattern used by GeminiTransport).
*
* We also drop OpenCode-specific notification variants that the
* @agentclientprotocol/sdk validator doesn't know about — currently this is
* `session/update` notifications with `sessionUpdate: 'usage_update'` (token
* cost / context size info). Letting these reach the SDK causes a noisy
* `Error handling notification` log without affecting functionality. We drop
* them at the transport layer so the SDK never sees them.
*/
filterStdoutLine(line) {
const trimmed = line.trim();
if (!trimmed) {
return null;
}
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
return null;
}
let parsed;
try {
parsed = JSON.parse(trimmed);
} catch {
return null;
}
if (typeof parsed !== "object" || parsed === null) {
return null;
}
const msg = parsed;
if (msg.method === "session/update") {
const variant = msg.params?.update?.sessionUpdate;
if (variant && UNSUPPORTED_SESSION_UPDATE_VARIANTS.has(variant)) {
return null;
}
}
return line;
}
/**
* Handle OpenCode stderr output.
*
* - Migration / shutdown lifecycle messages: suppress entirely
* - Upstream provider rate limits (429): suppress (OpenCode handles retries)
* - 401 / auth errors: surface as a user-visible error
* - Everything else: pass through to logs without emitting a UI message
*/
handleStderr(text, _context) {
const trimmed = text.trim();
if (!trimmed) {
return { message: null, suppress: true };
}
for (const pattern of STDERR_NOISE_PATTERNS) {
if (trimmed.includes(pattern)) {
return { message: null, suppress: true };
}
}
if (trimmed.includes("status 429") || trimmed.includes('"code":429') || trimmed.includes("rate limit") || trimmed.includes("Rate limit")) {
return { message: null, suppress: false };
}
if (trimmed.includes("status 401") || trimmed.includes('"code":401') || trimmed.includes("Unauthorized") || trimmed.includes("authentication required")) {
const errorMessage = {
type: "status",
status: "error",
detail: "Consortium Code authentication failed. Run `opencode auth login` to configure a provider, or set OPENAI_BASE_URL to point at the Consortium proxy."
};
return { message: errorMessage };
}
return { message: null };
}
/**
* Tool patterns. Empty for now — OpenCode's tool IDs appear to follow the
* `tool_name-<id>` convention, so the default extractor in AcpBackend
* handles the common case. Add specific patterns here as we observe tools
* that need disambiguation.
*/
getToolPatterns() {
return [];
}
}
const consortiumCodeTransport = new ConsortiumCodeTransport();
function redactToken(token) {
if (!token) return "(none)";
if (token.length <= 8) return "***";
return token.slice(0, 4) + "..." + token.slice(-4);
}
function validateNoTokensInArgs(args) {
const sensitivePatterns = [
/^(sk-|pk-|key-|token-)/i,
/^eyJ/
// JWT prefix
];
for (const arg of args) {
for (const pattern of sensitivePatterns) {
if (pattern.test(arg)) {
throw new Error(
"Security: sensitive token detected in command arguments. Tokens must be passed via environment variables, not CLI args."
);
}
}
}
}
const SENSITIVE_KEYS = [
"CONSORTIUM_TOKEN",
"CONSORTIUM_PROXY_TOKEN",
"CONSORTIUM_ENCRYPTION_KEY",
"CONSORTIUM_SESSION_ID",
"CONSORTIUM_ENCRYPTION_VARIANT",
"OPENAI_API_KEY",
"ANTHROPIC_API_KEY",
"ANTHROPIC_AUTH_TOKEN",
"GEMINI_API_KEY",
"AZURE_OPENAI_API_KEY"
];
function safeEnvForLogging(env) {
const safe = {};
for (const [key, value] of Object.entries(env)) {
safe[key] = SENSITIVE_KEYS.includes(key) ? redactToken(value) : value;
}
return safe;
}
function isDirectZenModel(model) {
return model.startsWith("opencode/");
}
function createConsortiumCodeBackend(options) {
const pure = options.pure ?? true;
const logLevel = options.logLevel ?? "ERROR";
const useProxy = !!(options.proxyUrl && options.proxyTokens?.consortium);
const consortiumMode = options.consortiumMode ?? useProxy;
let command;
try {
command = resolveConsortiumCodeBinarySync();
} catch {
logger.debug("[ConsortiumCode] Failed to resolve bundled binary, falling back to PATH lookup");
command = consortiumMode ? "consortium-code" : "opencode";
}
const args = [
"acp",
"--log-level",
logLevel,
"--port",
"0",
"--cwd",
options.cwd
];
if (pure) args.push("--pure");
if (consortiumMode) args.push("--consortium-mode");
validateNoTokensInArgs(args);
const env = {
...options.env
};
const selectedModel = options.model ?? "opencode/big-pickle";
env.OPENCODE_MODEL = selectedModel;
const directZen = isDirectZenModel(selectedModel);
if (useProxy) {
const configuredModel = selectedModel.includes("/") ? selectedModel : `opencode/${selectedModel}`;
const tokens = options.proxyTokens;
const provider = {};
if (!directZen) {
provider.opencode = { options: { baseURL: `${options.proxyUrl}/v1/proxy/consortium`, apiKey: tokens.consortium } };
}
if (tokens.anthropic) provider.anthropic = { options: { baseURL: `${options.proxyUrl}/v1/proxy/anthropic`, apiKey: tokens.anthropic } };
if (tokens.openai) provider.openai = { options: { baseURL: `${options.proxyUrl}/v1/proxy/openai`, apiKey: tokens.openai } };
if (tokens.google) provider.google = { options: { baseURL: `${options.proxyUrl}/v1/proxy/google`, apiKey: tokens.google } };
if (tokens.zai) provider.zai = { options: { baseURL: `${options.proxyUrl}/v1/proxy/zai`, apiKey: tokens.zai } };
env.OPENCODE_CONFIG_CONTENT = JSON.stringify({ model: configuredModel, provider });
}
if (useProxy && !directZen) {
env.CONSORTIUM_PROXY_URL = `${options.proxyUrl}/v1/proxy/consortium`;
env.CONSORTIUM_PROXY_TOKEN = options.proxyTokens.consortium;
}
if (options.baseUrl) {
env.OPENAI_BASE_URL = options.baseUrl;
env.ANTHROPIC_BASE_URL = options.baseUrl;
}
if (options.apiKey) {
env.OPENAI_API_KEY = options.apiKey;
env.ANTHROPIC_API_KEY = options.apiKey;
}
const billingMode = directZen ? "direct-zen" : useProxy ? "proxy" : options.apiKey ? "byok" : "zen";
const backendOptions = {
agentName: "consortium-code",
cwd: options.cwd,
command,
args,
env,
mcpServers: options.mcpServers,
permissionHandler: options.permissionHandler,
transportHandler: consortiumCodeTransport
};
logger.debug("[ConsortiumCode] Creating ACP backend:", {
command,
billingMode,
cwd: backendOptions.cwd,
args: backendOptions.args,
model: options.model ?? "(default/zen)",
pure,
logLevel,
consortiumMode,
mcpServerCount: options.mcpServers ? Object.keys(options.mcpServers).length : 0,
env: safeEnvForLogging(env)
});
return new AcpBackend(backendOptions);
}
function isWriteLikeTool(toolName) {
const lower = toolName.toLowerCase();
if (lower === "other" || lower === "unknown tool" || lower === "unknown") return true;
const patterns = [
"edit",
"write",
"patch",
"delete",
"remove",
"create",
"mkdir",
"rename",
"move",
"copy",
"exec",
"bash",
"shell",
"run",
"terminal"
];
return patterns.some((p) => lower === p || lower.includes(p));
}
const ALWAYS_AUTO_APPROVE = ["change_title", "think", "save_memory"];
class ConsortiumCodePermissionHandler extends BasePermissionHandler {
currentPermissionMode = "default";
constructor(session) {
super(session);
}
getLogPrefix() {
return "[ConsortiumCode]";
}
updateSession(newSession) {
super.updateSession(newSession);
}
setPermissionMode(mode) {
this.currentPermissionMode = mode;
logger.debug(`${this.getLogPrefix()} Permission mode set to: ${mode}`);
}
shouldAutoApprove(toolName, toolCallId) {
if (ALWAYS_AUTO_APPROVE.some((n) => toolName.toLowerCase().includes(n))) return true;
if (ALWAYS_AUTO_APPROVE.some((n) => toolCallId.toLowerCase().includes(n))) return true;
switch (this.currentPermissionMode) {
case "yolo":
return true;
case "safe-yolo":
return !isWriteLikeTool(toolName);
case "read-only":
return !isWriteLikeTool(toolName);
default:
return false;
}
}
async handleToolCall(toolCallId, toolName, input) {
if (this.shouldAutoApprove(toolName, toolCallId)) {
const decision = this.currentPermissionMode === "yolo" ? "approved_for_session" : "approved";
logger.debug(`${this.getLogPrefix()} Auto-approving tool ${toolName} (${toolCallId}) in ${this.currentPermissionMode} mode`);
this.session.updateAgentState((currentState) => ({
...currentState,
completedRequests: {
...currentState.completedRequests,
[toolCallId]: {
tool: toolName,
arguments: input,
createdAt: Date.now(),
completedAt: Date.now(),
status: "approved",
decision
}
}
}));
return { decision };
}
const defaultOnTimeout = isWriteLikeTool(toolName) ? "denied" : "approved";
return this.createPendingRequest(toolCallId, toolName, input, { defaultOnTimeout });
}
}
async function runConsortiumCode(opts) {
connectionState.setBackend("ConsortiumCode");
logger.debug(`[ConsortiumCode] Starting: startedBy=${opts.startedBy || "terminal"}`);
let session;
let permissionHandler;
let isProcessingMessage = false;
let pendingSessionSwap = null;
const applyPendingSessionSwap = () => {
if (pendingSessionSwap) {
logger.debug("[ConsortiumCode] Applying pending session swap");
session = pendingSessionSwap;
permissionHandler.updateSession(pendingSessionSwap);
pendingSessionSwap = null;
}
};
const api = await ApiClient.create(opts.credentials);
if (opts.existingSession) {
session = opts.existingSession;
} else {
const sessionTag = opts.resumeTag ?? randomUUID();
const settings = await readSettings();
const machineId = settings?.machineId;
if (!machineId) {
console.error("[START] No machine ID found. Run consortium auth to set up.");
process.exit(1);
}
await api.getOrCreateMachine({ machineId, metadata: initialMachineMetadata });
const { state, metadata } = createSessionMetadata({
flavor: "consortium-code",
machineId,
startedBy: opts.startedBy
});
const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
const { session: initialSession } = setupOfflineReconnection({
api,
sessionTag,
metadata,
state,
response,
onSessionSwap: (newSession) => {
if (isProcessingMessage) {
logger.debug("[ConsortiumCode] Session swap queued (processing in progress)");
pendingSessionSwap = newSession;
} else {
session = newSession;
permissionHandler.updateSession(newSession);
}
}
});
session = initialSession;
if (response) {
try {
const result = await notifyDaemonSessionStarted(response.id, metadata);
if (result.error) {
logger.debug("[ConsortiumCode] Failed to report to daemon:", result.error);
}
} catch (error) {
logger.debug("[ConsortiumCode] Failed to report to daemon:", error);
}
}
}
const consortiumServer = await startConsortiumServer(session, {
sendArtifact: (msg) => session.sendAgentMessage("consortium-code", msg)
});
permissionHandler = new ConsortiumCodePermissionHandler(session);
let driveClient = null;
if (opts.credentials.encryption?.type === "dataKey") {
driveClient = new DriveClient(
opts.credentials.token,
{ x25519SecretKey: opts.credentials.encryption.machineKey }
);
}
const scratchDir = new ScratchDir(session.sessionId, { workspaceDir: process.cwd() });
const attachmentResolver = driveClient ? new AttachmentResolver(driveClient, scratchDir) : null;
const pendingMessageLocalIds = [];
const pendingDriveNodeRefs = [];
const pendingAttachmentIds = [];
const messageQueue = opts.messageQueue ?? new MessageQueue2((mode) => hashObject({
permissionMode: mode.permissionMode,
model: mode.model
}));
let currentPermissionMode = void 0;
let currentModel = void 0;
let currentBackendModel = void 0;
let hasStoredFirstMessage = false;
let isFirstMessage = true;
session.onUserMessage((message) => {
const text = message.content.text;
const env = normalizeAttachmentEnvelope(message);
if (driveClient && env.driveId && env.driveDek) {
try {
driveClient.setKnownDek(env.driveId, new Uint8Array(Buffer.from(env.driveDek, "base64")));
} catch (err) {
logger.debug("[ConsortiumCode] setKnownDek failed:", err);
}
}
if (env.messageLocalId) pendingMessageLocalIds.push(env.messageLocalId);
if (env.driveId && env.driveNodeIds.length > 0) {
pendingDriveNodeRefs.push({ driveId: env.driveId, nodeIds: env.driveNodeIds });
}
if (env.bindingOnlyNodeIds.length > 0) {
pendingAttachmentIds.push(...env.bindingOnlyNodeIds);
}
if (!hasStoredFirstMessage && text) {
hasStoredFirstMessage = true;
session.updateMetadata((m) => ({ ...m, firstMessage: text.substring(0, 100) }));
}
if (message.meta?.permissionMode) {
const validModes = ["default", "read-only", "safe-yolo", "yolo"];
if (validModes.includes(message.meta.permissionMode)) {
currentPermissionMode = message.meta.permissionMode;
permissionHandler.setPermissionMode(currentPermissionMode);
}
}
if (currentPermissionMode === void 0) {
currentPermissionMode = "default";
permissionHandler.setPermissionMode("default");
}
if (message.meta?.hasOwnProperty("model")) {
if (message.meta.model === null) {
currentModel = void 0;
} else if (message.meta.model) {
currentModel = message.meta.model;
}
}
let fullPrompt = text;
if (isFirstMessage && message.meta?.appendSystemPrompt) {
fullPrompt = message.meta.appendSystemPrompt + "\n\n" + text;
}
isFirstMessage = false;
const mode = {
permissionMode: currentPermissionMode || "default",
model: currentModel
};
const special = parseSpecialCommand(text);
if (special.type === "clear") {
messageQueue.pushIsolateAndClear(fullPrompt, mode);
} else {
messageQueue.push(fullPrompt, mode);
}
});
const messageBuffer = opts.messageBuffer ?? new MessageBuffer();
const hasTTY = process.stdout.isTTY && process.stdin.isTTY;
let inkInstance = null;
if (hasTTY) {
console.clear();
inkInstance = render(React.createElement(RemoteModeDisplay, {
messageBuffer,
logPath: process.env.DEBUG ? logger.logFilePath : void 0,
onExit: async () => {
shouldExit = true;
await handleAbort();
},
onSwitchToLocal: () => {
logger.debug("[ConsortiumCode] Switching to local mode via double-space");
switchToLocal = true;
shouldExit = true;
handleAbort();
}
}), { exitOnCtrlC: false, patchConsole: false });
}
const agent = "consortium-code";
let thinking = false;
let shouldExit = false;
let switchToLocal = false;
let abortController = new AbortController();
let acpSessionId = null;
let backend = null;
let currentModeHash = null;
let accumulatedText = "";
let turnStartMs = 0;
let emptyIndicatorTimer = null;
const EMPTY_INDICATOR_DELAY_MS = 2500;
const cancelEmptyIndicator = () => {
if (emptyIndicatorTimer) {
clearTimeout(emptyIndicatorTimer);
emptyIndicatorTimer = null;
}
};
let sendPromptInFlight = false;
const OPTIONS_MARKER = "<options";
const HOLDBACK_LEN = OPTIONS_MARKER.length - 1;
let streamBuffer = "";
let streamFlushTimer = null;
const STREAM_FLUSH_MS = 600;
const STREAM_FLUSH_CHARS = 1500;
let turnFinalized = true;
let watchdog = null;
const WATCHDOG_MS = 24e4;
const clearWatchdog = () => {
if (watchdog) {
clearTimeout(watchdog);
watchdog = null;
}
};
const resetWatchdog = () => {
clearWatchdog();
if (!turnFinalized && sendPromptInFlight) {
watchdog = setTimeout(() => {
logger.debug("[ConsortiumCode] turn stalled (no backend activity for 90s); forcing finalize");
finalizeTurn("watchdog");
}, WATCHDOG_MS);
}
};
const startTurn = () => {
turnFinalized = false;
accumulatedText = "";
streamBuffer = "";
turnStartMs = Date.now();
if (streamFlushTimer) {
clearTimeout(streamFlushTimer);
streamFlushTimer = null;
}
cancelEmptyIndicator();
sendPromptInFlight = true;
resetWatchdog();
};
const readLatestOpencodeError = async () => {
try {
const logDir = join(homedir(), ".local/share/opencode/log");
const entries = await readdir(logDir).catch(() => []);
let bestPath = null;
let bestMtime = 0;
for (const name of entries) {
if (!name.endsWith(".log")) continue;
const path = join(logDir, name);
const s = await stat(path).catch(() => null);
if (!s) continue;
if (s.mtimeMs < turnStartMs - 2e3) continue;
if (s.mtimeMs > bestMtime) {
bestMtime = s.mtimeMs;
bestPath = path;
}
}
if (!bestPath) return null;
const body = await readFile(bestPath, "utf8").catch(() => null);
if (!body) return null;
const lines = body.split("\n");
for (let i = lines.length - 1; i >= 0; i--) {
const line = lines[i];
if (!line.includes("ERROR") || !line.includes("service=llm")) continue;
const msgMatch = line.match(/"message":"((?:[^"\\]|\\.)*)"/);
const statusMatch = line.match(/"statusCode":(\d+)/);
const message = msgMatch?.[1]?.replace(/\\"/g, '"').replace(/\\\\/g, "\\") ?? null;
const status = statusMatch?.[1] ?? null;
if (message) {
return status ? `HTTP ${status}: ${message}` : message;
}
}
return null;
} catch {
return null;
}
};
const finalizeTurn = (reason) => {
if (turnFinalized) return;
turnFinalized = true;
clearWatchdog();
flushStreamBuffer();
try {
const tail = streamBuffer;
streamBuffer = "";
let finalMessage = tail;
const markerIdx = tail.indexOf(OPTIONS_MARKER);
if (markerIdx !== -1) {
const pre = tail.slice(0, markerIdx);
const rest = tail.slice(markerIdx);
const { text: optionsText, options } = parseOptionsFromText(rest);
if (options.length > 0) {
finalMessage = pre + optionsText + formatOptionsXml(options);
logger.debug(`[ConsortiumCode] Found ${options.length} options in response:`, options);
} else if (hasIncompleteOptions(rest)) {
logger.debug("[ConsortiumCode] Warning: Incomplete options block detected");
finalMessage = pre + rest;
}
}
if (finalMessage.trim()) {
session.sendAgentMessage(agent, {
type: "message",
message: finalMessage,
id: randomUUID()
});
} else if (!accumulatedText.trim() && reason !== "error" && reason !== "watchdog") {
cancelEmptyIndicator();
emptyIndicatorTimer = setTimeout(() => {
emptyIndicatorTimer = null;
if (accumulatedText.trim().length > 0 || streamBuffer.length > 0) return;
session.sendAgentMessage(agent, {
type: "message",
message: "_(model returned no output \u2014 checking Consortium logs for details\u2026)_",
id: randomUUID()
});
readLatestOpencodeError().then((detail) => {
if (!detail) return;
session.sendAgentMessage(agent, {
type: "message",
message: `_(model error \u2014 ${detail})_`,
id: randomUUID()
});
}).catch(() => {
});
}, EMPTY_INDICATOR_DELAY_MS);
}
} catch (e) {
logger.debug("[ConsortiumCode] turn finalize flush failed:", e);
}
if (streamFlushTimer) {
clearTimeout(streamFlushTimer);
streamFlushTimer = null;
}
session.sendAgentMessage(agent, { type: "task_complete", id: randomUUID() });
thinking = false;
session.keepAlive(thinking, "remote");
logger.debug(`[ConsortiumCode] turn finalized via ${reason}`);
};
const flushStreamBuffer = () => {
if (streamFlushTimer) {
clearTimeout(streamFlushTimer);
streamFlushTimer = null;
}
if (!streamBuffer) return;
let cutAt = streamBuffer.length;
const optIdx = streamBuffer.indexOf(OPTIONS_MARKER);
if (optIdx !== -1) cutAt = optIdx;
if (cutAt === streamBuffer.length && cutAt > HOLDBACK_LEN) {
cutAt -= HOLDBACK_LEN;
}
const lookbackStart = Math.max(0, cutAt - 400);
const lastBreak = streamBuffer.lastIndexOf("\n\n", cutAt);
if (lastBreak >= lookbackStart) cutAt = lastBreak + 2;
if (cutAt <= 0) return;
const chunk = streamBuffer.slice(0, cutAt);
streamBuffer = streamBuffer.slice(cutAt);
if (!chunk) return;
session.sendAgentMessage(agent, {
type: "message",
message: chunk,
id: randomUUID()
});
};
const streamModelChunk = (chunk) => {
if (!chunk) return;
cancelEmptyIndicator();
messageBuffer.addMessage(chunk, "assistant");
resetWatchdog();
if (sendPromptInFlight) accumulatedText += chunk;
streamBuffer += chunk;
if (streamBuffer.length >= STREAM_FLUSH_CHARS) {
flushStreamBuffer();
} else if (!streamFlushTimer) {
streamFlushTimer = setTimeout(flushStreamBuffer, STREAM_FLUSH_MS);
}
};
session.keepAlive(thinking, "remote");
const keepAliveInterval = setInterval(() => {
if (!shouldExit) session.keepAlive(thinking, "remote");
}, 2e3);
session.updateAgentState((state) => ({ ...state, controlledByUser: false }));
startCaffeinate();
const sendReady = () => {
session.sendSessionEvent({ type: "ready" });
try {
api.push().sendToAllDevices(
"It's ready!",
"Consortium Code is waiting for your command",
{ sessionId: session.sessionId }
);
} catch (pushError) {
logger.debug("[ConsortiumCode] Failed to send ready push", pushError);
}
};
const spawnModelId = process.env.OPENCODE_MODEL || "opencode/big-pickle";
const byokProviderEnv = process.env.CONSORTIUM_CODE_BYOK_PROVIDER;
const byokFlag = process.env.CONSORTIUM_CODE_BYOK === "1";
function inferProviderFromModel(id) {
if (id.startsWith("custom:")) {
const rest = id.slice("custom:".length);
const ci = rest.indexOf(":");
return ci > 0 ? `custom:${rest.slice(0, ci)}` : `custom:${rest}`;
}
if (id.includes(":")) return id.slice(0, id.indexOf(":"));
if (id.includes("/")) return id.split("/")[0];
return void 0;
}
const inferredScope = inferProviderFromModel(spawnModelId);
const byokProviderId = byokProviderEnv ?? (byokFlag && inferredScope && inferredScope !== "opencode" && inferredScope !== "consortium" ? inferredScope : void 0);
let byokActive = false;
if (byokProviderId && byokProviderId !== "consortium") {
const providerEntry = getProvider("consortium-code", byokProviderId);
const opencodeEntry = findOpencodeProvider(byokProviderId);
const envVarFromEnv = process.env.CONSORTIUM_CODE_BYOK_ENV_VAR;
const envVar = providerEntry?.keyEnvVar ?? opencodeEntry?.env?.[0] ?? envVarFromEnv;
if (envVar) {
const existing = process.env[envVar];
let resolvedKey = existing && existing.length > 0 ? existing : null;
if (!resolvedKey) {
try {
resolvedKey = await getProviderKeyViaDaemon(byokProviderId);
} catch (err) {
logger.debug(`[ConsortiumCode] BYOK getProviderKeyViaDaemon(${byokProviderId}) threw:`, err);
}
}
if (resolvedKey) {
process.env[envVar] = resolvedKey;
delete process.env.OPENAI_BASE_URL;
delete process.env.ANTHROPIC_BASE_URL;
byokActive = true;
const modelTail = (() => {
if (spawnModelId.startsWith("custom:")) {
const rest = spawnModelId.slice("custom:".length);
const ci = rest.indexOf(":");
return ci > 0 ? rest.slice(ci + 1) : "";
}
if (spawnModelId.includes(":")) return spawnModelId.slice(spawnModelId.indexOf(":") + 1);
if (spawnModelId.includes("/")) return spawnModelId.split("/").slice(1).join("/");
return spawnModelId;
})();
const opencodeModelId = `${byokProviderId}/${modelTail}`;
const customBaseURL = process.env.CONSORTIUM_CODE_BYOK_BASE_URL;
const config = { model: opencodeModelId };
if (byokProviderId.startsWith("custom:")) {
if (customBaseURL && modelTail) {
config.provider = {
[byokProviderId]: {
npm: "@ai-sdk/openai-compatible",
options: { baseURL: customBaseURL, apiKey: resolvedKey },
models: { [modelTail]: {} }
}
};
}
} else if (modelTail) {
config.provider = {
[byokProviderId]: {
options: { apiKey: resolvedKey },
models: { [modelTail]: {} }
}
};
}
process.env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
logger.debug(`[ConsortiumCode] BYOK active for provider=${byokProviderId} envVar=${envVar} model=${opencodeModelId}; bypassing Consortium proxy mint.`);
} else {
logger.warn(`[ConsortiumCode] BYOK requested for provider=${byokProviderId} but no key found in env or daemon keystore; falling back to proxy path.`);
}
} else {
logger.warn(`[ConsortiumCode] BYOK requested for unknown provider=${byokProviderId}; falling back to proxy path.`);
}
}
const isFreeSlug = spawnModelId.startsWith("opencode/") || spawnModelId.startsWith("consortium/");
const PROVIDER_SCOPES = ["consortium", "anthropic", "openai", "google", "zai"];
const scopesToMint = isFreeSlug ? ["consortium"] : PROVIDER_SCOPES;
let consortiumProxyUrl = process.env.CONSORTIUM_PROXY_URL;
let proxyTokens;
const extractAxiosError = (reason) => {
const data = reason?.response?.data;
const status = reason?.response?.status;
const fromData = data?.error || data?.message;
const body = typeof fromData === "string" ? fromData : fromData ? JSON.stringify(fromData) : void 0;
const base = body || reason?.message || String(reason);
return status ? `${status} ${base}` : base;
};
const extractStructuredError = (reason) => {
const data = reason?.response?.data;
const code = typeof data?.error === "string" && data.error || typeof data?.code === "string" && data.code || reason?.code && String(reason.code) || "mint_failed";
const message = typeof data?.message === "string" && data.message || typeof data?.error === "string" && data.error || reason?.message || String(reason);
return { code, message };
};
const mintResults = byokActive ? [] : await Promise.allSettled(scopesToMint.map((providerId) => axios.post(
`${configuration.serverUrl}/v1/billing/proxy-token`,
{ providerId, sessionId: session.sessionId, usageMode: "consortium-code" },
{ headers: { Authorization: `Bearer ${opts.credentials.token}` }, timeout: 1e4 }
)));
const failed = [];
const scopeErrors = {};
const tokens = {};
let firstProxyBaseUrl;
let anyNetworkSucceeded = false;
mintResults.forEach((result, idx) => {
const scope = scopesToMint[idx];
if (result.status === "fulfilled") {
anyNetworkSucceeded = true;
const data = result.value.data;
if (data?.token && data?.proxyBaseUrl) {
tokens[scope] = data.token;
if (!firstProxyBaseUrl) {
firstProxyBaseUrl = String(data.proxyBaseUrl).replace(/\/v1\/proxy\/[^/]+$/, "");
}
} else {
failed.push(`${scope}: empty response`);
scopeErrors[scope] = { code: "empty_response", message: "Server returned no token" };
}
} else {
failed.push(`${scope}: ${extractAxiosError(result.reason)}`);
scopeErrors[scope] = extractStructuredError(result.reason);
}
});
if (byokActive) {
logger.debug("[ConsortiumCode] BYOK mode \u2014 skipping proxy mint + wallet preview.");
} else if (failed.length === 0 && tokens.consortium) {
proxyTokens = tokens;
if (firstProxyBaseUrl) consortiumProxyUrl = firstProxyBaseUrl;
logger.debug(`[ConsortiumCode] Acquired proxy tokens (${scopesToMint.length} provider${scopesToMint.length === 1 ? "" : "s"}) for session ${session.sessionId}`);
const desiredModel = process.env.OPENCODE_MODEL;
if (desiredModel) {
const [scope, ...rest] = desiredModel.split("/");
const bareModelId = rest.length > 0 ? rest.join("/") : scope;
const overrideProvider = rest.length === 0 || scope === "opencode" ? "consortium" : scope;
try {
await axios.post(
`${configuration.serverUrl}/v1/proxy/model`,
{ providerId: overrideProvider, modelId: bareModelId },
{ headers: { Authorization: `Bearer ${opts.credentials.token}` }, timeout: 5e3 }
);
logger.debug(`[ConsortiumCode] Set proxy model override ${overrideProvider}/${bareModelId} for session ${session.sessionId}`);
} catch (err) {
logger.warn(`[ConsortiumCode] setModelOverride failed (binary may silently fall back to big-pickle): ${err?.message ?? err}`);
}
}
} else if (!anyNetworkSucceeded) {
const envTokens = {
consortium: process.env.CONSORTIUM_PROXY_TOKEN_CONSORTIUM ?? process.env.CONSORTIUM_PROXY_TOKEN,
anthropic: process.env.CONSORTIUM_PROXY_TOKEN_ANTHROPIC,
openai: process.env.CONSORTIUM_PROXY_TOKEN_OPENAI,
google: process.env.CONSORTIUM_PROXY_TOKEN_GOOGLE,
zai: process.env.CONSORTIUM_PROXY_TOKEN_ZAI
};
const haveAllPaid = !!(envTokens.consortium && envTokens.anthropic && envTokens.openai && envTokens.google && envTokens.zai);
const haveJustConsortium = !!envTokens.consortium;
if (isFreeSlug && haveJustConsortium || haveAllPaid) {
proxyTokens = {
consortium: envTokens.consortium,
...envTokens.anthropic ? { anthropic: envTokens.anthropic } : {},
...envTokens.openai ? { openai: envTokens.openai } : {},
...envTokens.google ? { google: envTokens.google } : {},
...envTokens.zai ? { zai: envTokens.zai } : {}
};
logger.warn(`[ConsortiumCode] Proxy-token mint failed (network); using CONSORTIUM_PROXY_TOKEN_* env-var fallback.`);
} else {
const consortiumError = scopeErrors.consortium ?? { code: "network_error", message: failed.join("; ") };
logger.warn(`[ConsortiumCode] Failed to mint proxy tokens for providers: ${failed.join("; ")}. Aborting (no upstream-Zen fallback).`);
try {
session.sendSessionEvent({
type: "message",
message: `Cannot start session with ${spawnModelId}: ${consortiumError.message}`,
errorCode: consortiumError.code,
scope: "consortium"
});
} catch {
}
const err = new Error(`mint_failed:consortium:${consortiumError.code}:${consortiumError.message}`);
err.mintFailed = {
scope: "consortium",
errorCode: consortiumError.code,
message: consortiumError.message
};
throw err;
}
} else if (isFreeSlug && !tokens.consortium) {
const consortiumError = scopeErrors.consortium ?? { code: "mint_failed", message: failed.join("; ") };
logger.warn(`[ConsortiumCode] Consortium-scope mint failed for free session (code=${consortiumError.code}): ${consortiumError.message}. No upstream-Zen fallback \u2014 refusing spawn.`);
try {
session.sendSessionEvent({
type: "message",
message: `Cannot start session with ${spawnModelId}: ${consortiumError.message}`,
// Pass structured fields verbatim so the app can route to the
// right billing/upgrade UI without re-parsing strings.
errorCode: consortiumError.code,
scope: "consortium"
});
} catch {
}
const err = new Error(`mint_failed:consortium:${consortiumError.code}:${consortiumError.message}`);
err.mintFailed = {
scope: "consortium",
errorCode: consortiumError.code,
message: consortiumError.message
};
throw err;
} else if (!isFreeSlug && tokens.consortium) {
proxyTokens = tokens;
if (firstProxyBaseUrl) consortiumProxyUrl = firstProxyBaseUrl;
logger.warn(`[ConsortiumCode] Partial proxy-token mint (${failed.join("; ")}); paid native providers without tokens are unavailable this session.`);
} else {
const consortiumError = scopeErrors.consortium ?? { code: "mint_failed", message: failed.join("; ") };
logger.warn(`[ConsortiumCode] Failed to mint proxy tokens for providers: ${failed.join("; ")}`);
try {
session.sendSessionEvent({
type: "message",
message: `Cannot start session with ${spawnModelId}: ${consortiumError.message}`,
errorCode: consortiumError.code,
scope: "consortium"
});
} catch {
}
const err = new Error(`mint_failed:consortium:${consortiumError.code}:${consortiumError.message}`);
err.mintFailed = {
scope: "consortium",
errorCode: consortiumError.code,
message: consortiumError.message
};
throw err;
}
if (!byokActive && spawnModelId !== "opencode/big-pickle" && spawnModelId.includes("/")) {
const [providerScope, ...rest] = spawnModelId.split("/");
const bareModelId = rest.join("/");
try {
const previewRes = await axios.get(`${configuration.serverUrl}/v1/billing/wallet-preview`, {
params: { providerId: providerScope, modelId: bareModelId },
headers: { Authorization: `Bearer ${opts.credentials.token}` },
timeout: 7e3,
validateStatus: () => true
});
const data = previewRes.data ?? {};
if (previewRes.status === 200 && data.ok === false) {
const reason = data.code;
const friendly = reason === "insufficient_credits" ? `Your workspace needs credits to use ${spawnModelId}. Required ~${data.requiredCents}\xA2, available ${data.availableCents}\xA2.` : reason === "no_managed_key" ? `${providerScope} is not currently provisioned with a managed key on this server. Contact your operator.` : `Could not resolve a billable organization for this account.`;
logger.warn(`[ConsortiumCode] Wallet preview blocked spawn for ${spawnModelId}: ${reason}`);
try {
session.sendSessionEvent({
type: "message",
message: `Cannot start session with ${spawnModelId}: ${friendly}`
});
} catch {
}
throw new Error(`wallet_preview_blocked:${reason}:${spawnModelId}`);
}
} catch (err) {
if (typeof err?.message === "string" && err.message.startsWith("wallet_preview_blocked:")) {
throw err;
}
logger.debug(`[ConsortiumCode] Wallet preview check skipped: ${err?.message ?? err}`);
}
}
const ensureBackend = async (model) => {
if (backend) {
try {
await backend.dispose();
} catch {
}
backend = null;
acpSessionId = null;
}
const envModel = model || process.env.OPENCODE_MODEL;
const envApiKey = process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY;
const envBaseUrl = process.env.OPENAI_BASE_URL || process.env.ANTHROPIC_BASE_URL;
const proxyUrl = consortiumProxyUrl;
currentBackendModel = envModel ? envModel.includes("/") ? envModel : `opencode/${envModel}` : "opencode/big-pickle";
backend = createConsortiumCodeBackend({
cwd: process.cwd(),
model: envModel,
apiKey: envApiKey,
baseUrl: envBaseUrl,
proxyUrl,
proxyTokens,
// TEMP: DEBUG-level logging so we can see what the binary's
// consortium provider does when resolving consortium/big-pickle.
// Without this, "log-level ERROR" hides the catalog-fetch and
// model-resolution failures we're trying to diagnose. Drop to
// ERROR before production.
logLevel: "DEBUG",
permissionHandler,
mcpServers: {
consortium: {
command: join(projectPath(), "bin", "consortium-mcp.mjs"),
args: ["--url", consortiumServer.url]
}
}
});
backend.setScratchDir?.(scratchDir);
backend.setAttachmentCapability?.(resolveCapability("consortium-code", currentModel ?? null));
backend.onMessage((msg) => {
try {
resetWatchdog();
switch (msg.type) {
case "model-output": {
const chunk = msg.textDelta ?? msg.fullText ?? "";
streamModelChunk(chunk);
break;
}
case "status":
resetWatchdog();
if (msg.status === "running") {
thinking = true;
session.keepAlive(thinking, "remote");
} else if (msg.status === "idle" || msg.status === "stopped") {
if (accumulatedText.trim().length > 0) {
finalizeTurn("backendIdle");
} else {
logger.debug("[ConsortiumCode] backend idle with empty accumulatedText \u2014 deferring finalize to sendPromptResolved/watchdog");
}
} else if (msg.status === "error") {
const detail = typeof msg.detail === "object" ? JSON.stringify(msg.detail) : msg.detail ?? "unknown";
session.sendAgentMessage(agent, {
type: "message",
message: `Error: ${detail}`,
id: randomUUID()
});
messageBuffer.addMessage(`Error: ${detail}`, "status");
finalizeTurn("error");
}
break;
case "tool-call":
session.sendAgentMessage(agent, {
type: "tool-call",
name: msg.toolName,
callId: msg.callId,
input: msg.args,
id: randomUUID()
});
messageBuffer.addMessage(`Executing: ${msg.toolName}`, "tool");
break;
case "tool-result":
session.sendAgentMessage(agent, {
type: "tool-result",
callId: msg.callId,
output: msg.result,
id: randomUUID()
});
break;
case "fs-edit":
session.sendAgentMessage(agent, {
type: "file-edit",
description: msg.description,
diff: msg.diff,
filePath: msg.path ?? "unknown",
id: randomUUID()
});
messageBuffer.addMessage(`Edit: ${msg.path ?? "file"}`, "tool");
break;
case "terminal-output":
session.sendAgentMessage(agent, {
type: "terminal-output",
data: msg.data,
callId: msg.callId ?? randomUUID()
});
break;
case "permission-request":
session.sendAgentMessage(agent, msg);
break;
case "inline-media":
(async () => {
try {
const m = msg;
const bytes = Uint8Array.from(Buffer.from(m.base64, "base64"));
const uploaded = await session.uploadArtifact({ bytes, mime: m.mime });
session.sendAgentMessage(agent, {
type: "artifact",
artifactId: uploaded.id,
mime: uploaded.mime,
name: m.name,
sizeBytes: uploaded.sizeBytes,
id: randomUUID()
});
} catch (err) {
logger.debug("[consortium-code] inline-media upload failed:", err);
}
})();
break;
default:
logger.debug("[ConsortiumCode] Unhandled message type:", msg.type);
break;
}
} catch (err) {
logger.debug("[ConsortiumCode] Error forwarding message:", err);
}
});
const resumeSessionId = process.env.CONSORTIUM_CODE_RESUME_SESSION_ID;
if (resumeSessionId) {
delete process.env.CONSORTIUM_CODE_RESUME_SESSION_ID;
}
try {
let result;
if (resumeSessionId && typeof backend.loadSession === "function") {
logger.debug(`[ConsortiumCode] Resuming ACP session: ${resumeSessionId}`);
result = await backend.loadSession(resumeSessionId);
} else {
result = await backend.startSession();
}
acpSessionId = result.sessionId;
logger.debug(`[ConsortiumCode] ACP session ${resumeSessionId ? "loaded" : "started"}: ${acpSessionId}`);
session.updateMetadata((m) => ({ ...m, agentSessionId: acpSessionId ?? void 0 }));
} catch (err) {
logger.debug("[ConsortiumCode] Failed to start/load session:", err);
throw err;
}
return backend;
};
const handleAbort = async () => {
logger.debug("[ConsortiumCode] Abort requested");
session.sendAgentMessage(agent, { type: "turn_aborted", id: randomUUID() });
permissionHandler.reset();
messageQueue.reset();
try {
abortController.abort();
abortController = new AbortController();
if (acpSessionId && backend) await backend.cancel(acpSessionId);
} catch (err) {
logger.debug("[ConsortiumCode] Error during abort:", err);
}
};
const handleKillSession = async () => {
logger.debug("[ConsortiumCode] Kill session requested");
shouldExit = true;
await handleAbort();
try {
session.updateMetadata((m) => ({
...m,
lifecycleState: "archived",
lifecycleStateSince: Date.now(),
archivedBy: "cli",
archiveReason: "User terminated"
}));
session.sendSessionDeath();
await session.flush();
await session.close();
} catch (err) {
logger.debug("[ConsortiumCode] Error closing session:", err);
} finally {
clearInterval(keepAliveInterval);
stopCaffeinate();
consortiumServer.stop();
if (backend) try {
await backend.dispose();
} catch {
}
inkInstance?.unmount();
if (!opts.existingSession) {
process.exit(0);
}
}
};
session.rpcHandlerManager.registerHandler("abort", handleAbort);
registerKillSessionHandler(session.rpcHandlerManager, handleKillSession);
if (!hasTTY) {
console.log(" Consortium Code \u2014 waiting for prompts from the mobile app...");
console.log(" (Press Ctrl+C to exit)");
console.log("");
}
try {
while (!shouldExit) {
applyPendingSessionSwap();
const batch = await messageQueue.waitForMessagesAndGetAsString(abortController.signal);
if (!batch) {
if (abortController.signal.aborted && !shouldExit) continue;
break;
}
isProcessingMessage = true;
messageBuffer.addMessage(batch.message.substring(0, 200), "user");
const special = parseSpecialCommand(batch.message);
if (special.type === "clear") {
messageBuffer.addMessage("Resetting session...", "status");
if (backend) try {
await backend.dispose();
} catch {
}
backend = null;
acpSessionId = null;
currentModeHash = null;
permissionHandler.reset();
thinking = false;
session.keepAlive(thinking, "remote");
messageBuffer.addMessage("Session reset.", "status");
isProcessingMessage = false;
sendReady();
continue;
}
if (currentModeHash && batch.hash !== currentModeHash) {
logger.debug(`[ConsortiumCode] Mode hash changed: ${currentModeHash} \u2192 ${batch.hash}`);
permissionHandler.setPermissionMode(batch.mode.permissionMode);
}
currentModeHash = batch.hash;
thinking = true;
session.keepAlive(thinking, "remote");
session.sendAgentMessage(agent, { type: "task_started", id: randomUUID() });
const requestedModel = batch.mode.model;
const requestedFull = requestedModel ? requestedModel.includes("/") ? requestedModel : `opencode/${requestedModel}` : void 0;
if (backend && acpSessionId) {
if (requestedFull && requestedFull !== currentBackendModel) {
try {
await backend.setSessionModel(requestedFull);
const [scope, ...rest] = requestedFull.split("/");
const bareModelId = rest.join("/");
const overrideProvider = scope === "opencode" ? "consortium" : scope;
axios.post(
`${configuration.serverUrl}/v1/proxy/model`,
{ providerId: overrideProvider, modelId: bareModelId },
{ headers: { Authorization: `Bearer ${opts.credentials.token}` }, timeout: 5e3 }
).catch((err) => logger.warn(`[ConsortiumCode] in-session setModelOverride failed: ${err?.message ?? err}`));
currentBackendModel = requestedFull;
logger.debug(`[ConsortiumCode] Switched session model to ${requestedFull} (context preserved)`);
} catch (err) {
logger.warn(`[ConsortiumCode] setSessionModel failed (${err}); respawning backend`);
if (backend) try {
await backend.dispose();
} catch {
}
backend = null;
acpSessionId = null;
try {
await ensureBackend(requestedModel);
} catch (rebuildErr) {
logger.debug("[ConsortiumCode] Failed to rebuild backend after setSessionModel failure:", rebuildErr);
session.sendAgentMessage(agent, {
type: "message",
message: `Error switching model: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}`,
id: randomUUID()
});
thinking = false;
session.keepAlive(thinking, "remote");
session.sendAgentMessage(agent, { type: "task_complete", id: randomUUID() });
isProcessingMessage = false;
sendReady();
continue;
}