feat(acp): replace raw config and secret methods (#9000)

Signed-off-by: Kalvin Chau <kalvin@block.xyz>
This commit is contained in:
Kalvin C
2026-05-04 18:24:28 -07:00
committed by GitHub
parent e82c4fdcb7
commit 2fe4c3d0bb
39 changed files with 1481 additions and 855 deletions
@@ -1,161 +0,0 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import {
cancelDictationLocalModelDownload,
deleteDictationLocalModel,
deleteDictationProviderSecret,
downloadDictationLocalModel,
getDictationConfig,
getDictationLocalModelDownloadProgress,
listDictationLocalModels,
saveDictationModelSelection,
saveDictationProviderSecret,
transcribeDictation,
} from "../dictation";
import { getClient } from "../acpConnection";
vi.mock("../acpConnection", () => ({
getClient: vi.fn(),
}));
describe("dictation SDK wiring", () => {
let client: { goose: Record<string, ReturnType<typeof vi.fn>> };
beforeEach(() => {
client = {
goose: {
GooseDictationConfig: vi.fn().mockResolvedValue({
providers: {
openai: {
configured: true,
description: "OpenAI transcription",
usesProviderConfig: true,
availableModels: [],
},
},
}),
GooseDictationTranscribe: vi.fn().mockResolvedValue({ text: "hello" }),
},
};
vi.mocked(getClient).mockResolvedValue(
client as unknown as Awaited<ReturnType<typeof getClient>>,
);
});
it("getDictationConfig calls GooseDictationConfig and returns providers map", async () => {
const result = await getDictationConfig();
expect(client.goose.GooseDictationConfig).toHaveBeenCalledWith({});
expect(result.openai.configured).toBe(true);
});
it("transcribeDictation forwards audio + mimeType + provider", async () => {
const result = await transcribeDictation({
audio: "base64==",
mimeType: "audio/webm",
provider: "openai",
});
expect(client.goose.GooseDictationTranscribe).toHaveBeenCalledWith({
audio: "base64==",
mimeType: "audio/webm",
provider: "openai",
});
expect(result.text).toBe("hello");
});
it("saveDictationModelSelection calls GooseDictationModelSelect", async () => {
client.goose.GooseDictationModelSelect = vi.fn().mockResolvedValue({});
await saveDictationModelSelection("local", "tiny");
expect(client.goose.GooseDictationModelSelect).toHaveBeenCalledWith({
provider: "local",
modelId: "tiny",
});
});
it("saveDictationProviderSecret calls GooseSecretUpsert", async () => {
client.goose.GooseSecretUpsert = vi.fn().mockResolvedValue({});
await saveDictationProviderSecret("groq", "gsk-test", "GROQ_API_KEY");
expect(client.goose.GooseSecretUpsert).toHaveBeenCalledWith({
key: "GROQ_API_KEY",
value: "gsk-test",
});
});
it("deleteDictationProviderSecret calls GooseSecretRemove", async () => {
client.goose.GooseSecretRemove = vi.fn().mockResolvedValue({});
await deleteDictationProviderSecret("groq", "GROQ_API_KEY");
expect(client.goose.GooseSecretRemove).toHaveBeenCalledWith({
key: "GROQ_API_KEY",
});
});
it("listDictationLocalModels returns the models array", async () => {
client.goose.GooseDictationModelsList = vi.fn().mockResolvedValue({
models: [
{
id: "tiny",
description: "Tiny",
sizeMb: 75,
downloaded: true,
downloadInProgress: false,
},
],
});
const result = await listDictationLocalModels();
expect(client.goose.GooseDictationModelsList).toHaveBeenCalledWith({});
expect(result).toHaveLength(1);
expect(result[0].id).toBe("tiny");
});
it("downloadDictationLocalModel forwards modelId", async () => {
client.goose.GooseDictationModelsDownload = vi.fn().mockResolvedValue({});
await downloadDictationLocalModel("tiny");
expect(client.goose.GooseDictationModelsDownload).toHaveBeenCalledWith({
modelId: "tiny",
});
});
it("getDictationLocalModelDownloadProgress returns progress or null", async () => {
client.goose.GooseDictationModelsDownloadProgress = vi
.fn()
.mockResolvedValue({
progress: {
bytesDownloaded: 100,
totalBytes: 1000,
progressPercent: 10,
status: "downloading",
error: null,
},
});
const result = await getDictationLocalModelDownloadProgress("tiny");
expect(result?.bytesDownloaded).toBe(100);
expect(
client.goose.GooseDictationModelsDownloadProgress,
).toHaveBeenCalledWith({
modelId: "tiny",
});
});
it("getDictationLocalModelDownloadProgress returns null when no download", async () => {
client.goose.GooseDictationModelsDownloadProgress = vi
.fn()
.mockResolvedValue({
progress: undefined,
});
const result = await getDictationLocalModelDownloadProgress("tiny");
expect(result).toBeNull();
});
it("cancelDictationLocalModelDownload forwards modelId", async () => {
client.goose.GooseDictationModelsCancel = vi.fn().mockResolvedValue({});
await cancelDictationLocalModelDownload("tiny");
expect(client.goose.GooseDictationModelsCancel).toHaveBeenCalledWith({
modelId: "tiny",
});
});
it("deleteDictationLocalModel forwards modelId", async () => {
client.goose.GooseDictationModelsDelete = vi.fn().mockResolvedValue({});
await deleteDictationLocalModel("tiny");
expect(client.goose.GooseDictationModelsDelete).toHaveBeenCalledWith({
modelId: "tiny",
});
});
});
+4 -12
View File
@@ -40,26 +40,18 @@ export async function saveDictationModelSelection(
}
export async function saveDictationProviderSecret(
_provider: DictationProvider,
provider: DictationProvider,
value: string,
configKey?: string,
): Promise<void> {
if (!configKey) {
throw new Error("No config key for this provider");
}
const client = await getClient();
await client.goose.GooseSecretUpsert({ key: configKey, value });
await client.goose.GooseDictationSecretSave({ provider, value });
}
export async function deleteDictationProviderSecret(
_provider: DictationProvider,
configKey?: string,
provider: DictationProvider,
): Promise<void> {
if (!configKey) {
throw new Error("Cannot delete secrets for this provider");
}
const client = await getClient();
await client.goose.GooseSecretRemove({ key: configKey });
await client.goose.GooseDictationSecretDelete({ provider });
}
export async function listDictationLocalModels(): Promise<
@@ -176,6 +176,9 @@
"addApiKey": "Add API key",
"updateApiKey": "Update API key",
"removeApiKey": "Remove API key",
"providerConfigLabel": "Provider credentials",
"providerConfigDescription": "This transcription provider uses the credentials from its model provider setup.",
"openProviders": "Open Providers",
"localModelLabel": "Local Whisper Model",
"localModelDescription": "Download a Whisper model to run transcription locally. Selecting a model sets it as your active local transcription model.",
"noLocalModels": "No local Whisper models available.",
@@ -176,6 +176,9 @@
"addApiKey": "Agregar clave API",
"updateApiKey": "Actualizar clave API",
"removeApiKey": "Eliminar clave API",
"providerConfigLabel": "Credenciales del proveedor",
"providerConfigDescription": "Este proveedor de transcripción usa las credenciales de la configuración de su proveedor de modelos.",
"openProviders": "Abrir proveedores",
"localModelLabel": "Modelo Whisper local",
"localModelDescription": "Descarga un modelo Whisper para transcribir localmente. Seleccionar un modelo lo establece como tu modelo de transcripción local activo.",
"noLocalModels": "No hay modelos Whisper locales disponibles.",