fix(04): wire pending approval notifications in IPC and API server paths
This commit is contained in:
1 parent
9d01a7acc4
commit
a2a110f0c5
5 files changed
+26
-2
No files matched your search
+11
-1
@@ -9,7 +9,7 @@ import { resolveApprovalDecision, shouldAutoApproveApproval } from "./approval-p
|
||||
import type { AppDatabase } from "./database";
|
||||
import { inferTaskType } from "./connector-matching";
|
||||
import { dispatchAgentMessage } from "./message-dispatch";
|
||||
import type { DesktopEvent } from "@shared/types";
|
||||
import type { DesktopEvent, SectionId } from "@shared/types";
|
||||
|
||||
/**
|
||||
* Decode an HTTP request body to a UTF-8 string, handling the common Windows
|
||||
@@ -78,6 +78,7 @@ export interface ApiServerEventCallbacks {
|
||||
onDocumentCreated: (companyId: string, authorAgentId: string | null, projectId: string | null) => void;
|
||||
onAutoAssignTask: (taskId: string, companyId: string) => string | null;
|
||||
emitEvent: (event: DesktopEvent) => void;
|
||||
notify: (options: { title: string; body: string; urgency: "critical" | "informational"; navigation?: { section: SectionId; entityId?: string }; batchKey?: string }) => void;
|
||||
}
|
||||
|
||||
export class AgentApiServer {
|
||||
@@ -114,6 +115,7 @@ export class AgentApiServer {
|
||||
onDocumentCreated: callbacks?.onDocumentCreated ?? (() => {}),
|
||||
onAutoAssignTask: callbacks?.onAutoAssignTask ?? (() => null),
|
||||
emitEvent: callbacks?.emitEvent ?? (() => {}),
|
||||
notify: callbacks?.notify ?? (() => {}),
|
||||
};
|
||||
this.registerRoutes();
|
||||
}
|
||||
@@ -1009,6 +1011,14 @@ export class AgentApiServer {
|
||||
detail: "Auto-approved by company policy",
|
||||
});
|
||||
log.info(`[auto-approve] Auto-approved approval ${id}: ${input.payloadSummary}`);
|
||||
} else {
|
||||
this.callbacks.notify({
|
||||
title: "Approval Required",
|
||||
body: input.payloadSummary ?? `${input.type} approval pending`,
|
||||
urgency: "critical",
|
||||
navigation: { section: "approvals", entityId: id },
|
||||
batchKey: "pending_approval",
|
||||
});
|
||||
}
|
||||
|
||||
this.onDomainChanged();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { createServiceGraph } from "./service-graph";
|
||||
import { createIpcSupport } from "./ipc-support";
|
||||
import { createNotificationService } from "./notification-service";
|
||||
import type { NotificationOptions } from "./notification-service";
|
||||
import type { DesktopEvent } from "@shared/types";
|
||||
import type { DesktopEvent, SectionId } from "@shared/types";
|
||||
|
||||
interface BootstrapApplicationDependencies {
|
||||
hasSingleInstanceLock: boolean;
|
||||
@@ -33,6 +33,7 @@ interface BootstrapApplicationDependencies {
|
||||
onDocumentCreated: (companyId: string, authorAgentId: string | null, projectId: string | null) => void;
|
||||
onAutoAssignTask: (taskId: string, companyId: string) => string | null;
|
||||
emitEvent: (event: DesktopEvent) => void;
|
||||
notify: (options: { title: string; body: string; urgency: "critical" | "informational"; navigation?: { section: SectionId; entityId?: string }; batchKey?: string }) => void;
|
||||
}, allowedOrigins: string[]) => AgentApiServer;
|
||||
createRunToken: (agentId: string, companyId: string, runId: string) => string;
|
||||
seedDefaultAutomationRules: (companyId: string) => void;
|
||||
@@ -168,6 +169,7 @@ export async function bootstrapApplication({
|
||||
},
|
||||
onAutoAssignTask: (taskId, companyId) => db.autoAssignTask(taskId, companyId),
|
||||
emitEvent,
|
||||
notify,
|
||||
}, [isDev && devServerUrl ? new URL(devServerUrl).origin : null, "app://-"].filter((origin): origin is string => Boolean(origin)));
|
||||
|
||||
apiServerRef.current = apiServer;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { IpcMainInvokeEvent } from "electron";
|
||||
import type { DesktopResult } from "@shared/contracts";
|
||||
import type { SectionId } from "@shared/types";
|
||||
import type { AppDatabase } from "./database";
|
||||
|
||||
export type CompanyScopedTable = "workspaces" | "agents" | "goals" | "projects" | "tasks" | "approvals" | "runs" | "secrets";
|
||||
@@ -30,6 +31,7 @@ export interface RegisterCoreHandlersDependencies {
|
||||
resetAfterRestore: () => void;
|
||||
getApiPort: () => number;
|
||||
listConnectorModels: (connectorId: string) => Promise<Array<{ id: string; label: string }>>;
|
||||
notify: (options: { title: string; body: string; urgency: "critical" | "informational"; navigation?: { section: SectionId; entityId?: string }; batchKey?: string }) => void;
|
||||
}
|
||||
|
||||
export function ok<T>(data: T): DesktopResult<T> {
|
||||
|
||||
@@ -25,6 +25,7 @@ export function registerCoreOperationHandlers({
|
||||
dispatchAutomation,
|
||||
queueTaskRun,
|
||||
getWorkerProcess,
|
||||
notify,
|
||||
}: Pick<
|
||||
RegisterCoreHandlersDependencies,
|
||||
| "registerHandle"
|
||||
@@ -37,6 +38,7 @@ export function registerCoreOperationHandlers({
|
||||
| "dispatchAutomation"
|
||||
| "queueTaskRun"
|
||||
| "getWorkerProcess"
|
||||
| "notify"
|
||||
>) {
|
||||
registerHandle(IPC_CHANNELS.requestApproval, async (_event, payload) => {
|
||||
const parsed = approvalInputSchema.parse(payload);
|
||||
@@ -81,6 +83,13 @@ export function registerCoreOperationHandlers({
|
||||
agentId: parsed.requestedByAgentId ?? undefined,
|
||||
taskId: parsed.relatedTaskId ?? undefined,
|
||||
});
|
||||
notify({
|
||||
title: "Approval Required",
|
||||
body: parsed.payloadSummary ?? `${parsed.type} approval pending`,
|
||||
urgency: "critical",
|
||||
navigation: { section: "approvals", entityId: id },
|
||||
batchKey: "pending_approval",
|
||||
});
|
||||
publishDomainChanged();
|
||||
return ok(id);
|
||||
});
|
||||
|
||||
@@ -145,6 +145,7 @@ export function createMainRuntimeSupport(state: MainRuntimeState) {
|
||||
requireBrowserActionService().resetBrowserManager();
|
||||
},
|
||||
getApiPort: () => state.apiServer?.getPort() ?? 0,
|
||||
notify: (options) => requireIpcSupport().notify(options),
|
||||
listConnectorModels: async (connectorId) => {
|
||||
const definition = getConnectorDefinition(connectorId as Parameters<typeof getConnectorDefinition>[0]);
|
||||
return definition.listModels ? definition.listModels() : [];
|
||||
|
||||
Reference in new issue
Block a user