mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-03 20:41:07 +02:00
refactor agent yaml frontmatter parsing
This commit is contained in:
parent
a84caef043
commit
0b859d129e
2 changed files with 53 additions and 33 deletions
|
|
@ -4,7 +4,8 @@ import { glob } from "node:fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { Agent } from "@x/shared/dist/agent.js";
|
import { Agent } from "@x/shared/dist/agent.js";
|
||||||
import { parse, stringify } from "yaml";
|
import { stringify } from "yaml";
|
||||||
|
import { parseFrontmatter } from "../application/lib/parse-frontmatter.js";
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const UpdateAgentSchema = Agent.omit({ name: true });
|
const UpdateAgentSchema = Agent.omit({ name: true });
|
||||||
|
|
@ -33,7 +34,10 @@ export class FSAgentsRepo implements IAgentsRepo {
|
||||||
for (const file of matches) {
|
for (const file of matches) {
|
||||||
try {
|
try {
|
||||||
const agent = await this.parseAgentMd(path.join(this.agentsDir, file));
|
const agent = await this.parseAgentMd(path.join(this.agentsDir, file));
|
||||||
result.push(agent);
|
result.push({
|
||||||
|
...agent,
|
||||||
|
name: file.replace(/\.md$/, ""),
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error parsing agent ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
console.error(`Error parsing agent ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -42,44 +46,33 @@ export class FSAgentsRepo implements IAgentsRepo {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async parseAgentMd(filePath: string): Promise<z.infer<typeof Agent>> {
|
private async parseAgentMd(filepath: string): Promise<z.infer<typeof Agent>> {
|
||||||
const raw = await fs.readFile(filePath, "utf8");
|
const raw = await fs.readFile(filepath, "utf8");
|
||||||
|
|
||||||
// strip the path prefix from the file name
|
const { frontmatter, content } = parseFrontmatter(raw);
|
||||||
// and the .md extension
|
if (frontmatter) {
|
||||||
const agentName = filePath
|
const parsed = Agent
|
||||||
.replace(this.agentsDir + "/", "")
|
.omit({ instructions: true })
|
||||||
.replace(/\.md$/, "");
|
.parse(frontmatter);
|
||||||
let agent: z.infer<typeof Agent> = {
|
|
||||||
name: agentName,
|
|
||||||
instructions: raw,
|
|
||||||
};
|
|
||||||
let content = raw;
|
|
||||||
|
|
||||||
// check for frontmatter markers at start
|
return {
|
||||||
if (raw.startsWith("---")) {
|
...parsed,
|
||||||
const end = raw.indexOf("\n---", 3);
|
instructions: content,
|
||||||
|
};
|
||||||
if (end !== -1) {
|
|
||||||
const fm = raw.slice(3, end).trim(); // YAML text
|
|
||||||
content = raw.slice(end + 4).trim(); // body after frontmatter
|
|
||||||
const yaml = parse(fm);
|
|
||||||
const parsed = Agent
|
|
||||||
.omit({ name: true, instructions: true })
|
|
||||||
.parse(yaml);
|
|
||||||
agent = {
|
|
||||||
...agent,
|
|
||||||
...parsed,
|
|
||||||
instructions: content,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return agent;
|
return {
|
||||||
|
name: filepath,
|
||||||
|
instructions: raw,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetch(id: string): Promise<z.infer<typeof Agent>> {
|
async fetch(id: string): Promise<z.infer<typeof Agent>> {
|
||||||
return this.parseAgentMd(path.join(this.agentsDir, `${id}.md`));
|
const agent = await this.parseAgentMd(path.join(this.agentsDir, `${id}.md`));
|
||||||
|
return {
|
||||||
|
...agent,
|
||||||
|
name: id,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(agent: z.infer<typeof Agent>): Promise<void> {
|
async create(agent: z.infer<typeof Agent>): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { parse as parseYaml } from "yaml";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the YAML frontmatter from the input string. Returns the frontmatter and content.
|
||||||
|
* @param input - The input string to parse.
|
||||||
|
* @returns The frontmatter and content.
|
||||||
|
*/
|
||||||
|
export function parseFrontmatter(input: string): {
|
||||||
|
frontmatter: unknown | null;
|
||||||
|
content: string;
|
||||||
|
} {
|
||||||
|
if (input.startsWith("---")) {
|
||||||
|
const end = input.indexOf("\n---", 3);
|
||||||
|
|
||||||
|
if (end !== -1) {
|
||||||
|
const fm = input.slice(3, end).trim(); // YAML text
|
||||||
|
return {
|
||||||
|
frontmatter: parseYaml(fm),
|
||||||
|
content: input.slice(end + 4).trim(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
frontmatter: null,
|
||||||
|
content: input,
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue