e2e-ai 1.4.3 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,117 @@
1
+ import {
2
+ getPackageRoot,
3
+ getProjectRoot
4
+ } from "./cli-kx32qnf3.js";
5
+
6
+ // src/agents/loadAgent.ts
7
+ import { readFileSync, existsSync, readdirSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ function resolveAgentFile(dir, agentName) {
10
+ const exact = join(dir, `${agentName}.md`);
11
+ if (existsSync(exact))
12
+ return exact;
13
+ try {
14
+ const files = readdirSync(dir);
15
+ const suffix = `.${agentName}.md`;
16
+ const match = files.find((f) => f.endsWith(suffix));
17
+ if (match)
18
+ return join(dir, match);
19
+ } catch {}
20
+ return null;
21
+ }
22
+ function loadAgent(agentName, config) {
23
+ const localDir = join(getProjectRoot(), ".e2e-ai", "agents");
24
+ const packageDir = join(getPackageRoot(), "agents");
25
+ const filePath = resolveAgentFile(localDir, agentName) ?? resolveAgentFile(packageDir, agentName);
26
+ if (!filePath) {
27
+ throw new Error(`Agent file not found for "${agentName}" in ${localDir} or ${packageDir}`);
28
+ }
29
+ let content;
30
+ try {
31
+ content = readFileSync(filePath, "utf-8");
32
+ } catch {
33
+ throw new Error(`Agent file not readable: ${filePath}`);
34
+ }
35
+ const { frontmatter, body } = parseFrontmatter(content);
36
+ const agentConfig = extractConfig(frontmatter);
37
+ let systemPrompt = body;
38
+ if (config) {
39
+ const contextPath = join(getProjectRoot(), ".e2e-ai", "context.md");
40
+ if (existsSync(contextPath)) {
41
+ const projectContext = readFileSync(contextPath, "utf-8").trim();
42
+ if (projectContext) {
43
+ systemPrompt = `${body}
44
+
45
+ ## Project Context
46
+
47
+ ${projectContext}`;
48
+ }
49
+ }
50
+ if (config.llm.agentModels[agentName]) {
51
+ agentConfig.model = config.llm.agentModels[agentName];
52
+ }
53
+ }
54
+ const sections = parseSections(body);
55
+ return {
56
+ name: frontmatter.agent ?? agentName,
57
+ systemPrompt,
58
+ inputSchema: sections["Input Schema"],
59
+ outputSchema: sections["Output Schema"],
60
+ rules: sections["Rules"],
61
+ example: sections["Example"],
62
+ config: agentConfig
63
+ };
64
+ }
65
+ function parseFrontmatter(content) {
66
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
67
+ if (!match)
68
+ return { frontmatter: {}, body: content };
69
+ const frontmatter = {};
70
+ for (const line of match[1].split(`
71
+ `)) {
72
+ const colonIdx = line.indexOf(":");
73
+ if (colonIdx === -1)
74
+ continue;
75
+ const key = line.slice(0, colonIdx).trim();
76
+ let value = line.slice(colonIdx + 1).trim();
77
+ if (value.startsWith('"') && value.endsWith('"'))
78
+ value = value.slice(1, -1);
79
+ if (value === "true")
80
+ value = true;
81
+ if (value === "false")
82
+ value = false;
83
+ if (!isNaN(Number(value)) && value !== "")
84
+ value = Number(value);
85
+ frontmatter[key] = value;
86
+ }
87
+ return { frontmatter, body: match[2] };
88
+ }
89
+ function extractConfig(frontmatter) {
90
+ return {
91
+ model: frontmatter.model,
92
+ maxTokens: frontmatter.max_tokens ?? 4096,
93
+ temperature: frontmatter.temperature ?? 0.2
94
+ };
95
+ }
96
+ function parseSections(body) {
97
+ const sections = {};
98
+ const headingRegex = /^##\s+(.+)$/gm;
99
+ const headings = [];
100
+ let match;
101
+ while ((match = headingRegex.exec(body)) !== null) {
102
+ headings.push({ title: match[1].trim(), index: match.index });
103
+ }
104
+ const systemMatch = body.match(/^#\s+System Prompt\n([\s\S]*?)(?=\n##\s|$)/m);
105
+ if (systemMatch) {
106
+ sections["System Prompt"] = systemMatch[1].trim();
107
+ }
108
+ for (let i = 0;i < headings.length; i++) {
109
+ const start = headings[i].index + body.slice(headings[i].index).indexOf(`
110
+ `) + 1;
111
+ const end = i + 1 < headings.length ? headings[i + 1].index : body.length;
112
+ sections[headings[i].title] = body.slice(start, end).trim();
113
+ }
114
+ return sections;
115
+ }
116
+
117
+ export { loadAgent };