Package com.tnsai.rag

Class KnowledgeDeclarations

java.lang.Object
com.tnsai.rag.KnowledgeDeclarations

public final class KnowledgeDeclarations extends Object
The one reader of Knowledge declarations.

Every runtime that needs to know which knowledge a role, an agent, an action or a chat turn sees asks here, so the rules live in one place:

  • an agent's entries are its @AgentSpec entries under the agent level of its class configuration (Config): a name the annotation declares is overridden member by member, except that an entry that changes use keeps a maxTokens or search from below only when the new use applies to it (keepsMaxTokens(com.tnsai.annotations.Knowledge.Use, com.tnsai.annotations.Knowledge.Use), keepsSearch(com.tnsai.annotations.Knowledge.Use, com.tnsai.annotations.Knowledge.Use)), and a name only the file gives follows the annotation entries, in name order;
  • a role's entries are its @RoleSpec entries under the roles section of its agent's file, then under its own file, each layered the same way over everything below it, so the role's own file wins and overrides a name only the section gave member by member;
  • names are unique within one knowledge list;
  • use, maxTokens, search and every Search member hold at most one value;
  • a non-empty select applies only to a FILE or URL source;
  • an action's entry names a declared source and sets only use, maxTokens and search; each set value replaces the declared one, and an unset use is Knowledge.Use.SEARCH;
  • maxTokens needs use = DIRECT and search needs use = SEARCH, checked on the resolved entry;
  • action knowledge is valid on ActionType.LLM and ActionType.LOCAL only;
  • the SEARCH sources of one scope merge their Search settings member by member, and two different values for one member fail;
  • an action names at most one GRAPH entry and no document entry beside it; a wider scope merges its document entries without its GRAPH entries, and a scope of GRAPH entries alone searches with strategy GRAPH unless a set strategy says otherwise, which KnowledgeEntry rejects;
  • MEMORY knowledge is chat knowledge the application supplies at runtime: only @AgentSpec declares it, no action names it, and an agent's chat scope holds at most one MEMORY entry; other SEARCH entries and DIRECT entries may sit beside it, and the SEARCH settings of the MEMORY entry and of the other SEARCH entries merge apart, since a chat turn searches each on its own.
  • a KnowledgePolicy names a source the knowledge of its own spec declares, configuration files layered, and a source has at most one; WHEN_CONFIGURED applies to a FILE source whose use is not DIRECT.

Violations throw IllegalStateException naming the declaration.

