agnets done

This commit is contained in:
2026-08-28 11:02:02 +05:30
parent ab9adde6cd
commit eaf08e061d
58 changed files with 3506 additions and 4308 deletions

View File

@@ -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,