feat: Only send custom notifications when ACP client specifies this capability in the initialization request (#9596)

This commit is contained in:
Lifei Zhou
2026-06-05 08:39:59 +10:00
committed by GitHub
parent 6251e56347
commit ec519eeaaf
15 changed files with 306 additions and 103 deletions
+8
View File
@@ -0,0 +1,8 @@
import type { GooseMcpHostCapabilities } from "./mcp-apps.js";
export interface GooseClientCapabilitiesMeta {
goose?: {
mcpHostCapabilities?: GooseMcpHostCapabilities;
customNotifications?: boolean;
};
}
+16 -7
View File
@@ -733,28 +733,37 @@ export interface GooseExtNotifications {
) => Promise<void>;
}
export type GooseClientCallbacks = Client & GooseExtNotifications;
export type GooseClientCallbacks = Omit<Client, "extNotification"> &
Partial<Pick<Client, "extNotification">> &
GooseExtNotifications;
export function installGooseExtNotificationDispatcher(
callbacks: GooseClientCallbacks,
): Client {
const { unstable_sessionUpdate, ...rest } = callbacks;
const userExtNotification = rest.extNotification;
return {
...rest,
const dispatcher: Pick<Client, "extNotification"> = {
extNotification: async (method, params) => {
switch (method) {
case "_goose/unstable/session/update": {
const parsed = zGooseSessionNotification_unstable.parse(
params,
) as GooseSessionNotification_unstable;
await unstable_sessionUpdate?.(parsed);
await callbacks.unstable_sessionUpdate?.(parsed);
return;
}
default:
await userExtNotification?.(method, params);
await callbacks.extNotification?.(method, params);
return;
}
},
};
return new Proxy(callbacks, {
get(target, property) {
if (property === "extNotification") {
return dispatcher.extNotification;
}
const value = Reflect.get(target, property, target);
return typeof value === "function" ? value.bind(target) : value;
},
}) as Client;
}
+1
View File
@@ -6,6 +6,7 @@ export {
} from "./generated/client.gen.js";
export { GooseClient } from "./goose-client.js";
export { createHttpStream } from "./http-stream.js";
export * from "./client-capabilities.js";
export * from "./mcp-apps.js";
export {
-17
View File
@@ -1,7 +1,3 @@
import type {
Implementation,
InitializeRequest,
} from "@agentclientprotocol/sdk";
import { RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/app-bridge";
import type {
McpUiAppResourceConfig,
@@ -68,19 +64,6 @@ export interface GooseToolCallUpdateMeta {
[key: string]: unknown;
}
export interface GooseClientMeta {
goose: {
mcpHostCapabilities: GooseMcpHostCapabilities;
};
}
export type GooseInitializeRequest = InitializeRequest & {
clientCapabilities: NonNullable<InitializeRequest["clientCapabilities"]> & {
_meta: GooseClientMeta;
};
clientInfo: Implementation;
};
export const DEFAULT_GOOSE_MCP_HOST_CAPABILITIES: GooseMcpHostCapabilities = {
extensions: {
[GOOSE_MCP_UI_EXTENSION_ID]: {