Class AbstractAIProvider

java.lang.Object
org.machanism.machai.process.provider.AbstractAIProvider
All Implemented Interfaces:
ProcessProvider
Direct Known Subclasses:
AnthropicProvider, OpenAIProvider, ToolsProvider

public abstract class AbstractAIProvider extends Object implements ProcessProvider
Base implementation of the ProcessProvider contract shared by concrete provider integrations.

This class centralizes common configuration handling, request input logging, tool invocation safety, MCP/web-search bootstrap logic, and usage accounting state used by subclasses such as OpenAI- and Claude-based providers.

  • Field Details

    • logger

      static org.slf4j.Logger logger
      Logger instance for this provider.
    • ERROR_TOOL_RESULT_PREFIX

      public static final String ERROR_TOOL_RESULT_PREFIX
      Prefix prepended to tool invocation error messages that are returned back to the LLM.
      See Also:
    • USERNAME_PROP_NAME

      public static final String USERNAME_PROP_NAME
      Environment variable name for authenticating with the GenAI provider.
      See Also:
    • PASSWORD_PROP_NAME

      public static final String PASSWORD_PROP_NAME
      Environment variable name for authenticating with the GenAI provider.
      See Also:
    • LOG_LINE_LENG

      public static final int LOG_LINE_LENG
      Maximum length for log lines. Configures the truncation threshold when logging tool parameters and result strings.
      See Also:
    • LINE_SEPARATOR

      public static final String LINE_SEPARATOR
      Line separator used when composing prompts.
      See Also:
    • PARAGRAPH_SEPARATOR

      public static final String PARAGRAPH_SEPARATOR
      Paragraph separator used when composing prompts.
      See Also:
    • MCP_PROP_NAME_PREFIX

      protected static final String MCP_PROP_NAME_PREFIX
      Prefix for MCP property names.
      See Also:
    • MAX_OUTPUT_TOKENS

      public static final long MAX_OUTPUT_TOKENS
      Default maximum number of tokens the model may generate.
      See Also:
    • DEFAULT_WEBSEARCH_TYPE_NAME

      public static final String DEFAULT_WEBSEARCH_TYPE_NAME
      Default web search type name.
      See Also:
    • PROJECT_DIR_PARAM_NAME

      public static final String PROJECT_DIR_PARAM_NAME
      Name of the project directory parameter.
      See Also:
    • model

      private String model
      Active model identifier used in ProcessProvider.perform().
    • projectDir

      private File projectDir
      Working directory passed to tool handlers as contextual information.
    • timeoutSec

      private long timeoutSec
      Request timeout in seconds; 0 means SDK defaults are used.
    • instructions

      private String instructions
      Optional instructions applied to the request.
    • maxOutputTokens

      private Long maxOutputTokens
      Maximum number of output tokens for responses.
    • maxToolCalls

      private Long maxToolCalls
      Maximum number of tool calls permitted per response.
    • config

      private Configurator config
      Configuration source used to initialize clients and provider features.
    • errorHandling

      private boolean errorHandling
      Flag indicating if standard runtime exceptions should be wrapped or handled conversationally.
  • Constructor Details

    • AbstractAIProvider

      protected AbstractAIProvider()
      Creates a provider base instance.

      Subclasses are expected to complete initialization in init(String, Configurator).

  • Method Details

    • init

      public void init(String model, Configurator config)
      Initializes the provider from the given configuration.
      Specified by:
      init in interface ProcessProvider
      Parameters:
      model - the model identifier to use
      config - provider configuration source
    • addMcpServers

      protected void addMcpServers()
      Reads sequential MCP server configuration groups and registers them with the concrete provider implementation.

      The method looks for configuration keys named MCP.*, then MCP_1.*, MCP_2.*, and so on until no further URL is found.

    • addMcpServer

      protected void addMcpServer(String label, String url, String authorization, String description)
      Registers one MCP server/tool with the underlying provider SDK.

      This is an optional lifecycle method intended to be overridden by subclasses that natively support the Model Context Protocol (MCP).

      Parameters:
      label - provider-visible MCP server label
      url - server endpoint URL
      authorization - optional authorization token/value
      description - optional human-readable description
    • addWebSearch

      protected void addWebSearch()
      Registers a web-search capability when enabled in configuration.

      The default implementation reads configuration values and delegates the actual SDK-specific registration to addWebSearch(String, String, String, String).

    • addWebSearch

      protected void addWebSearch(String type, String city, String country, String region)
      Registers a provider-specific web-search tool.

      This is an optional capability hook intended to be overridden by subclasses whose underlying models natively support real-time web-search tools.

      Parameters:
      type - provider-specific web-search tool type/version
      city - optional user city
      country - optional user country
      region - optional user region
    • normalize

      protected String normalize(String value)
      Normalizes a string for case-insensitive comparisons.
      Parameters:
      value - source value
      Returns:
      lower-cased value, or an empty string when the input is null
    • safelyInvokeTool

      protected Object safelyInvokeTool(String name, ToolFunction tool, com.fasterxml.jackson.databind.JsonNode params, File projectDir)
      Safely invokes a tool function and converts IOExceptions into a textual error payload suitable for the model conversation.
      Parameters:
      name - tool name
      tool - tool handler
      params - parsed tool parameters
      projectDir - working directory passed to the tool
      Returns:
      tool output or a formatted error message string
      Throws:
      SpecialException - if a non-recoverable error occurs or when error-handling is disabled
    • instructions

      public void instructions(String instructions)
      Sets system-level instructions applied to subsequent requests.
      Specified by:
      instructions in interface ProcessProvider
      Parameters:
      instructions - instruction text, or null to clear
    • getTimeout

      public long getTimeout()
      Returns the configured request timeout.
      Returns:
      timeout in seconds; 0 indicates the SDK default
    • setTimeout

      public void setTimeout(long timeout)
      Sets the timeout value used by provider client creation.

      The second parameter is unused and retained only for API compatibility.

      Parameters:
      timeout - timeout in seconds; use 0 to use SDK defaults
    • addTool

      protected abstract void addTool(String name, String description, ToolFunction function, ParamDescriptor... paramsDesc)
      Adds a tool to the provider.

      Implemented by concrete subclasses to register the functional tool definition with the provider's specific API schemas (such as OpenAI's Tool schema or Claude's Tool definition).

      Parameters:
      name - the tool name
      description - the tool description
      function - the tool function implementation callback
      paramsDesc - descriptors for the tool parameters
    • addTools

      public void addTools(FunctionTools tools, String[] enabledTools)
      Registers tool methods from the given FunctionTools instance, filtering them based on an optional array of enabled tool patterns.

      This method inspects all public methods of the provided tools object using reflection, looking for methods annotated with Tool. For each annotated method, it performs the following steps:

      Filtering logic:

      • If enabledTools is null, all annotated tools are registered without restriction.
      • If enabledTools is provided, each entry is treated as a regular expression pattern. A tool is registered only if its fully qualified name matches at least one of the provided patterns (using Pattern.compile(String) and Matcher.find()).
      • When enabledTools is not null and a tool matches, an informational log entry is written indicating which tool was enabled.
      Specified by:
      addTools in interface ProcessProvider
      Parameters:
      tools - the FunctionTools instance whose annotated methods should be scanned and registered as tools; must not be null
      enabledTools - an optional array of regular expression patterns used to filter which tools should be enabled. If null, all discovered tools are enabled by default. Each pattern is matched against the fully qualified tool name (format: <ClassName>:<toolName>).
      See Also:
    • toSnakeCase

      public static String toSnakeCase(String input)
      Converts a given string into snake_case format.

      Examples:

      • "myMethodName" becomes "my_method_name"
      • "Already-Kebab" becomes "already_kebab"
      • "getHTTPResponse" becomes "get_http_response"
      • null or "" returns ""
      Parameters:
      input - the original string to convert
      Returns:
      the snake_case representation, or an empty string if input is null or empty
    • interpolateDescription

      private String interpolateDescription(String description)
      Interpolates system metadata variables (e.g., OS Name) inside the annotation's tool description text before registering it with the LLM.
      Parameters:
      description - the raw tool description from the annotation
      Returns:
      the interpolated description string
    • addPrompts

      public void addPrompts(FunctionTools tools)
      Registers all annotated prompt methods from the given FunctionTools instance.

      This method inspects the public methods of the provided FunctionTools class. For any method annotated with Prompt, it extracts its configured metadata—such as the name, description, and target Role. If no explicit name is defined in the annotation, it falls back to using the method's Java name, before registering it as an active prompt.

      Specified by:
      addPrompts in interface ProcessProvider
      Parameters:
      tools - the FunctionTools instance containing the annotated prompt methods to register
    • addResources

      public void addResources(FunctionTools tools)
      Scans the provided FunctionTools instance for methods annotated with Resource, and registers each resource for use during a run.
      Specified by:
      addResources in interface ProcessProvider
      Parameters:
      tools - the FunctionTools instance whose methods will be scanned for Resource annotations
    • addResource

      private void addResource(FunctionTools tools, Method method, String[] uris, String description, String mimeType)
      Resolves resource endpoints from declared arrays and binds them to the implementation context.
      Parameters:
      tools - target instance container
      method - reflective execution handle
      uris - URIs declared in the annotation config
      description - resource description text
      mimeType - the mime type associated with the resource
      Throws:
      IllegalArgumentException - if any URIs have incorrect syntax or execution fails
    • addResource

      protected void addResource(URI uri, String description, String mimeType, ToolFunction function, ParamDescriptor... paramsDesc)
      Registers a resource callback for providers that support resource management tools.

      Intended to be implemented by concrete subclasses to natively expose local/remote resources to the LLM model context.

      Parameters:
      uri - resource URI
      description - a description of the resource tool
      mimeType - the mime type format (e.g. application/json)
      function - the callback execution handler
      paramsDesc - variable-arity array of parameter descriptors
    • addPrompt

      private void addPrompt(FunctionTools tools, Method method, String name, String description, Role role)
      Configures and registers a single prompt method.
      Parameters:
      tools - instance container
      method - reflection handle
      name - the prompt name
      description - descriptive purpose
      role - role level instructions
    • addPrompt

      protected void addPrompt(String name, String description, ToolFunction function, Role role, ParamDescriptor... paramsDesc)
      Registers a prompt callback for providers that support prompt tools.

      Intended to be implemented by concrete subclasses to natively expose dynamic prompt templates to the underlying model execution context.

      Parameters:
      name - prompt name exposed to the provider
      description - prompt description used by the provider
      function - callback used to resolve the prompt content
      role - role associated with the generated prompt
      paramsDesc - descriptors for prompt input parameters
    • addTool

      private void addTool(FunctionTools tools, Method method, String name, String description)
      Configures and registers a single tool method.
      Parameters:
      tools - instance container
      method - reflection handle
      name - the tool name
      description - tool capabilities description
    • fillParamDesc

      private ParamDescriptor[] fillParamDesc(Method method)
      Analyzes method signature annotations to build an array of parameter descriptions.
      Parameters:
      method - the method to inspect
      Returns:
      an array of ParamDescriptor instances detailing parameters
    • invoke

      private Object invoke(FunctionTools tools, Method method, com.fasterxml.jackson.databind.JsonNode props, Object... paramsByType) throws ReflectiveOperationException
      Dynamically invokes the specified method on the given tools instance, matching arguments dynamically.
      Parameters:
      tools - target instance
      method - method handle
      props - the incoming JSON attributes
      paramsByType - variable array of parameter context constraints
      Returns:
      execution output
      Throws:
      ReflectiveOperationException - if the invoked target throws an exception
    • getParamByType

      private <T> T getParamByType(Class<T> type, Object[] paramsByType)
      Filters parameter arrays to find the first assignment-compatible instance of the specified type.
      Type Parameters:
      T - the generic class type to filter for
      Parameters:
      type - the class definition type representing the constraint
      paramsByType - variable array containing contextual params
      Returns:
      the mapped parameter matching the target class, or null if not found
    • getParamValue

      protected String getParamValue(com.fasterxml.jackson.databind.JsonNode props, String paramName, String defaultValue)
      Retrieves the value for a parameter from the given JSON node, or returns the default value if not present.
      Parameters:
      props - the JSON node containing parameters
      paramName - the parameter name
      defaultValue - the default value to use if not present
      Returns:
      the parameter value as a string
    • getProjectDir

      public File getProjectDir()
      Returns the current project directory.
      Returns:
      the active projectDir File context
    • setProjectDir

      public void setProjectDir(File projectDir)
      Sets the project directory.
      Specified by:
      setProjectDir in interface ProcessProvider
      Parameters:
      projectDir - the projectDir to set
    • prompt

      public void prompt(String text)
      Sets the prompt text for the provider.
      Specified by:
      prompt in interface ProcessProvider
      Parameters:
      text - the prompt text
    • clear

      public void clear()
      Clears the provider state.
      Specified by:
      clear in interface ProcessProvider
    • isErrorHandling

      public boolean isErrorHandling()
      Returns whether runtime tool errors are handled conversationally.
      Returns:
      true if errors are returned as text payload to the model; false if exceptions propagate and fail immediately.
    • setErrorHandling

      public void setErrorHandling(boolean errorHandling)
      Configures how runtime tool errors are handled by the invocation logic.

      Use this setter to toggle between conversational error recovery and strict, fail-fast exception reporting.

      Behavior Summary:

      • setErrorHandling(true) (Default): Captures all standard runtime tool exceptions and returns them in a text payload (e.g. "Error: The functional tool call failed..."). This permits conversational LLM agents to review the failure description and attempt self-correction.
      • setErrorHandling(false): Re-throws all invocation exceptions as a wrapped SpecialException up the current thread execution. Use this setting to debug and fail execution immediately upon the first unhandled exception.
      Specified by:
      setErrorHandling in interface ProcessProvider
      Parameters:
      errorHandling - true to enable conversational intercept and recovery; false to disable intercept and trigger strict stack propagation.
    • getConfigurator

      public Configurator getConfigurator()
      Returns the configurator context source.
      Returns:
      the config configuration source
    • getModel

      public String getModel()
      Returns:
      the model
    • setModel

      public void setModel(String model)
      Parameters:
      model - the model to set
    • getMaxOutputTokens

      public Long getMaxOutputTokens()
      Returns:
      the maxOutputTokens
    • setMaxOutputTokens

      public void setMaxOutputTokens(Long maxOutputTokens)
      Parameters:
      maxOutputTokens - the maxOutputTokens to set
    • getInstructions

      public String getInstructions()
      Returns:
      the instructions
    • setInstructions

      public void setInstructions(String instructions)
      Parameters:
      instructions - the instructions to set
    • getMaxToolCalls

      public Long getMaxToolCalls()
      Returns:
      the maxToolCalls
    • setMaxToolCalls

      public void setMaxToolCalls(Long maxToolCalls)
      Parameters:
      maxToolCalls - the maxToolCalls to set