@cuylabs/agent-core 0.4.0 → 0.6.0
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.
- package/README.md +81 -323
- package/dist/builder-BKkipazh.d.ts +34 -0
- package/dist/capabilities/index.d.ts +97 -0
- package/dist/capabilities/index.js +46 -0
- package/dist/chunk-3C4VKG4P.js +2149 -0
- package/dist/chunk-6TDTQJ4P.js +116 -0
- package/dist/chunk-7MUFEN4K.js +559 -0
- package/dist/chunk-BDBZ3SLK.js +745 -0
- package/dist/chunk-DWYX7ASF.js +26 -0
- package/dist/chunk-FG4MD5MU.js +54 -0
- package/dist/chunk-IVUJDISU.js +556 -0
- package/dist/chunk-LRHOS4ZN.js +584 -0
- package/dist/chunk-O2ZCFQL6.js +764 -0
- package/dist/chunk-P6YF7USR.js +182 -0
- package/dist/chunk-QAQADS4X.js +258 -0
- package/dist/chunk-QWFMX226.js +879 -0
- package/dist/{chunk-6VKLWNRE.js → chunk-SDSBEQXG.js} +1 -132
- package/dist/chunk-VBWWUHWI.js +724 -0
- package/dist/chunk-VEKUXUVF.js +41 -0
- package/dist/chunk-X635CM2F.js +305 -0
- package/dist/chunk-YUUJK53A.js +91 -0
- package/dist/chunk-ZXAKHMWH.js +283 -0
- package/dist/config-D2xeGEHK.d.ts +52 -0
- package/dist/context/index.d.ts +259 -0
- package/dist/context/index.js +26 -0
- package/dist/identifiers-BLUxFqV_.d.ts +12 -0
- package/dist/index-DZQJD_hp.d.ts +1067 -0
- package/dist/index-ipP3_ztp.d.ts +198 -0
- package/dist/index.d.ts +210 -5736
- package/dist/index.js +2132 -7767
- package/dist/mcp/index.d.ts +26 -0
- package/dist/mcp/index.js +14 -0
- package/dist/messages-BYWGn8TY.d.ts +110 -0
- package/dist/middleware/index.d.ts +8 -0
- package/dist/middleware/index.js +12 -0
- package/dist/models/index.d.ts +33 -0
- package/dist/models/index.js +12 -0
- package/dist/network-D76DS5ot.d.ts +5 -0
- package/dist/prompt/index.d.ts +225 -0
- package/dist/prompt/index.js +45 -0
- package/dist/reasoning/index.d.ts +71 -0
- package/dist/reasoning/index.js +47 -0
- package/dist/registry-CuRWWtcT.d.ts +164 -0
- package/dist/resolver-DOfZ-xuk.d.ts +254 -0
- package/dist/runner-G1wxEgac.d.ts +852 -0
- package/dist/runtime/index.d.ts +357 -0
- package/dist/runtime/index.js +64 -0
- package/dist/session-manager-Uawm2Le7.d.ts +274 -0
- package/dist/skill/index.d.ts +103 -0
- package/dist/skill/index.js +39 -0
- package/dist/storage/index.d.ts +167 -0
- package/dist/storage/index.js +50 -0
- package/dist/sub-agent/index.d.ts +14 -0
- package/dist/sub-agent/index.js +15 -0
- package/dist/tool/index.d.ts +174 -1
- package/dist/tool/index.js +12 -3
- package/dist/tool-DYp6-cC3.d.ts +239 -0
- package/dist/tool-pFAnJc5Y.d.ts +419 -0
- package/dist/tracker-DClqYqTj.d.ts +96 -0
- package/dist/tracking/index.d.ts +109 -0
- package/dist/tracking/index.js +20 -0
- package/dist/types-BWo810L_.d.ts +648 -0
- package/dist/types-CQaXbRsS.d.ts +47 -0
- package/dist/types-VQgymC1N.d.ts +156 -0
- package/package.json +89 -5
- package/dist/index-BlSTfS-W.d.ts +0 -470
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// src/models/identifiers.ts
|
|
2
|
+
function getModelId(model) {
|
|
3
|
+
if (typeof model === "string") return model;
|
|
4
|
+
if (typeof model === "object" && model !== null && "modelId" in model) {
|
|
5
|
+
return String(model.modelId);
|
|
6
|
+
}
|
|
7
|
+
return String(model);
|
|
8
|
+
}
|
|
9
|
+
function getProviderId(model) {
|
|
10
|
+
if (typeof model === "string") {
|
|
11
|
+
if (model.includes("/")) {
|
|
12
|
+
return model.split("/")[0];
|
|
13
|
+
}
|
|
14
|
+
return void 0;
|
|
15
|
+
}
|
|
16
|
+
if (typeof model === "object" && model !== null && "provider" in model) {
|
|
17
|
+
const provider = String(model.provider);
|
|
18
|
+
return provider.split(".")[0];
|
|
19
|
+
}
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
getModelId,
|
|
25
|
+
getProviderId
|
|
26
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractFilePathsFromArgs,
|
|
3
|
+
shouldCaptureBaseline
|
|
4
|
+
} from "./chunk-VEKUXUVF.js";
|
|
5
|
+
|
|
6
|
+
// src/tool/executor.ts
|
|
7
|
+
async function executeAgentToolCall(options) {
|
|
8
|
+
const initialized = await options.tool.init({ cwd: options.cwd });
|
|
9
|
+
const ctx = {
|
|
10
|
+
cwd: options.cwd,
|
|
11
|
+
abort: options.abort,
|
|
12
|
+
sessionID: options.sessionID,
|
|
13
|
+
messageID: options.messageID,
|
|
14
|
+
agent: options.agent ?? "default",
|
|
15
|
+
...options.host ? { host: options.host } : {},
|
|
16
|
+
...options.turnTracker ? { turnTracker: options.turnTracker } : {}
|
|
17
|
+
};
|
|
18
|
+
if (options.middleware?.hasMiddleware) {
|
|
19
|
+
const decision = await options.middleware.runBeforeToolCall(
|
|
20
|
+
options.toolName,
|
|
21
|
+
options.params,
|
|
22
|
+
ctx
|
|
23
|
+
);
|
|
24
|
+
if (decision.action === "deny") {
|
|
25
|
+
return {
|
|
26
|
+
output: decision.reason ?? `Tool call denied: ${options.toolName}`
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options.turnTracker && initialized.fileOps && shouldCaptureBaseline(initialized.fileOps)) {
|
|
31
|
+
const paths = extractFilePathsFromArgs(
|
|
32
|
+
options.params,
|
|
33
|
+
initialized.fileOps
|
|
34
|
+
);
|
|
35
|
+
for (const path of paths) {
|
|
36
|
+
await options.turnTracker.beforeWrite(path);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const result = await initialized.execute(options.params, ctx);
|
|
40
|
+
if (options.middleware?.hasMiddleware) {
|
|
41
|
+
const transformed = await options.middleware.runAfterToolCall(
|
|
42
|
+
options.toolName,
|
|
43
|
+
options.params,
|
|
44
|
+
result,
|
|
45
|
+
ctx
|
|
46
|
+
);
|
|
47
|
+
return { output: transformed.output };
|
|
48
|
+
}
|
|
49
|
+
return { output: result.output };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
executeAgentToolCall
|
|
54
|
+
};
|
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSkillRegistry,
|
|
3
|
+
emptySkillRegistry
|
|
4
|
+
} from "./chunk-LRHOS4ZN.js";
|
|
5
|
+
|
|
6
|
+
// src/prompt/templates.ts
|
|
7
|
+
function extractModelId(model) {
|
|
8
|
+
if (typeof model === "string") return model;
|
|
9
|
+
if (typeof model === "object" && model !== null && "modelId" in model) {
|
|
10
|
+
return String(model.modelId);
|
|
11
|
+
}
|
|
12
|
+
return void 0;
|
|
13
|
+
}
|
|
14
|
+
function extractProvider(model) {
|
|
15
|
+
if (typeof model === "object" && model !== null && "provider" in model) {
|
|
16
|
+
return String(model.provider);
|
|
17
|
+
}
|
|
18
|
+
return void 0;
|
|
19
|
+
}
|
|
20
|
+
function detectModelFamily(model) {
|
|
21
|
+
const provider = extractProvider(model);
|
|
22
|
+
const modelId = extractModelId(model);
|
|
23
|
+
if (provider) {
|
|
24
|
+
const p = provider.toLowerCase();
|
|
25
|
+
if (p.startsWith("anthropic")) return "anthropic";
|
|
26
|
+
if (p.startsWith("openai") || p.startsWith("azure")) return "openai";
|
|
27
|
+
if (p.startsWith("google") || p.startsWith("vertex")) return "google";
|
|
28
|
+
if (p.startsWith("deepseek")) return "deepseek";
|
|
29
|
+
}
|
|
30
|
+
if (modelId) {
|
|
31
|
+
const id = modelId.toLowerCase();
|
|
32
|
+
if (/claude/.test(id)) return "anthropic";
|
|
33
|
+
if (/gpt|o1-|o3-|o4-|chatgpt/.test(id)) return "openai";
|
|
34
|
+
if (/gemini|palm/.test(id)) return "google";
|
|
35
|
+
if (/deepseek/.test(id)) return "deepseek";
|
|
36
|
+
}
|
|
37
|
+
return "default";
|
|
38
|
+
}
|
|
39
|
+
var TEMPLATE_ANTHROPIC = `You are a capable AI assistant with access to tools.
|
|
40
|
+
|
|
41
|
+
<approach>
|
|
42
|
+
- Think through problems carefully before taking action
|
|
43
|
+
- Break complex tasks into smaller, verifiable steps
|
|
44
|
+
- Gather context and information before making decisions
|
|
45
|
+
- If uncertain, investigate first rather than guessing
|
|
46
|
+
- Verify results after each action
|
|
47
|
+
</approach>
|
|
48
|
+
|
|
49
|
+
<tool-usage>
|
|
50
|
+
- Use the tools available to you to accomplish tasks
|
|
51
|
+
- Choose the most appropriate tool for each step
|
|
52
|
+
- Review tool output before proceeding to the next step
|
|
53
|
+
- If a tool fails, try an alternative approach \u2014 do not give up after one error
|
|
54
|
+
- Keep iterating until the task is fully resolved or all options are exhausted
|
|
55
|
+
</tool-usage>
|
|
56
|
+
|
|
57
|
+
<communication>
|
|
58
|
+
- Be concise and direct in responses
|
|
59
|
+
- Explain the reasoning behind important decisions
|
|
60
|
+
- If a task cannot be completed, explain clearly what's blocking it
|
|
61
|
+
- Proactively mention potential issues or risks
|
|
62
|
+
</communication>`;
|
|
63
|
+
var TEMPLATE_OPENAI = `You are a capable AI assistant with access to tools.
|
|
64
|
+
|
|
65
|
+
## Approach
|
|
66
|
+
1. Think through problems step by step before acting
|
|
67
|
+
2. Break complex tasks into smaller steps and validate each one
|
|
68
|
+
3. Gather context and information before making decisions
|
|
69
|
+
4. When uncertain, investigate rather than guess
|
|
70
|
+
5. Verify results after each action
|
|
71
|
+
|
|
72
|
+
## Tool Usage
|
|
73
|
+
1. Use the most appropriate tool for each step
|
|
74
|
+
2. Review tool output before proceeding
|
|
75
|
+
3. If a tool fails, try an alternative approach \u2014 do not give up after one error
|
|
76
|
+
4. Combine tools effectively to accomplish complex tasks
|
|
77
|
+
5. Keep iterating until the task is fully resolved or all options are exhausted
|
|
78
|
+
|
|
79
|
+
## Communication
|
|
80
|
+
- Be direct and concise
|
|
81
|
+
- Explain your reasoning for important decisions
|
|
82
|
+
- Flag potential issues or risks proactively
|
|
83
|
+
- If blocked, explain clearly what's needed`;
|
|
84
|
+
var TEMPLATE_GOOGLE = `You are a capable AI assistant with access to tools.
|
|
85
|
+
|
|
86
|
+
**Approach:**
|
|
87
|
+
- Think through problems carefully before taking action
|
|
88
|
+
- Break complex tasks into smaller, verifiable steps
|
|
89
|
+
- Gather context before making decisions
|
|
90
|
+
- When uncertain, investigate rather than guess
|
|
91
|
+
- Verify results after each action
|
|
92
|
+
|
|
93
|
+
**Tool Usage:**
|
|
94
|
+
- Choose the most appropriate tool for each step
|
|
95
|
+
- Review tool output before proceeding
|
|
96
|
+
- If a tool fails, try an alternative approach \u2014 do not give up after one error
|
|
97
|
+
- Keep iterating until the task is fully resolved or all options are exhausted
|
|
98
|
+
|
|
99
|
+
**Communication:**
|
|
100
|
+
- Be concise and direct
|
|
101
|
+
- Explain your reasoning for important decisions
|
|
102
|
+
- Proactively mention potential issues or risks`;
|
|
103
|
+
var TEMPLATE_DEEPSEEK = `You are a capable AI assistant with access to tools.
|
|
104
|
+
|
|
105
|
+
Principles:
|
|
106
|
+
- Reason carefully before taking action
|
|
107
|
+
- Break complex tasks into smaller steps
|
|
108
|
+
- Gather context and verify assumptions
|
|
109
|
+
- Use tools effectively \u2014 choose the right one for each step
|
|
110
|
+
- If a tool fails, try an alternative \u2014 do not give up after one error
|
|
111
|
+
- Keep iterating until the task is fully resolved
|
|
112
|
+
- Verify results after each action
|
|
113
|
+
|
|
114
|
+
Communication:
|
|
115
|
+
- Be concise and direct
|
|
116
|
+
- Focus on reasoning and results
|
|
117
|
+
- Flag risks or issues proactively`;
|
|
118
|
+
var TEMPLATE_DEFAULT = `You are a capable AI assistant with access to tools.
|
|
119
|
+
|
|
120
|
+
Guidelines:
|
|
121
|
+
- Think through problems step by step before taking action
|
|
122
|
+
- Break complex tasks into smaller, verifiable steps
|
|
123
|
+
- Gather context and information before making decisions
|
|
124
|
+
- Use the most appropriate tool for each step
|
|
125
|
+
- If a tool fails, try an alternative \u2014 do not give up after one error
|
|
126
|
+
- Keep iterating until the task is fully resolved or all options are exhausted
|
|
127
|
+
- Verify results after each action
|
|
128
|
+
- Be concise and direct in communication
|
|
129
|
+
- Proactively mention potential issues or risks`;
|
|
130
|
+
var TEMPLATES = {
|
|
131
|
+
anthropic: TEMPLATE_ANTHROPIC,
|
|
132
|
+
openai: TEMPLATE_OPENAI,
|
|
133
|
+
google: TEMPLATE_GOOGLE,
|
|
134
|
+
deepseek: TEMPLATE_DEEPSEEK,
|
|
135
|
+
default: TEMPLATE_DEFAULT
|
|
136
|
+
};
|
|
137
|
+
function getTemplate(family) {
|
|
138
|
+
return TEMPLATES[family] ?? TEMPLATES.default;
|
|
139
|
+
}
|
|
140
|
+
function getAvailableFamilies() {
|
|
141
|
+
return Object.keys(TEMPLATES);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/prompt/environment.ts
|
|
145
|
+
import { execSync } from "child_process";
|
|
146
|
+
import { platform, arch } from "os";
|
|
147
|
+
import { basename, resolve } from "path";
|
|
148
|
+
function runQuiet(command, cwd) {
|
|
149
|
+
try {
|
|
150
|
+
return execSync(command, {
|
|
151
|
+
cwd,
|
|
152
|
+
encoding: "utf-8",
|
|
153
|
+
timeout: 3e3,
|
|
154
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
155
|
+
}).trim();
|
|
156
|
+
} catch {
|
|
157
|
+
return void 0;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function formatPlatform() {
|
|
161
|
+
const os = platform();
|
|
162
|
+
const cpu = arch();
|
|
163
|
+
const names = {
|
|
164
|
+
darwin: "macOS",
|
|
165
|
+
linux: "Linux",
|
|
166
|
+
win32: "Windows",
|
|
167
|
+
freebsd: "FreeBSD"
|
|
168
|
+
};
|
|
169
|
+
return `${names[os] ?? os} (${os} ${cpu})`;
|
|
170
|
+
}
|
|
171
|
+
function formatDate() {
|
|
172
|
+
const now = /* @__PURE__ */ new Date();
|
|
173
|
+
return now.toLocaleDateString("en-US", {
|
|
174
|
+
weekday: "long",
|
|
175
|
+
year: "numeric",
|
|
176
|
+
month: "long",
|
|
177
|
+
day: "numeric",
|
|
178
|
+
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function gatherEnvironment(cwd) {
|
|
182
|
+
const resolvedCwd = resolve(cwd);
|
|
183
|
+
const gitBranch = runQuiet("git branch --show-current", resolvedCwd);
|
|
184
|
+
const gitStatus = runQuiet("git status --porcelain", resolvedCwd);
|
|
185
|
+
const gitRoot = runQuiet("git rev-parse --show-toplevel", resolvedCwd);
|
|
186
|
+
return {
|
|
187
|
+
cwd: resolvedCwd,
|
|
188
|
+
platform: formatPlatform(),
|
|
189
|
+
date: formatDate(),
|
|
190
|
+
shell: process.env.SHELL ?? process.env.COMSPEC,
|
|
191
|
+
gitBranch: gitBranch || void 0,
|
|
192
|
+
gitClean: gitStatus !== void 0 ? gitStatus.length === 0 : void 0,
|
|
193
|
+
gitRoot: gitRoot || void 0
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function formatEnvironment(info) {
|
|
197
|
+
const lines = [];
|
|
198
|
+
lines.push("<workspace>");
|
|
199
|
+
lines.push(`Directory: ${info.cwd}`);
|
|
200
|
+
lines.push(`Project: ${basename(info.cwd)}`);
|
|
201
|
+
lines.push(`Platform: ${info.platform}`);
|
|
202
|
+
lines.push(`Date: ${info.date}`);
|
|
203
|
+
if (info.shell) {
|
|
204
|
+
lines.push(`Shell: ${info.shell}`);
|
|
205
|
+
}
|
|
206
|
+
if (info.gitBranch) {
|
|
207
|
+
const status = info.gitClean ? "clean" : "uncommitted changes";
|
|
208
|
+
lines.push(`Git: ${info.gitBranch} (${status})`);
|
|
209
|
+
}
|
|
210
|
+
lines.push("</workspace>");
|
|
211
|
+
return lines.join("\n");
|
|
212
|
+
}
|
|
213
|
+
function summarizeEnvironment(info) {
|
|
214
|
+
const parts = [basename(info.cwd)];
|
|
215
|
+
if (info.gitBranch) parts.push(`[${info.gitBranch}]`);
|
|
216
|
+
parts.push(info.platform);
|
|
217
|
+
return parts.join(" \xB7 ");
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/prompt/instructions.ts
|
|
221
|
+
import { readFile, stat, access } from "fs/promises";
|
|
222
|
+
import { dirname, join, resolve as resolve2, basename as basename2, sep } from "path";
|
|
223
|
+
import { homedir } from "os";
|
|
224
|
+
var DEFAULT_INSTRUCTION_PATTERNS = [
|
|
225
|
+
"AGENTS.md",
|
|
226
|
+
"CLAUDE.md",
|
|
227
|
+
"COPILOT.md",
|
|
228
|
+
".cuylabs/instructions.md"
|
|
229
|
+
];
|
|
230
|
+
var DEFAULT_MAX_FILE_SIZE = 51200;
|
|
231
|
+
var DEFAULT_MAX_DEPTH = 10;
|
|
232
|
+
async function fileExists(path) {
|
|
233
|
+
try {
|
|
234
|
+
await access(path);
|
|
235
|
+
return true;
|
|
236
|
+
} catch {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function readInstructionFile(path, maxSize) {
|
|
241
|
+
try {
|
|
242
|
+
const info = await stat(path);
|
|
243
|
+
if (!info.isFile() || info.size > maxSize) return void 0;
|
|
244
|
+
const content = await readFile(path, "utf-8");
|
|
245
|
+
return content.trim();
|
|
246
|
+
} catch {
|
|
247
|
+
return void 0;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async function findGitRoot(startDir) {
|
|
251
|
+
let dir = resolve2(startDir);
|
|
252
|
+
const root = sep === "/" ? "/" : dir.slice(0, 3);
|
|
253
|
+
while (dir !== root && dir !== homedir()) {
|
|
254
|
+
if (await fileExists(join(dir, ".git"))) {
|
|
255
|
+
return dir;
|
|
256
|
+
}
|
|
257
|
+
const parent = dirname(dir);
|
|
258
|
+
if (parent === dir) break;
|
|
259
|
+
dir = parent;
|
|
260
|
+
}
|
|
261
|
+
return void 0;
|
|
262
|
+
}
|
|
263
|
+
async function discoverInstructions(cwd, patterns = DEFAULT_INSTRUCTION_PATTERNS, options) {
|
|
264
|
+
const maxDepth = options?.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
265
|
+
const maxSize = options?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
|
|
266
|
+
const stopAtGit = options?.stopAtGitRoot ?? false;
|
|
267
|
+
const resolvedCwd = resolve2(cwd);
|
|
268
|
+
const home = homedir();
|
|
269
|
+
const root = sep === "/" ? "/" : resolvedCwd.slice(0, 3);
|
|
270
|
+
const gitRoot = await findGitRoot(resolvedCwd);
|
|
271
|
+
const found = [];
|
|
272
|
+
let currentDir = resolvedCwd;
|
|
273
|
+
let depth = 0;
|
|
274
|
+
while (depth <= maxDepth) {
|
|
275
|
+
if (currentDir === home || currentDir === root) break;
|
|
276
|
+
if (stopAtGit && gitRoot && currentDir === dirname(gitRoot)) break;
|
|
277
|
+
for (const pattern of patterns) {
|
|
278
|
+
const filePath = join(currentDir, pattern);
|
|
279
|
+
const content = await readInstructionFile(filePath, maxSize);
|
|
280
|
+
if (content && content.length > 0) {
|
|
281
|
+
let source;
|
|
282
|
+
if (depth === 0) {
|
|
283
|
+
source = "project";
|
|
284
|
+
} else if (gitRoot && currentDir === gitRoot) {
|
|
285
|
+
source = "workspace";
|
|
286
|
+
} else {
|
|
287
|
+
source = "workspace";
|
|
288
|
+
}
|
|
289
|
+
found.push({ path: filePath, content, source, depth });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const parent = dirname(currentDir);
|
|
293
|
+
if (parent === currentDir) break;
|
|
294
|
+
currentDir = parent;
|
|
295
|
+
depth++;
|
|
296
|
+
}
|
|
297
|
+
found.reverse();
|
|
298
|
+
return found;
|
|
299
|
+
}
|
|
300
|
+
async function loadGlobalInstructions(paths, maxSize = DEFAULT_MAX_FILE_SIZE) {
|
|
301
|
+
const results = [];
|
|
302
|
+
for (const filePath of paths) {
|
|
303
|
+
const content = await readInstructionFile(resolve2(filePath), maxSize);
|
|
304
|
+
if (content && content.length > 0) {
|
|
305
|
+
results.push({
|
|
306
|
+
path: resolve2(filePath),
|
|
307
|
+
content,
|
|
308
|
+
source: "global",
|
|
309
|
+
depth: -1
|
|
310
|
+
// global = before all local files
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return results;
|
|
315
|
+
}
|
|
316
|
+
function formatInstructions(files, basePath) {
|
|
317
|
+
if (files.length === 0) return "";
|
|
318
|
+
const blocks = [];
|
|
319
|
+
blocks.push("<project-instructions>");
|
|
320
|
+
for (const file of files) {
|
|
321
|
+
const displayPath = basePath ? file.path.replace(basePath + sep, "").replace(basePath, "") : basename2(file.path);
|
|
322
|
+
blocks.push("");
|
|
323
|
+
blocks.push(`<instructions source="${displayPath}" scope="${file.source}">`);
|
|
324
|
+
blocks.push(file.content);
|
|
325
|
+
blocks.push("</instructions>");
|
|
326
|
+
}
|
|
327
|
+
blocks.push("");
|
|
328
|
+
blocks.push("</project-instructions>");
|
|
329
|
+
return blocks.join("\n");
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/prompt/builder/priorities.ts
|
|
333
|
+
var PRIORITY_BASE = 10;
|
|
334
|
+
var PRIORITY_ENVIRONMENT = 20;
|
|
335
|
+
var PRIORITY_INSTRUCTIONS = 30;
|
|
336
|
+
var PRIORITY_CUSTOM = 50;
|
|
337
|
+
var PRIORITY_SKILLS = 70;
|
|
338
|
+
var PRIORITY_OVERRIDE = 90;
|
|
339
|
+
|
|
340
|
+
// src/prompt/builder/sections.ts
|
|
341
|
+
async function composePromptSections(options) {
|
|
342
|
+
const { config, context, customSections, middleware, sources } = options;
|
|
343
|
+
const sections = [];
|
|
344
|
+
const family = config.modelFamily ?? detectModelFamily(context.model);
|
|
345
|
+
const templateContent = config.baseTemplate ?? getTemplate(family);
|
|
346
|
+
sections.push({
|
|
347
|
+
id: "base",
|
|
348
|
+
label: "Base Template",
|
|
349
|
+
content: templateContent,
|
|
350
|
+
priority: PRIORITY_BASE
|
|
351
|
+
});
|
|
352
|
+
if (config.includeEnvironment) {
|
|
353
|
+
const envInfo = sources.getEnvironment(context.cwd);
|
|
354
|
+
sections.push({
|
|
355
|
+
id: "environment",
|
|
356
|
+
label: "Environment",
|
|
357
|
+
content: formatEnvironment(envInfo),
|
|
358
|
+
priority: PRIORITY_ENVIRONMENT
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
if (config.includeInstructions) {
|
|
362
|
+
const instructionFiles = await sources.getInstructions(context.cwd);
|
|
363
|
+
if (instructionFiles.length > 0) {
|
|
364
|
+
sections.push({
|
|
365
|
+
id: "instructions",
|
|
366
|
+
label: "Project Instructions",
|
|
367
|
+
content: formatInstructions(instructionFiles, context.cwd),
|
|
368
|
+
priority: PRIORITY_INSTRUCTIONS
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (config.skills) {
|
|
373
|
+
const registry = await sources.getSkillRegistry(context.cwd);
|
|
374
|
+
const summary = registry.formatSummary();
|
|
375
|
+
if (summary.length > 0) {
|
|
376
|
+
sections.push({
|
|
377
|
+
id: "skills",
|
|
378
|
+
label: "Available Skills",
|
|
379
|
+
content: summary,
|
|
380
|
+
priority: PRIORITY_SKILLS
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
for (const section of customSections) {
|
|
385
|
+
sections.push(section);
|
|
386
|
+
}
|
|
387
|
+
if (middleware?.hasMiddleware) {
|
|
388
|
+
sections.push(...middleware.collectPromptSections(context));
|
|
389
|
+
}
|
|
390
|
+
if (context.override) {
|
|
391
|
+
sections.push({
|
|
392
|
+
id: "override",
|
|
393
|
+
label: "Additional Context",
|
|
394
|
+
content: context.override,
|
|
395
|
+
priority: PRIORITY_OVERRIDE
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
sections.sort(
|
|
399
|
+
(left, right) => (left.priority ?? PRIORITY_CUSTOM) - (right.priority ?? PRIORITY_CUSTOM)
|
|
400
|
+
);
|
|
401
|
+
return sections;
|
|
402
|
+
}
|
|
403
|
+
async function previewPromptSections(options) {
|
|
404
|
+
const sections = await composePromptSections(options);
|
|
405
|
+
return sections.filter((section) => section.enabled !== false).map((section) => ({
|
|
406
|
+
id: section.id,
|
|
407
|
+
label: section.label,
|
|
408
|
+
priority: section.priority ?? PRIORITY_CUSTOM,
|
|
409
|
+
size: section.content.length
|
|
410
|
+
}));
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// src/prompt/builder/builder.ts
|
|
414
|
+
var PromptBuilder = class {
|
|
415
|
+
config;
|
|
416
|
+
customSections = /* @__PURE__ */ new Map();
|
|
417
|
+
envCache;
|
|
418
|
+
instructionCache;
|
|
419
|
+
skillRegistryCache;
|
|
420
|
+
constructor(config) {
|
|
421
|
+
this.config = {
|
|
422
|
+
includeEnvironment: true,
|
|
423
|
+
includeInstructions: true,
|
|
424
|
+
separator: "\n\n",
|
|
425
|
+
...config
|
|
426
|
+
};
|
|
427
|
+
if (config?.sections) {
|
|
428
|
+
for (const section of config.sections) {
|
|
429
|
+
this.customSections.set(section.id, section);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
async build(context, middleware) {
|
|
434
|
+
const sections = await composePromptSections({
|
|
435
|
+
config: this.config,
|
|
436
|
+
context,
|
|
437
|
+
customSections: this.customSections.values(),
|
|
438
|
+
middleware,
|
|
439
|
+
sources: {
|
|
440
|
+
getEnvironment: (cwd) => this.getEnvironment(cwd),
|
|
441
|
+
getInstructions: (cwd) => this.getInstructions(cwd),
|
|
442
|
+
getSkillRegistry: (cwd) => this.getSkillRegistry(cwd)
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
return sections.filter((section) => section.enabled !== false).map((section) => section.content).filter((content) => content.length > 0).join(this.config.separator);
|
|
446
|
+
}
|
|
447
|
+
addSection(section) {
|
|
448
|
+
this.customSections.set(section.id, section);
|
|
449
|
+
}
|
|
450
|
+
removeSection(id) {
|
|
451
|
+
return this.customSections.delete(id);
|
|
452
|
+
}
|
|
453
|
+
toggleSection(id, enabled) {
|
|
454
|
+
const section = this.customSections.get(id);
|
|
455
|
+
if (section) {
|
|
456
|
+
section.enabled = enabled;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
getSections() {
|
|
460
|
+
return Array.from(this.customSections.values());
|
|
461
|
+
}
|
|
462
|
+
hasSection(id) {
|
|
463
|
+
return this.customSections.has(id);
|
|
464
|
+
}
|
|
465
|
+
clearCache() {
|
|
466
|
+
this.envCache = void 0;
|
|
467
|
+
this.instructionCache = void 0;
|
|
468
|
+
this.skillRegistryCache = void 0;
|
|
469
|
+
}
|
|
470
|
+
async getSkillRegistry(cwd) {
|
|
471
|
+
if (this.skillRegistryCache && this.skillRegistryCache.cwd === cwd) {
|
|
472
|
+
return this.skillRegistryCache.registry;
|
|
473
|
+
}
|
|
474
|
+
if (!this.config.skills) {
|
|
475
|
+
const registry2 = emptySkillRegistry();
|
|
476
|
+
this.skillRegistryCache = { cwd, registry: registry2 };
|
|
477
|
+
return registry2;
|
|
478
|
+
}
|
|
479
|
+
const registry = await createSkillRegistry(cwd, this.config.skills);
|
|
480
|
+
this.skillRegistryCache = { cwd, registry };
|
|
481
|
+
return registry;
|
|
482
|
+
}
|
|
483
|
+
getModelFamily(model) {
|
|
484
|
+
return this.config.modelFamily ?? detectModelFamily(model);
|
|
485
|
+
}
|
|
486
|
+
getBaseTemplate(model) {
|
|
487
|
+
const family = this.getModelFamily(model);
|
|
488
|
+
return this.config.baseTemplate ?? getTemplate(family);
|
|
489
|
+
}
|
|
490
|
+
async preview(context, middleware) {
|
|
491
|
+
return await previewPromptSections({
|
|
492
|
+
config: this.config,
|
|
493
|
+
context,
|
|
494
|
+
customSections: this.customSections.values(),
|
|
495
|
+
middleware,
|
|
496
|
+
sources: {
|
|
497
|
+
getEnvironment: (cwd) => this.getEnvironment(cwd),
|
|
498
|
+
getInstructions: (cwd) => this.getInstructions(cwd),
|
|
499
|
+
getSkillRegistry: (cwd) => this.getSkillRegistry(cwd)
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
getEnvironment(cwd) {
|
|
504
|
+
if (this.envCache && this.envCache.cwd === cwd) {
|
|
505
|
+
return this.envCache.info;
|
|
506
|
+
}
|
|
507
|
+
const info = gatherEnvironment(cwd);
|
|
508
|
+
this.envCache = { cwd, info };
|
|
509
|
+
return info;
|
|
510
|
+
}
|
|
511
|
+
async getInstructions(cwd) {
|
|
512
|
+
if (this.instructionCache && this.instructionCache.cwd === cwd) {
|
|
513
|
+
return this.instructionCache.files;
|
|
514
|
+
}
|
|
515
|
+
const patterns = this.config.instructionPatterns ?? DEFAULT_INSTRUCTION_PATTERNS;
|
|
516
|
+
const maxDepth = this.config.instructionMaxDepth;
|
|
517
|
+
const maxFileSize = this.config.instructionMaxSize;
|
|
518
|
+
const localFiles = await discoverInstructions(cwd, patterns, {
|
|
519
|
+
maxDepth,
|
|
520
|
+
maxFileSize
|
|
521
|
+
});
|
|
522
|
+
const globalFiles = this.config.globalInstructions ? await loadGlobalInstructions(
|
|
523
|
+
this.config.globalInstructions,
|
|
524
|
+
maxFileSize
|
|
525
|
+
) : [];
|
|
526
|
+
const allFiles = [...globalFiles, ...localFiles];
|
|
527
|
+
this.instructionCache = { cwd, files: allFiles };
|
|
528
|
+
return allFiles;
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
function createPromptBuilder(config) {
|
|
532
|
+
return new PromptBuilder(config);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
export {
|
|
536
|
+
detectModelFamily,
|
|
537
|
+
getTemplate,
|
|
538
|
+
getAvailableFamilies,
|
|
539
|
+
gatherEnvironment,
|
|
540
|
+
formatEnvironment,
|
|
541
|
+
summarizeEnvironment,
|
|
542
|
+
DEFAULT_INSTRUCTION_PATTERNS,
|
|
543
|
+
DEFAULT_MAX_FILE_SIZE,
|
|
544
|
+
DEFAULT_MAX_DEPTH,
|
|
545
|
+
discoverInstructions,
|
|
546
|
+
loadGlobalInstructions,
|
|
547
|
+
formatInstructions,
|
|
548
|
+
PRIORITY_BASE,
|
|
549
|
+
PRIORITY_ENVIRONMENT,
|
|
550
|
+
PRIORITY_INSTRUCTIONS,
|
|
551
|
+
PRIORITY_CUSTOM,
|
|
552
|
+
PRIORITY_SKILLS,
|
|
553
|
+
PRIORITY_OVERRIDE,
|
|
554
|
+
PromptBuilder,
|
|
555
|
+
createPromptBuilder
|
|
556
|
+
};
|