mono/packages/kbot/dist-in/commands/run.js

204 lines
18 KiB
JavaScript

import * as path from 'node:path';
import { hasMagic } from 'glob';
import { sync as dir } from '@polymech/fs/dir';
import { sync as exists } from '@polymech/fs/exists';
import { sync as write } from '@polymech/fs/write';
import { sync as read } from '@polymech/fs/read';
import { forward_slash, resolve, isFile, pathInfoEx } from '@polymech/commons';
import { isArray, isString } from '@polymech/core/primitives';
import { Logger } from 'tslog';
import { createClient } from '../client.js';
import { OptionsSchema } from '../zod_schema.js';
import { get } from '../source.js';
import { flatten } from '../utils/array.js';
import { collector } from '../collector.js';
import { load as loadProfile } from '../profile.js';
import { load as loadTools } from '../tools.js';
import { preferences, prompt } from '../prompt.js';
import { variables } from '../variables.js';
import { E_Mode } from '../zod_schema.js';
import { runCompletion } from './run-completion.js';
import { runTools } from './run-tools.js';
import { runAssistant } from './run-assistant.js';
import { all } from '../models/index.js';
import { getLogger } from '../index.js';
export const processRun = async (opts) => {
let options = null;
const logger = getLogger(opts);
opts.logger = logger;
const target = path.resolve(opts.output || opts.path);
if (!exists(target)) {
dir(target);
}
opts.disable = flatten(opts.disable);
opts.disableTools = flatten(opts.disableTools);
opts.include = flatten(opts.include);
opts.variables = await loadProfile(opts);
try {
options = OptionsSchema().parse(opts);
}
catch (error) {
logger.error('Failed to parse options:', error.message, error.issues);
return;
}
const client = createClient(options);
options.variables = { ...options.variables, ...variables(options) };
if (!client) {
logger.error('Failed to create client');
return;
}
options.client = client;
options.collector = collector(options, client);
options.onRun = options.onRun || (async (options) => options);
let messages = [];
const promptMessage = await prompt(opts);
if (!promptMessage.content) {
return "";
}
messages.push(promptMessage);
messages.push(await preferences(opts));
let files = await get(path.resolve(options.path), options.include) || [];
files = files.map(f => { return { ...f, role: 'user' }; });
messages = [...messages, ...files];
const params = {
model: options.model,
messages,
tools: []
};
if (options.mode === E_Mode.TOOLS || options.mode === E_Mode.ASSISTANT) {
params.tools = await loadTools(options);
params.tool_choice = 'auto';
params.parallel_tool_calls = false;
}
const logDir = path.resolve(resolve(opts.logs));
const paramsPath = path.join(logDir, 'params.json');
write(paramsPath, JSON.stringify({ ...params }, null, 2));
logger.debug(`kbot run ${options.mode} : ${options.model} @ ${options.router} : ${files.length} files from project ${path.resolve(options.path)} with ${options.include}`, files.map(f => f.path), params.tools.map(t => `${t.function.name} : ${t.function.description}`));
let ret = null;
options = await options.onRun(options) || options;
try {
switch (options.mode) {
case E_Mode.COMPLETION:
ret = await runCompletion(client, params, options);
break;
case E_Mode.TOOLS:
ret = await runTools(client, params, options);
break;
case E_Mode.ASSISTANT:
ret = await runAssistant(client, params, options);
break;
default:
throw new Error(`Unsupported mode: ${options.mode}`);
}
}
catch (e) {
logger.error(`Error running ${options.mode} mode: ${e.message}`);
}
opts.variables['LAST'] = ret;
return ret;
};
/**
* Extract file paths (Windows or POSIX style) from a single string,
* preserving any spaces within the paths. Needed for Salamand File Manager selections (eg: kbot "summarize, as json" -i "$(ListOfSelectedFullNames)")
* - For Windows, it looks for patterns like "C:\" (any drive letter).
* - For POSIX, it looks for a leading slash "/".
*
* Returns an array of path strings. If no matches are found, returns [].
*
*/
function extractPaths(input) {
if (exists(path.resolve(resolve(input)))) {
return [input];
}
// Matches either a Windows drive pattern like "C:\" or a forward slash "/".
// Parentheses group with `|` to match either part correctly.
const pathStartRegex = /([A-Za-z]:\\)|\//g;
const matchIndices = [];
let match;
// Collect the start index of each path
while ((match = pathStartRegex.exec(input)) !== null) {
matchIndices.push(match.index);
}
// If none found, return empty
if (!matchIndices.length) {
return [];
}
// Slice from each index to just before the next
const paths = [];
for (let i = 0; i < matchIndices.length; i++) {
const start = matchIndices[i];
const end = i < matchIndices.length - 1 ? matchIndices[i + 1] : input.length;
const path = input.substring(start, end).trim();
if (path) {
paths.push(path);
}
}
return paths;
}
function flattenArrays(arrays) {
return arrays.reduce((accumulator, current) => {
return accumulator.concat(current);
}, []);
}
export const run = async (opts) => {
const ret = [];
const logger = new Logger({
minLevel: opts.logLevel
});
if (opts.include) {
if (isString(opts.include)) {
opts.include = [opts.include];
}
if (isArray(opts.include)) {
opts.include = flattenArrays(opts.include.map(extractPaths));
}
opts.include = Array.from(new Set(opts.include));
}
else {
opts.include = [];
}
if (opts.each) {
let items = [];
if (isArray(opts.each)) {
items = opts.each;
}
else if (exists(opts.each) && isFile(opts.each) && path.parse(opts.each).ext === '.json') {
items = read(opts.each, 'json') || [];
}
else if (hasMagic(opts.each)) {
const info = pathInfoEx(forward_slash(path.resolve(resolve(opts.each))));
items = info.FILES;
}
else if (isFile(opts.each) && exists(opts.each)) {
items = [opts.each];
}
else if (isString(opts.each)) {
items = opts.each.split(',');
}
if (items.length === 0) {
logger.warn(`No files matching pattern ${opts.each} found in ${opts.path}`);
return ret;
}
logger.info(`Processing ${items.length} items matching pattern ${opts.each}...`);
const _models = all();
for (const item of items) {
const itemOpts = {
...opts,
ITEM: item,
variables: { ITEM: item }
};
//override model if item is a model id
const model = _models.find(m => m.id === item);
if (model) {
itemOpts.model = item;
}
itemOpts.include = [...opts.include, ...[forward_slash(item)]];
ret.push(await processRun(itemOpts));
}
}
else {
ret.push(await processRun(opts));
}
return ret;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL3J1bi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssSUFBSSxNQUFNLFdBQVcsQ0FBQTtBQUNqQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sTUFBTSxDQUFBO0FBQy9CLE9BQU8sRUFBRSxJQUFJLElBQUksR0FBRyxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDOUMsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsSUFBSSxJQUFJLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDaEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQzlFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUE7QUFLN0QsT0FBTyxFQUFFLE1BQU0sRUFBVyxNQUFNLE9BQU8sQ0FBQTtBQUN2QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQzNDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ2xDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDM0MsT0FBTyxFQUFFLElBQUksSUFBSSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUE7QUFDbkQsT0FBTyxFQUFFLElBQUksSUFBSSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFB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