agnets done
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { canonicalPage } from '@/lib/skills/surfaces';
|
||||
import { DOMAIN_SURFACES, canonicalPage } from '@/lib/skills/surfaces';
|
||||
import { pageKeyForContext } from '@/lib/skills/registry';
|
||||
import { getAgent } from './registry';
|
||||
import { reasoningFor } from './vocabulary';
|
||||
@@ -122,19 +122,33 @@ export function agentsForContext(agents = [], contextId) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The general agent every page falls back to.
|
||||
* Whether an agent is a *general* one: it covers every domain surface.
|
||||
*
|
||||
* Named once, here, because two different things need it and neither should
|
||||
* carry its own copy: resolving a default, and deciding whether a page has an
|
||||
* agent *of its own*.
|
||||
* Derived from the definition rather than matched against an id. This used to
|
||||
* be `FALLBACK_AGENT_ID = 'krow-workforce-agent'` — a literal agent key that
|
||||
* two functions below branched on, which is precisely the thing agent specs
|
||||
* being data is supposed to make impossible. With a key in the runtime,
|
||||
* renaming the general agent silently demotes it, deleting it leaves two dead
|
||||
* branches, and a workspace can never write a second general agent because
|
||||
* only one id is privileged.
|
||||
*
|
||||
* Reading `pages` instead makes it a fact about the spec: an agent listing
|
||||
* every surface that holds workforce records is an agent with no speciality,
|
||||
* which is exactly what makes it the sensible fallback. A general agent may
|
||||
* list *more* than the domain surfaces — the workforce agent also covers the
|
||||
* agent workspace — so this is a subset test, never an equality one.
|
||||
*/
|
||||
export const FALLBACK_AGENT_ID = 'krow-workforce-agent';
|
||||
export function isGeneralAgent(agent) {
|
||||
if (!agent?.pages?.length) return false;
|
||||
const covered = new Set(agent.pages);
|
||||
return DOMAIN_SURFACES.every((id) => covered.has(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* The agent written *for* this page, if there is one.
|
||||
*
|
||||
* The general agent is deliberately excluded. It covers every surface — which
|
||||
* is what makes it a fallback — so counting it as a page's own agent would make
|
||||
* General agents are deliberately excluded. One covers every surface — which is
|
||||
* what makes it a fallback — so counting it as a page's own agent would make
|
||||
* "does this page have a native agent?" true everywhere and the distinction
|
||||
* meaningless.
|
||||
*
|
||||
@@ -142,20 +156,26 @@ export const FALLBACK_AGENT_ID = 'krow-workforce-agent';
|
||||
* a broken one: see `resolveDefaultAgent`.
|
||||
*/
|
||||
export function nativeAgentForContext(agents = [], contextId) {
|
||||
return agentsForContext(agents, contextId).find((a) => a.id !== FALLBACK_AGENT_ID) || null;
|
||||
return agentsForContext(agents, contextId).find((a) => !isGeneralAgent(a)) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The general agent, when it can answer here.
|
||||
* The general agent, when one can answer here.
|
||||
*
|
||||
* Falls through to whichever published agent covers the page if the general one
|
||||
* has been archived or does not list this surface — a page must never be left
|
||||
* without an agent because of how the registry happens to be configured.
|
||||
* `agentsForContext` has already narrowed to published agents covering this
|
||||
* page and sorted them most-specific-first, so general agents sit at the end
|
||||
* and the *last* of them is the broadest. Taking that one is identical to the
|
||||
* old behaviour while exactly one general agent exists, and is a stated choice
|
||||
* rather than an arbitrary one once a workspace has written a second.
|
||||
*
|
||||
* Falls through to whichever published agent covers the page when no general
|
||||
* one does — a page must never be left without an agent because of how the
|
||||
* registry happens to be configured.
|
||||
*/
|
||||
export function fallbackAgentForContext(agents = [], contextId) {
|
||||
const general = getAgent(agents, FALLBACK_AGENT_ID);
|
||||
if (general && general.status === 'published' && agentCovers(general, contextId)) return general;
|
||||
return agentsForContext(agents, contextId)[0] || null;
|
||||
const covering = agentsForContext(agents, contextId);
|
||||
const general = covering.filter(isGeneralAgent);
|
||||
return general[general.length - 1] || covering[0] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user