@openai/agents-core
Version:
The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.
95 lines • 3.15 kB
JavaScript
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
import { dirname, join, resolve } from 'node:path';
import { parseSkillFrontmatter, } from "./capabilities/skills.mjs";
import { localDir } from "./entries/index.mjs";
import { isHostPathWithinRoot, sandboxPathGrantHostPath, } from "./shared/hostPath.mjs";
export function localDirLazySkillSource(srcOrOptions) {
const options = typeof srcOrOptions === 'string' ? { src: srcOrOptions } : srcOrOptions;
const sourceRoot = resolve(options.baseDir ?? process.cwd(), options.src);
return {
source: localDir({ src: sourceRoot }),
getIndex: (manifest) => discoverLocalDirSkillIndex(options, manifest.extraPathGrants),
};
}
function discoverLocalDirSkillIndex(options, sourceGrants = []) {
const base = resolve(options.baseDir ?? process.cwd());
let root;
try {
root = resolveLocalSkillSourcePath(options.src, base, sourceGrants);
}
catch {
return [];
}
if (hasLocalSourceSymlinkAncestor(root) || !isDirectory(root)) {
return [];
}
return readdirSync(root, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.sort((left, right) => left.name.localeCompare(right.name))
.flatMap((entry) => {
const skillMarkdownPath = join(root, entry.name, 'SKILL.md');
if (!isRegularFileWithoutSymlink(skillMarkdownPath)) {
return [];
}
let markdown;
try {
markdown = readFileSync(skillMarkdownPath, 'utf8');
}
catch {
return [];
}
const frontmatter = parseSkillFrontmatter(markdown);
return [
{
name: frontmatter.name ?? entry.name,
description: frontmatter.description ?? 'No description provided.',
path: entry.name,
},
];
});
}
function resolveLocalSkillSourcePath(sourcePath, base, sourceGrants) {
const resolvedSourcePath = resolve(base, sourcePath);
if (isHostPathWithinRoot(base, resolvedSourcePath) ||
sourceGrants.some((grant) => isHostPathWithinRoot(resolve(sandboxPathGrantHostPath(grant)), resolvedSourcePath))) {
return resolvedSourcePath;
}
throw new Error('local skill source is outside base directory');
}
function isDirectory(path) {
try {
return lstatSync(path).isDirectory();
}
catch {
return false;
}
}
function hasLocalSourceSymlinkAncestor(path) {
const resolvedPath = resolve(path);
let current = dirname(resolvedPath);
while (current !== dirname(current)) {
const parent = dirname(current);
if (parent === dirname(parent)) {
break;
}
try {
if (lstatSync(current).isSymbolicLink()) {
return true;
}
}
catch {
return false;
}
current = parent;
}
return false;
}
function isRegularFileWithoutSymlink(path) {
try {
return lstatSync(path).isFile();
}
catch {
return false;
}
}
//# sourceMappingURL=localSkills.mjs.map