Q168: a connected provider's default model changes without its credential

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-09 03:55:55 -04:00
1 parent 26c3365896
commit 5cd413ffcf
12 files changed
+130 -2

No files matched your search

+1
View File
@@ -17,6 +17,7 @@ export const platformContracts = {
setIntegrationKey: z.strictObject({ name: z.enum(INTEGRATION_KEY_NAMES), value: z.string() }) satisfies z.ZodType<C.SetIntegrationKeyInput>,
clearIntegrationKey: z.strictObject({ name: z.enum(INTEGRATION_KEY_NAMES) }) satisfies z.ZodType<C.ClearIntegrationKeyInput>,
saveProviderCredential: z.strictObject({ orgId: id, providerId: id, secret: z.string(), model: z.string().nullable() }) satisfies z.ZodType<C.SaveProviderCredentialInput>,
setProviderModel: z.strictObject({ orgId: id, providerId: id, model: z.string().max(200) }) satisfies z.ZodType<C.SetProviderModelInput>,
revokeProviderCredential: z.strictObject({ orgId: id, providerId: id }) satisfies z.ZodType<C.RevokeProviderCredentialInput>,
startProviderOAuth: z.strictObject({
providerKey: z.string(), enterpriseDomain: z.string().nullable().optional(), orgId: id.optional(), providerId: id.optional(),
+2
View File
@@ -40,6 +40,7 @@ import { stopAllRuns, stopRun } from "../services/run-control";
import { cancelQueuedRun } from "../services/run-cancel";
import { runHistory } from "../services/run-history";
import { deleteWorkspace, setPrimaryWorkspace, updateWorkspace } from "../services/workspace-admin";
import { setProviderModel } from "../services/provider-default-model";
export interface IpcDeps {
connection: DatabaseConnection;
@@ -225,6 +226,7 @@ export function registerIpcHandlers(deps: IpcDeps): void {
handle("deleteMessage", (input) => mutate(() => chat.deleteMessage(input)));
handle("markChatSpaceRead", (input) => mutate(() => chat.markSpaceRead(input)));
handle("saveProviderCredential", (input) => mutate(() => providers.saveCredential(input)));
handle("setProviderModel", (input) => mutate(() => setProviderModel(deps.connection.db, input)));
handle("revokeProviderCredential", async (input) => {
try {
await providers.revokeCredential(input);
@@ -0,0 +1,17 @@
import type { DatabaseSync } from "node:sqlite";
import type { SetProviderModelInput } from "../../shared/commands";
import { AuditService } from "./audit-service";
/** Changes a connected provider's default model without touching its credential; sessions already started keep their pinned model. */
export function setProviderModel(db: DatabaseSync, input: SetProviderModelInput): void {
const provider = db.prepare("select provider_key, credential_id, model from providers where id = ? and org_id = ?")
.get(input.providerId, input.orgId) as { provider_key: string; credential_id: string | null; model: string | null } | undefined;
if (!provider) throw new Error("Provider was not found.");
const model = input.model.trim();
if (!model) throw new Error("Name the default model.");
if (!provider.credential_id) throw new Error("Connect this provider first; its default model is set when it connects.");
if (provider.provider_key === "azure-openai") throw new Error("Azure OpenAI calls the deployment saved with its credential; change the deployment under Manage.");
db.prepare("update providers set model = ? where id = ? and org_id = ?").run(model, input.providerId, input.orgId);
new AuditService(db).record({ orgId: input.orgId, entityType: "provider", entityId: input.providerId, actorType: "employee", actorId: null, action: "default_model_changed", payload: { from: provider.model, to: model } });
console.info(`[providers] ${provider.provider_key} default model: ${provider.model ?? "none"} -> ${model}`);
}