feat(ui): use acp method to load skills (#9959)
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
import type { SourceEntry, SourceType } from '@aaif/goose-sdk';
|
||||
import { getAcpClient } from './acpConnection';
|
||||
|
||||
const SKILL_SOURCE_TYPES: SourceType[] = ['skill', 'builtinSkill'];
|
||||
const inFlightSkillSourceLoads = new Map<string, Promise<SourceEntry[]>>();
|
||||
|
||||
export async function listSkillSources(projectDir: string): Promise<SourceEntry[]> {
|
||||
const inFlightLoad = inFlightSkillSourceLoads.get(projectDir);
|
||||
if (inFlightLoad) {
|
||||
return inFlightLoad;
|
||||
}
|
||||
|
||||
const load = loadSkillSources(projectDir);
|
||||
inFlightSkillSourceLoads.set(projectDir, load);
|
||||
|
||||
try {
|
||||
return await load;
|
||||
} finally {
|
||||
if (inFlightSkillSourceLoads.get(projectDir) === load) {
|
||||
inFlightSkillSourceLoads.delete(projectDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSkillSources(projectDir: string): Promise<SourceEntry[]> {
|
||||
const client = await getAcpClient();
|
||||
const responses = await Promise.all(
|
||||
SKILL_SOURCE_TYPES.map((type) =>
|
||||
client.goose.sourcesList_unstable({
|
||||
type,
|
||||
projectDir,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
return responses
|
||||
.flatMap((response) => response.sources)
|
||||
.sort(
|
||||
(a, b) =>
|
||||
a.name.localeCompare(b.name, undefined, { sensitivity: 'base' }) ||
|
||||
a.path.localeCompare(b.path)
|
||||
);
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import { Card } from '../ui/card';
|
||||
import { Button } from '../ui/button';
|
||||
import { Skeleton } from '../ui/skeleton';
|
||||
import { MainPanelLayout } from '../Layout/MainPanelLayout';
|
||||
import { getSlashCommands } from '../../api';
|
||||
import { errorMessage } from '../../utils/conversionUtils';
|
||||
import { getInitialWorkingDir } from '../../utils/workingDir';
|
||||
import { defineMessages, useIntl } from '../../i18n';
|
||||
import { SearchView } from '../conversation/SearchView';
|
||||
import { getSearchShortcutText } from '../../utils/keyboardShortcuts';
|
||||
import { listSkillSources } from '../../acp/sources';
|
||||
|
||||
const i18n = defineMessages({
|
||||
errorLoadingSkills: {
|
||||
@@ -118,16 +118,11 @@ export default function SkillsView() {
|
||||
setShowSkeleton(true);
|
||||
setShowContent(false);
|
||||
setError(null);
|
||||
const response = await getSlashCommands({
|
||||
query: { working_dir: getInitialWorkingDir() },
|
||||
throwOnError: true,
|
||||
});
|
||||
const skillEntries: SkillEntry[] = (response.data?.commands ?? [])
|
||||
.filter((cmd) => cmd.command_type === 'Skill')
|
||||
.map((cmd) => ({
|
||||
name: cmd.command,
|
||||
description: cmd.help,
|
||||
}));
|
||||
const sources = await listSkillSources(getInitialWorkingDir());
|
||||
const skillEntries: SkillEntry[] = sources.map((source) => ({
|
||||
name: source.name,
|
||||
description: source.description,
|
||||
}));
|
||||
setSkills(skillEntries);
|
||||
} catch (err) {
|
||||
setError(errorMessage(err, 'Failed to load skills'));
|
||||
|
||||
Reference in New Issue
Block a user