agnets done
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { usePreferences, useUpdatePreferences } from '@/lib/krowHooks';
|
||||
import {
|
||||
useAgentDefinitions, useAuthoredSources, useDeleteAgentDefinition,
|
||||
useMigrateStoredAgents, useSaveAgentDefinition,
|
||||
} from './agentStore';
|
||||
import { reportSave } from '@/lib/skills/saveFeedback';
|
||||
import { AGENTS, parseAgent, readAgentRegistry, validateAgentSource } from './registry';
|
||||
import { customAgentSource, removeCustomAgent, upsertCustomAgent } from './customAgents';
|
||||
import { customAgentSource } from './customAgents';
|
||||
import { archiveAgent, duplicateAgent, publishAgent, restoreAgent } from './agentLifecycle';
|
||||
|
||||
/**
|
||||
@@ -24,11 +28,36 @@ import { archiveAgent, duplicateAgent, publishAgent, restoreAgent } from './agen
|
||||
*/
|
||||
export function useAgents() {
|
||||
const preferences = usePreferences();
|
||||
const updatePreferences = useUpdatePreferences();
|
||||
|
||||
const stored = useMemo(() => preferences.customAgents || [], [preferences.customAgents]);
|
||||
/* Authored agents come from the registry the runtime resolves from, not from
|
||||
this account's preferences. They used to come from preferences, and the
|
||||
consequence was an agent that the list called "published" and every run
|
||||
answered 404: the backend stored it faithfully, in a table the runtime does
|
||||
not read. Skills are still preferences-backed — that is a separate move. */
|
||||
const definitions = useAgentDefinitions();
|
||||
const saveDefinition = useSaveAgentDefinition();
|
||||
const deleteDefinition = useDeleteAgentDefinition();
|
||||
|
||||
const rows = useMemo(() => definitions.data || [], [definitions.data]);
|
||||
const stored = useAuthoredSources(rows);
|
||||
const customSkills = useMemo(() => preferences.customSkills || [], [preferences.customSkills]);
|
||||
|
||||
/* Anything an author wrote before the store moved. Without this it would stop
|
||||
being displayed rather than being carried across — the rows would sit in
|
||||
the preferences column, unread, and the agent would appear to have been
|
||||
deleted. Runs once, and clears the old copy only after every write lands. */
|
||||
const updatePreferences = useUpdatePreferences();
|
||||
const legacy = useMemo(() => preferences.customAgents || [], [preferences.customAgents]);
|
||||
useMigrateStoredAgents({
|
||||
rows,
|
||||
stored: legacy,
|
||||
enabled: !definitions.isPending,
|
||||
clearStored: useCallback(
|
||||
() => updatePreferences.mutateAsync({ customAgents: [] }),
|
||||
[updatePreferences]
|
||||
),
|
||||
});
|
||||
|
||||
const { agents, diagnostics } = useMemo(
|
||||
() => readAgentRegistry(stored, { customSkills }),
|
||||
[stored, customSkills]
|
||||
@@ -63,23 +92,29 @@ export function useAgents() {
|
||||
const problem = validateAgentSource(source);
|
||||
if (problem) return { ok: false, error: problem };
|
||||
|
||||
const { agent, next } = upsertCustomAgent(stored, source);
|
||||
await updatePreferences.mutateAsync(
|
||||
{ customAgents: next },
|
||||
reportSave(message || `${agent.name} saved`)
|
||||
);
|
||||
const agent = parseAgent(source, { custom: true });
|
||||
try {
|
||||
await saveDefinition.mutateAsync({ definitionId: agent.id, markdown: source });
|
||||
} catch (error) {
|
||||
/* The service refuses a definition naming a tool that does not exist, and
|
||||
says which. Surfaced rather than swallowed: the author picked it, and
|
||||
the alternative is an agent quietly missing the capability. */
|
||||
return { ok: false, error: error?.message || 'That agent could not be saved.' };
|
||||
}
|
||||
reportSave(message || `${agent.name} saved`);
|
||||
return { ok: true, agent };
|
||||
}, [stored, updatePreferences]);
|
||||
}, [saveDefinition]);
|
||||
|
||||
/** Removes the account's definition. A shipped agent returns to its shipped form. */
|
||||
const remove = useCallback(async (id) => {
|
||||
const next = removeCustomAgent(stored, id);
|
||||
await updatePreferences.mutateAsync(
|
||||
{ customAgents: next },
|
||||
reportSave(isShipped(id) ? 'Reverted to the shipped definition' : 'Agent removed')
|
||||
);
|
||||
try {
|
||||
await deleteDefinition.mutateAsync(id);
|
||||
} catch (error) {
|
||||
return { ok: false, error: error?.message || 'That agent could not be removed.' };
|
||||
}
|
||||
reportSave(isShipped(id) ? 'Reverted to the shipped definition' : 'Agent removed');
|
||||
return { ok: true };
|
||||
}, [stored, updatePreferences, isShipped]);
|
||||
}, [deleteDefinition, isShipped]);
|
||||
|
||||
/**
|
||||
* Publishes, refusing to overwrite a newer published version.
|
||||
@@ -123,7 +158,8 @@ export function useAgents() {
|
||||
return {
|
||||
agents,
|
||||
diagnostics,
|
||||
saving: updatePreferences.isPending,
|
||||
loading: definitions.isPending,
|
||||
saving: saveDefinition.isPending || deleteDefinition.isPending,
|
||||
isShipped,
|
||||
isOverridden,
|
||||
sourceFor,
|
||||
|
||||
Reference in New Issue
Block a user