@aaroncql/pim-agent 0.2.0 → 0.4.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 +11 -1
- package/package.json +6 -6
- package/src/extensions/apply-patch/coordinator.ts +25 -7
- package/src/extensions/apply-patch/index.ts +2 -1
- package/src/extensions/file-picker/FilePickerSuggestionEngine.ts +14 -0
- package/src/extensions/file-picker/InProcessFilePickerSuggestionEngine.ts +52 -0
- package/src/extensions/file-picker/WorkerFilePickerSuggestionEngine.ts +268 -0
- package/src/extensions/file-picker/catalog.ts +38 -33
- package/src/extensions/file-picker/filePickerWorker.ts +72 -0
- package/src/extensions/file-picker/filePickerWorkerMessages.ts +39 -0
- package/src/extensions/file-picker/index.ts +138 -83
- package/src/extensions/file-picker/ranker.ts +180 -12
- package/src/extensions/grep/grep.ts +45 -2
- package/src/extensions/web-search/ExaMcpClient.ts +20 -3
- package/src/shared/FileEnumerator.ts +492 -0
- package/src/shared/FileScanner.ts +15 -17
- package/src/shared/McpClient.ts +90 -28
- package/src/shared/RateLimiter.ts +50 -0
- package/src/telegram/Markdown.ts +82 -49
- package/src/telegram/Renderer.ts +37 -32
- package/src/telegram/SendFileTool.ts +5 -19
- package/src/telegram/Session.ts +1 -1
- package/src/shared/GitignoreFilter.ts +0 -142
package/src/telegram/Session.ts
CHANGED
|
@@ -498,7 +498,7 @@ export class Session {
|
|
|
498
498
|
}
|
|
499
499
|
const username = this.deps.getBotUsername();
|
|
500
500
|
const handle = username ? ` (@${username})` : "";
|
|
501
|
-
const systemIx = `You are running as a Telegram bot${handle} powered by Pim Agent. The telegram_user_instructions below are your editable instructions - edit the file at its \`path\` attribute to update your instructions.`;
|
|
501
|
+
const systemIx = `You are running as a Telegram bot${handle} powered by Pim Agent. The telegram_user_instructions below are your editable instructions - edit the file at its \`path\` attribute to update your instructions. Wrap LaTeX math in a \`\`\`math fenced block without the $$ delimitters; inline math is not supported.`;
|
|
502
502
|
const userIx = `<telegram_user_instructions path="${path}">${userContent ? `\n${userContent}\n` : ""}</telegram_user_instructions>`;
|
|
503
503
|
return `<telegram_system_instructions>\n${systemIx}\n${userIx}\n</telegram_system_instructions>`;
|
|
504
504
|
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { readFile, stat } from "node:fs/promises";
|
|
2
|
-
import { dirname, isAbsolute, parse, relative, resolve } from "node:path";
|
|
3
|
-
import ignore, { type Ignore } from "ignore";
|
|
4
|
-
import { FsErrors } from "./FsErrors";
|
|
5
|
-
import { Paths } from "./Paths";
|
|
6
|
-
|
|
7
|
-
type IgnoreMatcher = {
|
|
8
|
-
readonly baseDirectory: string;
|
|
9
|
-
readonly matcher: Ignore;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export class GitignoreFilter {
|
|
13
|
-
private static readonly alwaysIgnoredPatterns = [
|
|
14
|
-
".git/",
|
|
15
|
-
"node_modules/",
|
|
16
|
-
"dist/",
|
|
17
|
-
"build/",
|
|
18
|
-
"out/",
|
|
19
|
-
"target/",
|
|
20
|
-
"coverage/",
|
|
21
|
-
".next/",
|
|
22
|
-
".cache/",
|
|
23
|
-
".turbo/",
|
|
24
|
-
".vercel/",
|
|
25
|
-
".svelte-kit/",
|
|
26
|
-
] as const;
|
|
27
|
-
|
|
28
|
-
private readonly matchers: readonly IgnoreMatcher[];
|
|
29
|
-
|
|
30
|
-
private constructor(matchers: readonly IgnoreMatcher[]) {
|
|
31
|
-
this.matchers = matchers;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public static async for(root: string): Promise<GitignoreFilter> {
|
|
35
|
-
const absoluteRoot = resolve(root);
|
|
36
|
-
const rootDirectory =
|
|
37
|
-
await GitignoreFilter.containingDirectory(absoluteRoot);
|
|
38
|
-
const directories =
|
|
39
|
-
await GitignoreFilter.gitignoreDirectories(rootDirectory);
|
|
40
|
-
const contents = await Promise.all(
|
|
41
|
-
directories.map((directory) => GitignoreFilter.readGitignore(directory))
|
|
42
|
-
);
|
|
43
|
-
const matchers: IgnoreMatcher[] = [
|
|
44
|
-
{
|
|
45
|
-
baseDirectory: rootDirectory,
|
|
46
|
-
matcher: ignore().add([...GitignoreFilter.alwaysIgnoredPatterns]),
|
|
47
|
-
},
|
|
48
|
-
];
|
|
49
|
-
|
|
50
|
-
for (const [index, directory] of directories.entries()) {
|
|
51
|
-
const body = contents[index];
|
|
52
|
-
|
|
53
|
-
if (body !== undefined) {
|
|
54
|
-
matchers.push({
|
|
55
|
-
baseDirectory: directory,
|
|
56
|
-
matcher: ignore().add(body),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return new GitignoreFilter(matchers);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
public ignores(absolutePath: string): boolean {
|
|
65
|
-
if (!isAbsolute(absolutePath)) {
|
|
66
|
-
throw new Error(`Expected absolute path: ${absolutePath}`);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
for (const { baseDirectory, matcher } of this.matchers) {
|
|
70
|
-
const candidate = this.relativePath(baseDirectory, absolutePath);
|
|
71
|
-
|
|
72
|
-
if (candidate !== undefined && matcher.ignores(candidate)) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private static async containingDirectory(path: string): Promise<string> {
|
|
81
|
-
const metadata = await stat(path);
|
|
82
|
-
|
|
83
|
-
return metadata.isDirectory() ? path : dirname(path);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
private static async gitignoreDirectories(
|
|
87
|
-
root: string
|
|
88
|
-
): Promise<readonly string[]> {
|
|
89
|
-
const directories: string[] = [];
|
|
90
|
-
const filesystemRoot = parse(root).root;
|
|
91
|
-
let current = root;
|
|
92
|
-
|
|
93
|
-
while (true) {
|
|
94
|
-
directories.push(current);
|
|
95
|
-
|
|
96
|
-
if (await Bun.file(resolve(current, ".git")).exists()) {
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (current === filesystemRoot) {
|
|
101
|
-
break;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
current = dirname(current);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return directories;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
private static async readGitignore(
|
|
111
|
-
directory: string
|
|
112
|
-
): Promise<string | undefined> {
|
|
113
|
-
const path = resolve(directory, ".gitignore");
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
return await readFile(path, "utf8");
|
|
117
|
-
} catch (error) {
|
|
118
|
-
if (FsErrors.code(error) === "ENOENT") {
|
|
119
|
-
return undefined;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
throw error;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private relativePath(
|
|
127
|
-
baseDirectory: string,
|
|
128
|
-
absolutePath: string
|
|
129
|
-
): string | undefined {
|
|
130
|
-
const candidate = relative(baseDirectory, absolutePath);
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
candidate.length === 0 ||
|
|
134
|
-
candidate.startsWith("..") ||
|
|
135
|
-
isAbsolute(candidate)
|
|
136
|
-
) {
|
|
137
|
-
return undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return Paths.toForwardSlashes(candidate);
|
|
141
|
-
}
|
|
142
|
-
}
|