Manage skills as sources over ACP (#8675)
Co-authored-by: Lifei Zhou <lifei@squareup.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { getClient } from "@/shared/api/acpConnection";
|
||||
|
||||
export interface SkillInfo {
|
||||
name: string;
|
||||
@@ -7,20 +7,54 @@ export interface SkillInfo {
|
||||
path: string;
|
||||
}
|
||||
|
||||
// Shape returned by _goose/sources/*. Narrowed to skill-type sources here.
|
||||
interface SourceEntry {
|
||||
type: "skill";
|
||||
name: string;
|
||||
description: string;
|
||||
content: string;
|
||||
directory: string;
|
||||
global: boolean;
|
||||
}
|
||||
|
||||
function toSkillInfo(source: SourceEntry): SkillInfo {
|
||||
return {
|
||||
name: source.name,
|
||||
description: source.description,
|
||||
instructions: source.content,
|
||||
path: source.directory,
|
||||
};
|
||||
}
|
||||
|
||||
export async function createSkill(
|
||||
name: string,
|
||||
description: string,
|
||||
instructions: string,
|
||||
): Promise<void> {
|
||||
return invoke("create_skill", { name, description, instructions });
|
||||
const client = await getClient();
|
||||
await client.extMethod("_goose/sources/create", {
|
||||
type: "skill",
|
||||
name,
|
||||
description,
|
||||
content: instructions,
|
||||
global: true,
|
||||
});
|
||||
}
|
||||
|
||||
export async function listSkills(): Promise<SkillInfo[]> {
|
||||
return invoke("list_skills");
|
||||
const client = await getClient();
|
||||
const raw = await client.extMethod("_goose/sources/list", { type: "skill" });
|
||||
const sources = (raw.sources ?? []) as SourceEntry[];
|
||||
return sources.map(toSkillInfo);
|
||||
}
|
||||
|
||||
export async function deleteSkill(name: string): Promise<void> {
|
||||
return invoke("delete_skill", { name });
|
||||
const client = await getClient();
|
||||
await client.extMethod("_goose/sources/delete", {
|
||||
type: "skill",
|
||||
name,
|
||||
global: true,
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateSkill(
|
||||
@@ -28,21 +62,42 @@ export async function updateSkill(
|
||||
description: string,
|
||||
instructions: string,
|
||||
): Promise<SkillInfo> {
|
||||
return invoke("update_skill", { name, description, instructions });
|
||||
const client = await getClient();
|
||||
const raw = await client.extMethod("_goose/sources/update", {
|
||||
type: "skill",
|
||||
name,
|
||||
description,
|
||||
content: instructions,
|
||||
global: true,
|
||||
});
|
||||
return toSkillInfo(raw.source as SourceEntry);
|
||||
}
|
||||
|
||||
export async function exportSkill(
|
||||
name: string,
|
||||
): Promise<{ json: string; filename: string }> {
|
||||
return invoke("export_skill", { name });
|
||||
const client = await getClient();
|
||||
const raw = await client.extMethod("_goose/sources/export", {
|
||||
type: "skill",
|
||||
name,
|
||||
global: true,
|
||||
});
|
||||
return { json: raw.json as string, filename: raw.filename as string };
|
||||
}
|
||||
|
||||
export async function importSkills(
|
||||
fileBytes: number[],
|
||||
fileName: string,
|
||||
): Promise<SkillInfo[]> {
|
||||
return invoke("import_skills", {
|
||||
fileBytes: Array.from(fileBytes),
|
||||
fileName,
|
||||
if (!fileName.endsWith(".skill.json") && !fileName.endsWith(".json")) {
|
||||
throw new Error("File must have a .skill.json or .json extension");
|
||||
}
|
||||
const data = new TextDecoder().decode(new Uint8Array(fileBytes));
|
||||
const client = await getClient();
|
||||
const raw = await client.extMethod("_goose/sources/import", {
|
||||
data,
|
||||
global: true,
|
||||
});
|
||||
const sources = (raw.sources ?? []) as SourceEntry[];
|
||||
return sources.map(toSkillInfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user