# Feature Discovery The core package discovers features from the filesystem and registers them in SQLite for fast lookup. Features are organized into subdirectories within each search path: `agents/`, `workflows/`, `actions/`, `adaptaters/`, `cmds/`, and `skills/`. ## Directory Structure Each feature search path should follow this structure: ``` features/ ├── agents/ # Agent definitions (.yml) ├── workflows/ # Workflow pipelines (.yml) ├── actions/ # Action scripts (.yml, .js, .py) ├── adaptaters/ # Data adapters (.js) ├── cmds/ # Custom commands (.js) └── skills/ # Skill documentation (subdirectories with SKILL.md) ``` ## Agent Discovery Agents are discovered by scanning the `agents/` subdirectory for `.yml` files. Each YAML file defines an agent specification including its name, tools, template, and inference parameters. The discovery process: 1. Reads all `.yml` files in the agents directory 2. Parses each file to extract the agent name (from filename) 3. Extracts tool documentation from the `tool:` section using `extractAgentToolDocAndVariables()` 4. Registers the feature with its path, extension (`yml`), variables, type, and category ```typescript import { getFeatureSpec } from "@agent-smith/core"; const spec = getFeatureSpec("writer", "agent"); // Returns: { found: true, path: "/path/to/agents/writer.yml", ext: "yml" } ``` ### Agent YAML Format ```yaml # tool is to declare this agent can be used as a subagent tool tool: name: writer description: Writes content based on a prompt arguments: topic: description: The topic to write about (string) prompt: "{prompt}" model: gemma24b template: system: "You are a helpful writing assistant." tools: - read ``` ## Action Discovery Actions are discovered from the `actions/` subdirectory supporting three file types: `.yml`, `.js`, and `.py`. ### YAML Actions YAML actions define a shell command to execute. The `tool:` section provides the action's description and arguments. ```yaml tool: name: read description: Reads a file arguments: path: description: File path to read (string) args: ["cat"] ``` ### JavaScript Actions JavaScript actions export an `action` function that receives parameters and options: ```javascript // actions/read.js export async function action(args, options) { const [filePath] = args; return require("fs").readFileSync(filePath, "utf-8"); } ``` ### Python Actions Python actions are executed via the `python-shell` package. The script receives arguments as command-line parameters: ```python # actions/read.py import sys print(open(sys.argv[1]).read()) ``` ## Workflow Discovery Workflows are discovered from the `workflows/` subdirectory as `.yml` files defining a pipeline of steps. Each step specifies a type (`agent`, `action`, `adaptater`, or `cmd`) and the feature name to execute. ### Workflow YAML Format ```yaml steps: - action: "read" - agent: "summarizer" - adaptater: "format" ``` The `readWorkflow()` function loads a workflow by name, parses the YAML, and returns an array of `WorkflowStep` objects: ```typescript import { fs } from "@agent-smith/core"; const { found, workflow } = await fs.readWorkflow("my-pipeline"); // workflow: Array<{ name: string, type: string }> ``` ## Adapter Discovery Adaptaters are discovered from the `adaptaters/` subdirectory. Currently only `.js` files are supported. Each file exports an `action` function that transforms data: ```javascript // adaptaters/prequery.ts export async function action(args, options) { const [input] = args; return { query: input.toLowerCase(), processed: true }; } ``` Adaptaters are executed via `executeAdaptater()`, which dynamically imports the JS module and calls the exported action. ## Command Discovery Commands are discovered from the `cmds/` subdirectory as `.js` files. Each file must export a `runCmd` function: ```javascript // cmds/git-status.js export async function runCmd(args, options) { const { execute } = await import("@agent-smith/core"); return execute("git", ["status"]); } ``` Commands are registered in the `cmd` table and can be referenced in workflow steps with type `cmd`. ## Skill Discovery Skills are discovered from the `skills/` subdirectory. Each skill is a subdirectory containing a `SKILL.md` file with front-matter metadata: ```markdown --- name: python-basics description: Python programming fundamentals --- # Python Basics Learn Python syntax and common patterns. ``` The `_readSkills()` function parses the front-matter to extract the name and description, then registers each skill in the `skill` table. For detailed information about creating and using skills, see the [Skills Documentation](/libraries/core/skills). ## SQLite Registration All discovered features are registered in their respective SQLite tables: | Table | Extension | Columns | |-------|-----------|---------| | `agent` | `yml` | name, path, variables (JSON), ext, type, category | | `workflow` | `yml` | name, path, variables (JSON), ext, type, category | | `action` | `yml`, `js`, `py` | name, path, variables (JSON), ext | | `adaptater` | `yml`, `js`, `py` | name, path, variables (JSON), ext | | `cmd` | `js` | name, path, variables (JSON), ext | | `skill` | `md` | name, path, variables (JSON), ext | The `updateAllFeatures()` function orchestrates the full discovery pipeline: ```typescript import { updateAllFeatures } from "@agent-smith/core/updateconf"; // Scan builtin features + all registered paths await updateAllFeatures( ["/home/user/features", "/opt/plugins/dist"], userFeatures // optional additional user features ); ``` This function: 1. Combines the builtin features directory with all registered paths 2. Calls `readFeaturesDirs()` to scan each directory 3. Reads command metadata via `readUserCmd()` for `cmd` features 4. Calls `updateFeatures()` to upsert each feature type into SQLite 5. Calls `updateAliases()` to create aliases in the `aliases` table ## Feature Lookup Once registered, features are looked up by name and type through the `getFeatureSpec()` function, which queries the SQLite database: ```typescript import { getFeatureSpec } from "@agent-smith/core"; const spec = getFeatureSpec("writer", "agent"); if (spec.found) { console.log(spec.path); // Full file path console.log(spec.ext); // File extension console.log(spec.variables); // Variable definitions } ``` Next: Tool Execution