Since:
0.18.0
  • Method Details

    • declared

      public static List<KnowledgeEntry> declared(Class<?> host)
      Knowledge a role or agent class declares, in declaration order.
      Parameters:
      host - a class carrying RoleSpec or AgentSpec
      Returns:
      the declared entries, each resolved on its own
      Throws:
      IllegalStateException - when a declaration breaks a rule
    • declared

      public static List<KnowledgeEntry> declared(Class<?> host, List<KnowledgeEntry> overrides, String overridesWhere)
      The knowledge an agent class chats and acts with: what its @AgentSpec declares, as declared(Class) reads it, with overrides layered over it by name. An override replaces the declared entry of its name in place, so one that replaces an entry of the class's @RoleSpec stays a role entry; an override with a new name follows the declared entries. A class without @AgentSpec declares no agent knowledge, so its knowledge is the overrides alone. The rules over the whole list run on the result.
      Parameters:
      host - the agent class
      overrides - the entries that win over the declared ones
      overridesWhere - what gives the overrides, for messages
      Returns:
      the layered entries
      Throws:
      IllegalStateException - when a declaration or the layered list breaks a rule
      Since:
      0.18.0
    • policy

      public static Optional<KnowledgePolicy> policy(Class<?> host, String name)
      The presence policy a role or agent class gives a source it declares: the KnowledgePolicy of that name in the knowledgePolicy of the spec whose knowledge, configuration files layered, declares the source. declared(Class) validates the policies.
      Parameters:
      host - a role or agent class
      name - the source name
      Returns:
      the policy, or empty when the source has none and so must load
      Since:
      0.18.1
    • validateAction

      public static void validateAction(Method method)
      Checks what an action declares on its own: its type allows knowledge, each entry names a source once and sets no source member, and every member holds at most one value. Names are resolved later, against the knowledge in reach, by forAction(Method, List).
      Parameters:
      method - an action method
      Throws:
      IllegalStateException - when the action's knowledge breaks a rule
    • forAction

      public static KnowledgeSelection forAction(Method method, List<KnowledgeEntry> available)
      The knowledge an action sees: the sources its ActionSpec.knowledge() names, with the action's values applied.
      Parameters:
      method - an action method
      available - the knowledge in reach of the action; a later entry with the same name replaces an earlier one
      Returns:
      the action's scope; KnowledgeSelection.EMPTY when it names none
      Throws:
      IllegalStateException - when a name is unknown or the resolved scope breaks a rule
    • forAction

      public static KnowledgeSelection forAction(Method method, List<KnowledgeEntry> available, Map<String,List<String>> actionKnowledge)
      Like forAction(Method, List), but an action the agent gives its knowledge by name, keyed by action name in actionKnowledge, sees those entries as declared instead of its ActionSpec.knowledge().
      Parameters:
      method - an action method
      available - the knowledge in reach of the action
      actionKnowledge - entry names by action name that replace an action's own knowledge
      Returns:
      the action's scope; KnowledgeSelection.EMPTY when it names none
      Throws:
      IllegalStateException - when a name is unknown or the resolved scope breaks a rule
      Since:
      0.18.0
    • forActionIfResolvable

      public static Optional<KnowledgeSelection> forActionIfResolvable(Method method, List<KnowledgeEntry> available)
      Like forAction(Method, List), but leaves an action that names knowledge outside available unresolved instead of failing. A role resolves its actions this way before it knows its agent; the agent resolves them strictly.
      Parameters:
      method - an action method
      available - the knowledge in reach so far
      Returns:
      the action's scope, or empty when a name is not in reach yet
      Throws:
      IllegalStateException - when the resolved scope breaks a rule
    • forActionIfResolvable

      public static Optional<KnowledgeSelection> forActionIfResolvable(Method method, List<KnowledgeEntry> available, Map<String,List<String>> actionKnowledge)
      Like forActionIfResolvable(Method, List), with the action's knowledge given by name as forAction(Method, List, Map) takes it.
      Parameters:
      method - an action method
      available - the knowledge in reach so far
      actionKnowledge - entry names by action name that replace an action's own knowledge
      Returns:
      the action's scope, or empty when a name is not in reach yet
      Throws:
      IllegalStateException - when the resolved scope breaks a rule
      Since:
      0.18.0
    • select

      public static KnowledgeSelection select(List<KnowledgeEntry> entries, String where)
      A scope over the given entries searched together, such as a chat turn over an agent's MEMORY knowledge or over its other knowledge.
      Parameters:
      entries - the sources in scope, in declaration order
      where - what declared them, for messages
      Returns:
      the scope
      Throws:
      IllegalStateException - when the SEARCH settings conflict
    • select

      public static KnowledgeSelection select(List<KnowledgeEntry> entries, String where, Supplier<RetrievalConfig.Builder> defaults)
      A scope over the given entries whose SEARCH settings overlay the given defaults instead of the framework's, such as a chat turn's.
      Parameters:
      entries - the sources in scope, in declaration order
      where - what declared them, for messages
      defaults - a fresh builder carrying the scope's defaults per call
      Returns:
      the scope
      Throws:
      IllegalStateException - when the SEARCH settings conflict
      Since:
      0.18.0
    • validate

      public static void validate(Class<?> host, List<KnowledgeEntry> outer)
      Checks every action of a class against the knowledge in its reach.
      Parameters:
      host - a role or agent class
      outer - knowledge in reach beyond the class's own declarations, such as the enclosing agent's; it replaces a class entry of the same name
      Throws:
      IllegalStateException - when a declaration breaks a rule
    • validate

      public static void validate(Class<?> host, List<KnowledgeEntry> outer, Map<String,List<String>> actionKnowledge)
      Like validate(Class, List), with the knowledge of some actions given by name as forAction(Method, List, Map) takes it.
      Parameters:
      host - a role or agent class
      outer - knowledge in reach beyond the class's own declarations
      actionKnowledge - entry names by action name that replace an action's own knowledge
      Throws:
      IllegalStateException - when a declaration breaks a rule
      Since:
      0.18.0
    • hasKnowledge

      public static boolean hasKnowledge(Method method)
      Parameters:
      method - an action method
      Returns:
      true when the action names knowledge
    • hasKnowledge

      public static boolean hasKnowledge(Method method, Map<String,List<String>> actionKnowledge)
      Like hasKnowledge(Method), with the knowledge of some actions given by name: an action given names has knowledge when it is given at least one, whatever its ActionSpec.knowledge() declares.
      Parameters:
      method - an action method
      actionKnowledge - entry names by action name that replace an action's own knowledge
      Returns:
      true when the action has knowledge
      Since:
      0.18.0
    • declaresKnowledge

      public static boolean declaresKnowledge(Class<?> host)
      Parameters:
      host - a role or agent class
      Returns:
      true when the class declares knowledge or one of its actions names some
    • where

      public static String where(Class<?> host)
      Where a class declares its knowledge as a whole, for the rules over the whole list: @AgentSpec on the class, @RoleSpec on it, or @RoleSpec and @AgentSpec on a class that is both, then with each configuration file that gives it knowledge. A file counts on the side whose annotation names it. The chat scope and the merged search of a class are such rules.
      Parameters:
      host - the declaring class
      Returns:
      the label
      Since:
      0.18.0
    • where

      public static String where(Class<?> host, String overridesWhere)
      Where an agent class's knowledge is declared when overridesWhere gives entries over it, as declared(Class, List, String) layers them: where(Class) and overridesWhere, or overridesWhere alone for a class without @AgentSpec.
      Parameters:
      host - the agent class
      overridesWhere - what gives the overrides
      Returns:
      the label
      Since:
      0.18.0
    • chatScope

      public static List<KnowledgeEntry> chatScope(List<KnowledgeEntry> entries)
      The knowledge a chat turn sees: the enabled entries whose use is SEARCH or DIRECT, in declaration order. SEQUENTIAL entries are ignored by chat, and GRAPH entries stay out of it; actions that name them still see them.
      Parameters:
      entries - an agent's @AgentSpec knowledge
      Returns:
      the entries chat sees
    • withoutMemoryBesideSearch

      public static List<KnowledgeEntry> withoutMemoryBesideSearch(List<KnowledgeEntry> entries)
      The entries a class's SEARCH settings merge over: all of them, except that when its chat scope searches a MEMORY entry beside other SEARCH entries, the MEMORY entries stay out, since their binding searches them on its own with its own settings.
      Parameters:
      entries - a class's knowledge, in declaration order
      Returns:
      the entries to merge, in declaration order
      Since:
      0.18.6
    • chatSearchDefaults

      public static RetrievalConfig.Builder chatSearchDefaults()
      The settings a chat turn's SEARCH starts from: chat keeps every hit and lets the model judge relevance (minScore 0), caches, and grounds without evidence rather than failing the turn. A field the entries' @Search sets wins over these.
      Returns:
      a fresh builder carrying the chat defaults
      Since:
      0.18.0
    • roleName

      public static String roleName(Class<?> roleClass)
      The name a role is referenced by: RoleSpec.name(), or the simple class name when that is blank. An anonymous class has no simple name and is referenced by its binary name.
      Parameters:
      roleClass - a role class
      Returns:
      the role name
    • requireUniqueRoleNames

      public static void requireUniqueRoleNames(Collection<Class<?>> roleClasses, String agent)
      Checks that no two roles of one agent share a name.
      Parameters:
      roleClasses - the agent's role classes
      agent - the agent, for messages
      Throws:
      IllegalStateException - when two roles share a name
    • keepsMaxTokens

      public static boolean keepsMaxTokens(Knowledge.Use below, Knowledge.Use use)
      Whether a layer keeps the maxTokens of the layer below it when the layer does not give maxTokens itself: when it leaves use as it was, or changes it to Knowledge.Use.DIRECT. See keepsSearch(com.tnsai.annotations.Knowledge.Use, com.tnsai.annotations.Knowledge.Use) for why a layer that changes use drops the members of the other modes.
      Parameters:
      below - the resolved use of the layer below; unset is Knowledge.Use.SEARCH
      use - the resolved use of the layer
      Returns:
      true when the maxTokens below carries into the layer
    • keepsSearch

      public static boolean keepsSearch(Knowledge.Use below, Knowledge.Use use)
      Whether a layer keeps the search of the layer below it when the layer does not give search itself: when it leaves use as it was, or changes it to Knowledge.Use.SEARCH. A layer that changes use drops the members of every mode other than its new use: it could not unset them, so inheriting them would make the combination unwritable. A layer that leaves use as it was inherits every member, so a lower declaration that sets a member its use does not take still fails. An action over its declared source and a configuration file over the layer below it both layer this way.
      Parameters:
      below - the resolved use of the layer below; unset is Knowledge.Use.SEARCH
      use - the resolved use of the layer
      Returns:
      true when the search below carries into the layer