This commit is contained in:
ZacharyZhang-NY committed 2026-03-30 00:15:21 -04:00
1 parent 65e85135c1
commit 6f1de8047e
64 files changed
+1269 -515

No files matched your search

+20 -1
View File
@@ -1955,6 +1955,24 @@ export class AppDatabase {
this.setSetting(`budget_reset_month_${companyId}`, month);
}
getDisabledModels(connectorId: string): Array<{ id: string; label: string }> {
const raw = this.getSetting(`disabled_models:${connectorId}`);
if (!raw) return [];
try {
return JSON.parse(raw);
} catch {
return raw.split(",").filter(Boolean).map((id) => ({ id, label: id }));
}
}
setDisabledModels(connectorId: string, models: Array<{ id: string; label: string }>) {
if (models.length === 0) {
this.db.prepare("delete from settings where key = ?").run(`disabled_models:${connectorId}`);
} else {
this.setSetting(`disabled_models:${connectorId}`, JSON.stringify(models));
}
}
listHeartbeatEligibleAgents(companyId: string): AgentRecord[] {
return this.readAll<AgentRecord>(
"select id, company_id as companyId, name, role, title, department, status, reports_to as reportsTo, connector_id as connectorId, workspace_id as workspaceId, model, capabilities, budget_monthly_usd as budgetMonthlyUsd, spent_monthly_usd as spentMonthlyUsd, metadata_json as metadataJson, heartbeat_enabled as heartbeatEnabled, heartbeat_interval_sec as heartbeatIntervalSec, last_heartbeat_at as lastHeartbeatAt, created_at as createdAt, updated_at as updatedAt from agents where company_id = ? and heartbeat_enabled = 1 and status not in ('terminated', 'paused', 'error', 'pending_approval')",
@@ -2351,7 +2369,8 @@ export class AppDatabase {
private seedConnectors() {
// Remove connector rows for adapters that have been removed from the codebase.
this.db.prepare("delete from connectors where id not in ('codex_local', 'claude_local', 'gemini_local')").run();
// Preserve native connectors and all claude_compat slots (user-configured API providers).
this.db.prepare("delete from connectors where id not in ('codex_local', 'claude_local', 'gemini_local') and id not like 'claude_compat%'").run();
const currentRows = this.readAll<Partial<ConnectorRecord>>(
"select id, label, description, status, command, version, auth_state as authState, last_checked_at as lastCheckedAt, last_error as lastError, model, env_binding_text as envBindingText, notes from connectors",
);
+8
View File
@@ -2,6 +2,7 @@ import { execSync } from "node:child_process";
import {
IPC_CHANNELS,
companyInputSchema,
connectorDisabledModelsSchema,
connectorInputSchema,
deleteEntitySchema,
openTerminalCommandSchema,
@@ -98,6 +99,13 @@ export function registerCoreAdminHandlers({
return ok(true);
});
registerHandle(IPC_CHANNELS.setConnectorDisabledModels, async (_event, payload) => {
const parsed = connectorDisabledModelsSchema.parse(payload);
db.setDisabledModels(parsed.connectorId, parsed.disabledModels);
publishDomainChanged();
return ok(true);
});
registerHandle(IPC_CHANNELS.saveSecret, async (_event, payload) => {
const parsed = secretInputSchema.parse(payload);
const companyError = ensureCompanyExists(parsed.companyId);
+9
View File
@@ -109,6 +109,15 @@ export function registerCoreReadHandlers({
}
});
registerHandle(IPC_CHANNELS.getConnectorDisabledModels, (_event, connectorId) => {
try {
const parsed = connectorInputSchema.shape.id.parse(connectorId);
return ok(db.getDisabledModels(parsed));
} catch {
return ok([]);
}
});
registerHandle(IPC_CHANNELS.getInbox, (_event, payload) => {
const companyId = z.string().uuid().parse(payload);
const err = ensureCompanyExists(companyId);
+6 -2
View File
@@ -148,15 +148,19 @@ export function createMainRuntimeSupport(state: MainRuntimeState) {
getApiPort: () => state.apiServer?.getPort() ?? 0,
notify: (options) => requireIpcSupport().notify(options),
listConnectorModels: async (connectorId) => {
const disabled = new Set(requireDb().getDisabledModels(connectorId).map((m) => m.id));
// For claude_compatible, return user-configured models from the DB
// (stored as comma-separated values in the connector's model field)
if (connectorId.startsWith("claude_compat")) {
const connector = requireDb().getConnector(connectorId);
const raw = connector.model ?? "";
return raw.split(",").map((m) => m.trim()).filter(Boolean).map((m) => ({ id: m, label: m }));
return raw.split(",").map((m) => m.trim()).filter(Boolean)
.filter((m) => !disabled.has(m))
.map((m) => ({ id: m, label: m }));
}
const definition = getConnectorDefinition(connectorId as Parameters<typeof getConnectorDefinition>[0]);
return definition.listModels ? definition.listModels() : [];
const models = definition.listModels ? await definition.listModels() : [];
return models.filter((m) => !disabled.has(m.id));
},
});