Q172: disconnecting a provider shows what it stops, then the outcome

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-09 04:25:31 -04:00
1 parent 059970e7e1
commit 538d834647
12 files changed
+170 -1

No files matched your search

+1
View File
@@ -18,6 +18,7 @@ export const platformContracts = {
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>,
providerEndpoint: z.strictObject({ orgId: id, providerId: id }),
providerDisconnectImpact: z.strictObject({ orgId: id, providerId: id }),
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({
+8
View File
@@ -41,6 +41,7 @@ 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";
import { providerDisconnectImpact } from "../services/provider-disconnect-impact";
export interface IpcDeps {
connection: DatabaseConnection;
@@ -233,6 +234,13 @@ export function registerIpcHandlers(deps: IpcDeps): void {
return fail("provider_endpoint_failed", error instanceof Error ? error.message : String(error));
}
});
handle("providerDisconnectImpact", (input) => {
try {
return ok(providerDisconnectImpact(deps.connection.db, input.orgId, input.providerId));
} catch (error) {
return fail("provider_impact_failed", error instanceof Error ? error.message : String(error));
}
});
handle("setProviderModel", (input) => mutate(() => setProviderModel(deps.connection.db, input)));
handle("revokeProviderCredential", async (input) => {
try {
@@ -0,0 +1,14 @@
import type { DatabaseSync } from "node:sqlite";
import type { ProviderDisconnectImpact } from "../../shared/commands";
/** What disconnecting a provider stops: its agents cannot work, running sessions stop now, queued ones fail when they start. */
export function providerDisconnectImpact(db: DatabaseSync, orgId: string, providerId: string): ProviderDisconnectImpact {
if (!db.prepare("select 1 from providers where id = ? and org_id = ?").get(providerId, orgId)) throw new Error("Provider was not found.");
const agents = (db.prepare("select name from agents where org_id = ? and model_provider_id = ? and lifecycle = 'active' order by name").all(orgId, providerId) as Array<{ name: string }>).map((agent) => agent.name);
const openTasks = (db.prepare(`
select count(*) as n from tasks t join agents a on a.id = t.assignee_agent_id
where t.org_id = ? and a.model_provider_id = ? and a.lifecycle = 'active' and t.status <> 'done' and t.origin is null
`).get(orgId, providerId) as { n: number }).n;
const runs = (state: string) => (db.prepare("select count(*) as n from task_runs where org_id = ? and provider_id = ? and state = ?").get(orgId, providerId, state) as { n: number }).n;
return { agents, openTasks, runningRuns: runs("running"), queuedRuns: runs("queued") };
}