fix: compatibility of config extension acp call in TUI (#9683)

This commit is contained in:
Lifei Zhou
2026-06-09 12:57:31 +10:00
committed by GitHub
parent e5fd568e01
commit 8eb6cd60d6
+67 -17
View File
@@ -1,7 +1,12 @@
import React, { useCallback, useEffect, useState } from "react";
import { Box, Text, useInput, useStdout } from "ink";
import { TextInput } from "@inkjs/ui";
import type { GooseClient } from "@aaif/goose-sdk";
import type {
GooseClient,
GooseExtension,
GooseExtensionEntry,
McpServerStdio,
} from "@aaif/goose-sdk";
import {
CRANBERRY,
GOLD,
@@ -21,17 +26,63 @@ type ExtEntry = {
[key: string]: unknown;
};
function isExtEntry(v: unknown): v is ExtEntry {
return (
!!v &&
typeof v === "object" &&
"enabled" in v &&
"type" in v &&
"name" in v &&
typeof (v as ExtEntry).enabled === "boolean" &&
typeof (v as ExtEntry).type === "string" &&
typeof (v as ExtEntry).name === "string"
);
function entryToExtEntry(entry: GooseExtensionEntry): ExtEntry | null {
const ext = entry.extension;
if (ext.type !== "mcp") {
return {
enabled: entry.enabled,
type: ext.type,
name: ext.name,
description: ext.description ?? "",
display_name: ext.display_name ?? null,
timeout: "timeout" in ext ? (ext.timeout ?? null) : null,
bundled: ext.bundled ?? null,
};
}
const server = ext.server;
if ("type" in server && server.type === "sse") return null;
const common = {
enabled: entry.enabled,
description: ext.description ?? "",
env_keys: ext.envKeys ?? [],
timeout: ext.timeout ?? null,
bundled: ext.bundled ?? null,
};
if ("type" in server && server.type === "http") {
return {
...common,
type: "streamable_http",
name: server.name,
uri: server.url,
headers: Object.fromEntries(
(server.headers ?? []).map((h) => [h.name, h.value]),
),
socket: ext.socket ?? null,
};
}
const stdio = server as McpServerStdio;
return {
...common,
type: "stdio",
name: stdio.name,
cmd: stdio.command,
args: stdio.args,
};
}
function toGooseExtension(e: ExtEntry): GooseExtension {
if (e.type === "streamable_http") {
return {
type: "mcp",
server: { type: "http", name: e.name, url: String(e.uri ?? ""), headers: [] },
description: e.description || undefined,
};
}
return {
type: "mcp",
server: { name: e.name, command: String(e.cmd ?? ""), args: (e.args as string[]) ?? [], env: [] },
description: e.description || undefined,
};
}
type AddType = "stdio" | "streamable_http";
@@ -126,9 +177,9 @@ export default function ExtensionsManager({
client.goose.sessionExtensionsList_unstable({ sessionId }),
]);
const allExtensions = (configResp.extensions as unknown[]).filter(
isExtEntry,
);
const allExtensions = (configResp.extensions as GooseExtensionEntry[])
.map(entryToExtEntry)
.filter((e): e is ExtEntry => e !== null);
const activeNames = new Set(
(sessionResp.extensions as Array<{ name?: string }>).map((e) => e.name),
);
@@ -188,8 +239,7 @@ export default function ExtensionsManager({
const config = buildConfig(addType, addValue, addName, description);
withSaving(async () => {
await client.goose.configExtensionsAdd_unstable({
name: config.name,
extensionConfig: config as any,
extension: toGooseExtension(config),
enabled: true,
});
await client.goose.sessionExtensionsAdd_unstable({