diff --git a/packages/lmtask/package.json b/packages/lmtask/package.json index 0cf71d4..3477ea2 100644 --- a/packages/lmtask/package.json +++ b/packages/lmtask/package.json @@ -1,6 +1,6 @@ { "name": "@agent-smith/lmtask", - "version": "0.0.2", + "version": "0.0.5", "description": "An api to create human friendly agents: language model tasks module", "repository": "https://github.com/synw/agent-smith", "scripts": { @@ -15,7 +15,7 @@ "yaml": "^2.4.2" }, "devDependencies": { - "@agent-smith/brain": "^0.0.15", + "@agent-smith/brain": "^0.0.17", "@agent-smith/tmem-jobs": "^0.0.3", "@locallm/types": "^0.0.16", "@rollup/plugin-node-resolve": "^15.2.3", @@ -26,7 +26,7 @@ "rollup": "^4.18.0", "tslib": "^2.6.2", "typedoc": "^0.25.13", - "typedoc-plugin-markdown": "^4.0.2", + "typedoc-plugin-markdown": "^4.0.3", "typedoc-plugin-rename-defaults": "^0.7.0", "typescript": "^5.4.5" }, diff --git a/packages/lmtask/src/lmtask.ts b/packages/lmtask/src/lmtask.ts index f08c228..453405d 100644 --- a/packages/lmtask/src/lmtask.ts +++ b/packages/lmtask/src/lmtask.ts @@ -1,15 +1,76 @@ +import { default as fs } from "fs"; +import { default as path } from "path"; +import YAML from 'yaml'; import { type AgentBrain } from "@agent-smith/brain"; import { AgentTask, AgentTaskSpec, useAgentTask } from "@agent-smith/jobs"; import { PromptTemplate } from "modprompt"; -import { readTask } from "./utils.js"; +import { LmTask } from "./interfaces.js"; /** - * A hook that provides a language model task. + * `useLmTask` is a function that provides a set of utilities for managing language model tasks. * - * @param {AgentBrain} brain - The agent brain instance to use. - * @returns {{ read: (taskPath: string) => AgentTask }} + * @param {AgentBrain} brain - The brain object that contains the language model experts. + * @returns {{ + * init: (taskPath: string) => AgentTask, + * read: (taskPath: string) => { found: boolean, task: LmTask }, + * readDir: (dir: string) => Array + * }} An object containing the `init`, `read`, and `readDir` functions. + * + * @example + * const lmTask = useLmTask(brain); + * const task = lmTask.init('path/to/task'); + * const {task, found} = lmTask.read('path/to/task'); + * const tasks = lmTask.readDir('path/to/directory'); */ -const useLmTask = (brain: AgentBrain) => { +const useLmTask = (brain: AgentBrain): { + init: (taskPath: string) => AgentTask, + read: (taskPath: string) => { found: boolean, task: LmTask }, + readDir: (dir: string) => Array +} => { + /** + * Reads all files in a directory that have a .yml extension and returns an array of their filenames. + * @param {string} dir - The path to the directory containing the yaml files. + * @returns {Array} An array of filenames with a .yml extension found in the specified directory. + */ + const readDir = (dir: string): Array => { + const tasks = new Array(); + fs.readdirSync(dir).forEach((filename) => { + const filepath = path.join(dir, filename); + const isDir = fs.statSync(filepath).isDirectory(); + if (!isDir) { + if (filename.endsWith(".yml")) { + tasks.push(filename) + } + } + }); + return tasks + } + + /** + * Reads a task from a file. + * + * @param {string} taskpath - The path to the task file. + * @returns {{ found: boolean, task: LmTask }} An object containing whether or not the task was found and the task data itself. + * If no task is found at the provided path, an empty `LmTask` object will be returned. + * + * @example + * const {task, found} = readTask('/path/to/your/task.yml'); + * if (found) { + * console.log('Task Found:', task); + * } else { + * console.log('No Task Found at the provided path.'); + * } + */ + const read = (taskpath: string): { found: boolean, task: LmTask } => { + if (!fs.existsSync(taskpath)) { + return { task: {} as LmTask, found: false } + } + const file = fs.readFileSync(taskpath, 'utf8'); + const data = YAML.parse(file); + //console.log("READ TASK", data); + return { task: data, found: true } + } + /** * Reads a language model task from a file and returns an AgentTask object. * @@ -20,8 +81,8 @@ const useLmTask = (brain: AgentBrain) => { * const lmTask = useLmTask(brain); * const task = lmTask.read('path/to/task'); */ - const read = (taskPath: string): AgentTask => { - const { found, task } = readTask(taskPath); + const init = (taskPath: string): AgentTask => { + const { found, task } = read(taskPath); if (!found) { throw new Error(`Task ${taskPath} not found`) } @@ -30,7 +91,7 @@ const useLmTask = (brain: AgentBrain) => { id: task.name, title: task.description, run: async (params: { prompt: string }) => { - //let res: Record = {}; + //console.log("Running", task.name, "params:", params); const expert = brain.getExpertForModel(task.model.name); if (!expert) { return { error: `Expert for model ${task.model.name} not found` } @@ -52,7 +113,7 @@ const useLmTask = (brain: AgentBrain) => { if (task.template?.assistant) { tpl.afterAssistant(task.template.assistant) } - if (task.shots.length > 0) { + if (task.shots) { task.shots.forEach((s) => tpl.addShot(s.user, s.assistant)); } //const _p = task.prompt.replace("{prompt}", args[0]); @@ -76,7 +137,9 @@ const useLmTask = (brain: AgentBrain) => { } return { + init, read, + readDir, } } diff --git a/packages/lmtask/src/main.ts b/packages/lmtask/src/main.ts index c8d7fee..af7c7c6 100644 --- a/packages/lmtask/src/main.ts +++ b/packages/lmtask/src/main.ts @@ -1,4 +1,4 @@ -import { useLmTask } from "./lmtask"; +import { useLmTask } from "./lmtask.js"; import { TemplateSpec, LmTask } from "./interfaces.js"; export { diff --git a/packages/lmtask/src/utils.ts b/packages/lmtask/src/utils.ts index bd3ee84..2223a19 100644 --- a/packages/lmtask/src/utils.ts +++ b/packages/lmtask/src/utils.ts @@ -30,7 +30,7 @@ function readTasksDir(dir: string): Array { * If no task is found at the provided path, an empty `LmTask` object will be returned. * * @example - * const {task, found} = readTask('/path/to/your/task'); + * const {task, found} = readTask('/path/to/your/task.yml'); * if (found) { * console.log('Task Found:', task); * } else {