surgent 0.8.0-alpha.0 → 0.10.7
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/bin/build.mjs +53 -0
- package/bin/surgent.js +14 -13
- package/dist/optimizer/README.md +12 -4
- package/dist/optimizer/index.js +523 -1024
- package/dist/optimizer/index.js.map +4 -4
- package/dist/optimizer/package.json +2 -2
- package/package.json +11 -11
- package/src/agent/built-in/documenter.md +17 -17
- package/src/agent/built-in/general.md +70 -69
- package/src/agent/built-in/planner.md +13 -13
- package/src/agent/built-in/scout.md +17 -19
- package/src/agent/command.ts +76 -44
- package/src/agent/config.ts +167 -0
- package/src/agent/helpers.ts +44 -39
- package/src/agent/index.ts +32 -10
- package/src/agent/storage.ts +96 -186
- package/src/agent/types.ts +6 -0
- package/src/checkpoint/git.ts +12 -8
- package/src/checkpoint/index.ts +84 -20
- package/src/checkpoint/snapshot.ts +1 -1
- package/src/checkpoint/stage.ts +4 -2
- package/src/checkpoint/store.ts +6 -13
- package/src/cleanup/index.ts +1 -3
- package/src/commands/helpers.ts +7 -9
- package/src/commands/index.ts +1 -1
- package/src/commands/render.ts +14 -15
- package/src/optimizer/README.md +12 -4
- package/src/optimizer/deduplicator/index.ts +23 -13
- package/src/optimizer/deduplicator/resources.ts +35 -63
- package/src/optimizer/deduplicator/state.ts +48 -106
- package/src/optimizer/entries.ts +20 -99
- package/src/optimizer/index.ts +6 -7
- package/src/optimizer/inspector/helpers.ts +1 -19
- package/src/optimizer/inspector/index.ts +6 -7
- package/src/optimizer/inspector/inspect.ts +3 -14
- package/src/optimizer/languages/symbols.ts +2 -10
- package/src/optimizer/languages/types.ts +0 -4
- package/src/optimizer/languages/typescript.ts +6 -0
- package/src/optimizer/mapper/files.ts +60 -67
- package/src/optimizer/mapper/index.ts +91 -99
- package/src/optimizer/pruner/cleanup.ts +0 -89
- package/src/optimizer/pruner/index.ts +42 -33
- package/src/optimizer/reducer/bash.ts +100 -0
- package/src/optimizer/reducer/grep.ts +104 -0
- package/src/optimizer/reducer/index.ts +81 -0
- package/src/permission/constants.ts +2 -1
- package/src/permission/helpers.ts +14 -4
- package/src/permission/index.ts +8 -9
- package/src/permission/resolution.ts +26 -36
- package/src/permission/types.ts +2 -2
- package/src/questionnaire/component.ts +21 -12
- package/src/questionnaire/helpers.ts +11 -67
- package/src/questionnaire/index.ts +24 -11
- package/src/questionnaire/schemas.ts +12 -8
- package/src/questionnaire/types.ts +3 -3
- package/src/redactor/index.ts +30 -15
- package/src/redactor/patterns.ts +6 -6
- package/src/redactor/results.ts +156 -0
- package/src/redactor/secrets.ts +20 -64
- package/src/state.ts +3 -1
- package/src/subagent/helpers.ts +18 -9
- package/src/subagent/index.ts +57 -29
- package/src/subagent/sdk.ts +9 -5
- package/src/subagent/storage.ts +1 -2
- package/src/subagent/subsession.ts +46 -14
- package/src/subagent/types.ts +14 -7
- package/src/subagent/validation.ts +11 -54
- package/src/ui/components/bash-mode.ts +20 -12
- package/src/ui/components/frame.ts +4 -0
- package/src/ui/components/scrollable-view.ts +23 -7
- package/src/utils.ts +16 -6
- package/src/web-tools/providers/brave.ts +7 -2
- package/src/web-tools/providers/firecrawl.ts +47 -15
- package/src/web-tools/providers/index.ts +2 -2
- package/src/web-tools/providers/jina.ts +2 -1
- package/src/web-tools/providers/native.ts +2 -1
- package/src/web-tools/providers/tavily.ts +43 -22
- package/src/web-tools/web-fetch/index.ts +10 -11
- package/src/web-tools/web-fetch/storage.ts +17 -2
- package/src/web-tools/web-login/index.ts +10 -9
- package/src/web-tools/web-login/input.ts +55 -0
- package/src/web-tools/web-search/index.ts +3 -3
- package/src/cleanup/helpers.ts +0 -24
- package/src/cleanup/permission.ts +0 -76
- package/src/mcp-client/call-tool.ts +0 -143
- package/src/mcp-client/client.ts +0 -90
- package/src/mcp-client/command.ts +0 -257
- package/src/mcp-client/helpers.ts +0 -153
- package/src/mcp-client/index.ts +0 -21
- package/src/mcp-client/list-tools.ts +0 -84
- package/src/mcp-client/storage.ts +0 -190
- package/src/mcp-client/types.ts +0 -34
- package/src/mcp-client/validation.ts +0 -115
- package/src/optimizer/compactor/bash.ts +0 -141
- package/src/optimizer/compactor/grep.ts +0 -209
- package/src/optimizer/compactor/index.ts +0 -155
- package/src/optimizer/deduplicator/helpers.ts +0 -75
- package/src/optimizer/deduplicator/types.ts +0 -14
- package/src/optimizer/inspector/types.ts +0 -7
- package/src/optimizer/mapper/types.ts +0 -6
- package/src/optimizer/pruner/context.ts +0 -46
- package/src/optimizer/pruner/session.ts +0 -34
- package/src/optimizer/pruner/types.ts +0 -18
package/bin/build.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { build } from "esbuild";
|
|
2
|
+
import { copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const projectRoot = resolve(scriptDir, "..");
|
|
8
|
+
const optimizerDir = resolve(projectRoot, "dist", "optimizer");
|
|
9
|
+
const rootPackage = JSON.parse(await readFile(resolve(projectRoot, "package.json"), "utf8"));
|
|
10
|
+
|
|
11
|
+
await rm(optimizerDir, { recursive: true, force: true });
|
|
12
|
+
await mkdir(optimizerDir, { recursive: true });
|
|
13
|
+
await build({
|
|
14
|
+
entryPoints: [resolve(projectRoot, "src", "optimizer", "index.ts")],
|
|
15
|
+
outfile: resolve(optimizerDir, "index.js"),
|
|
16
|
+
bundle: true,
|
|
17
|
+
format: "esm",
|
|
18
|
+
packages: "external",
|
|
19
|
+
platform: "node",
|
|
20
|
+
sourcemap: true,
|
|
21
|
+
target: "node22",
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const optimizerPackage = {
|
|
25
|
+
name: "pi-optimizer",
|
|
26
|
+
version: rootPackage.version,
|
|
27
|
+
description: "Context optimization tools for pi coding agent",
|
|
28
|
+
type: "module",
|
|
29
|
+
main: "./index.js",
|
|
30
|
+
exports: "./index.js",
|
|
31
|
+
engines: rootPackage.engines,
|
|
32
|
+
license: rootPackage.license,
|
|
33
|
+
keywords: ["pi-package", "pi-coding-agent", "context-optimization"],
|
|
34
|
+
pi: { extensions: ["./index.js"] },
|
|
35
|
+
dependencies: {
|
|
36
|
+
picomatch: rootPackage.dependencies.picomatch,
|
|
37
|
+
"tree-sitter": rootPackage.dependencies["tree-sitter"],
|
|
38
|
+
},
|
|
39
|
+
peerDependencies: {
|
|
40
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
41
|
+
"@earendil-works/pi-tui": "*",
|
|
42
|
+
typebox: "*",
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
await Promise.all([
|
|
47
|
+
writeFile(resolve(optimizerDir, "package.json"), `${JSON.stringify(optimizerPackage, null, 2)}\n`),
|
|
48
|
+
copyFile(resolve(projectRoot, "LICENSE"), resolve(optimizerDir, "LICENSE")),
|
|
49
|
+
copyFile(
|
|
50
|
+
resolve(projectRoot, "src", "optimizer", "README.md"),
|
|
51
|
+
resolve(optimizerDir, "README.md"),
|
|
52
|
+
),
|
|
53
|
+
]);
|
package/bin/surgent.js
CHANGED
|
@@ -11,20 +11,22 @@ import { fileURLToPath } from "node:url";
|
|
|
11
11
|
process.title = "surgent";
|
|
12
12
|
const args = process.argv.slice(2);
|
|
13
13
|
|
|
14
|
+
const GLOBAL_PI_DIR = resolve(homedir(), ".pi", "agent");
|
|
14
15
|
const PACKAGE_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
16
|
const AGENT_ENTRY_URL = import.meta.resolve("@earendil-works/pi-coding-agent");
|
|
16
17
|
const LOCAL_PI_SUBDIRS = ["agents", "plans"];
|
|
18
|
+
const GLOBAL_PI_SUBDIRS = ["agents", "grammars"];
|
|
17
19
|
const BASE_TOOLS = ["ls", "find", "grep", "code_map", "inspect", "read"];
|
|
18
20
|
const BUILT_IN_META = {
|
|
19
21
|
documenter: {
|
|
20
|
-
tools: [
|
|
22
|
+
tools: BASE_TOOLS.concat(["edit", "write", "questionnaire"]),
|
|
21
23
|
"files.write": ["**/*.md"],
|
|
22
24
|
},
|
|
23
25
|
planner: {
|
|
24
|
-
tools: [
|
|
26
|
+
tools: BASE_TOOLS.concat(["web_fetch", "web_search", "questionnaire"]),
|
|
25
27
|
},
|
|
26
28
|
scout: {
|
|
27
|
-
tools: [
|
|
29
|
+
tools: BASE_TOOLS.concat(["web_fetch", "web_search"]),
|
|
28
30
|
},
|
|
29
31
|
};
|
|
30
32
|
|
|
@@ -33,9 +35,8 @@ function isMissingFileError(error) {
|
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
async function initBuiltInMeta() {
|
|
36
|
-
const settingsPath = resolve(
|
|
38
|
+
const settingsPath = resolve(GLOBAL_PI_DIR, "settings.json");
|
|
37
39
|
let settings;
|
|
38
|
-
|
|
39
40
|
try {
|
|
40
41
|
settings = JSON.parse(await readFile(settingsPath, "utf8"));
|
|
41
42
|
} catch (error) {
|
|
@@ -129,7 +130,7 @@ async function syncPiIgnore(cwd) {
|
|
|
129
130
|
return;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
await writeFile(piIgnorePath, gitIgnoreContents);
|
|
133
|
+
await writeFile(piIgnorePath, `.pi\n\n${gitIgnoreContents}`);
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
function isJsonModeActive(args) {
|
|
@@ -195,16 +196,16 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
195
196
|
await runRewrittenHelp(args);
|
|
196
197
|
} else {
|
|
197
198
|
const cwd = process.cwd();
|
|
199
|
+
const srcDir = resolve(PACKAGE_DIR, "src");
|
|
198
200
|
if (!isJsonModeActive(args)) {
|
|
199
|
-
await ensurePiExcluded(cwd);
|
|
200
|
-
await syncPiIgnore(cwd);
|
|
201
|
-
}
|
|
202
|
-
for (const localPiSubdir of LOCAL_PI_SUBDIRS) {
|
|
203
|
-
await mkdir(resolve(cwd, ".pi", localPiSubdir), { recursive: true });
|
|
201
|
+
await Promise.all([ensurePiExcluded(cwd), syncPiIgnore(cwd)]);
|
|
204
202
|
}
|
|
203
|
+
const [entries] = await Promise.all([
|
|
204
|
+
readdir(srcDir, { withFileTypes: true }),
|
|
205
|
+
...LOCAL_PI_SUBDIRS.map((dir) => mkdir(resolve(cwd, ".pi", dir), { recursive: true })),
|
|
206
|
+
...GLOBAL_PI_SUBDIRS.map((dir) => mkdir(resolve(GLOBAL_PI_DIR, dir), { recursive: true })),
|
|
207
|
+
]);
|
|
205
208
|
|
|
206
|
-
const srcDir = resolve(PACKAGE_DIR, "src");
|
|
207
|
-
const entries = await readdir(srcDir, { withFileTypes: true });
|
|
208
209
|
const extensionArgs = entries
|
|
209
210
|
.filter((entry) => entry.isDirectory())
|
|
210
211
|
.flatMap((entry) => ["--extension", resolve(srcDir, entry.name)]);
|
package/dist/optimizer/README.md
CHANGED
|
@@ -13,13 +13,21 @@ Long coding sessions accumulate large tool results, repeated file content, and o
|
|
|
13
13
|
- Adds `code_map`, which uses Tree-sitter to index symbols and declarations before files are read in full.
|
|
14
14
|
- Adds `inspect`, which returns one selected symbol body for targeted code reading and edits.
|
|
15
15
|
- Supports TypeScript, JavaScript, Python, Go, Java, and Rust code navigation.
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
16
|
+
- Losslessly compresses consecutive Bash lines with at most one varying alphanumeric token: `status {204, 404, 500}`. Order, duplicates, and raw bytes remain recoverable; `{{` / `}}` escape literal braces. Compression applies only when shorter. Bash output limits still apply.
|
|
17
|
+
- Reduces grep output during execution by grouping matches under file paths.
|
|
18
|
+
- Filters older eligible `inspect` exchanges and pre-write `read`/`inspect` exchanges from model requests using a session-start snapshot.
|
|
19
|
+
- Persistently prunes eligible error and empty tool results, together with their tool calls, through append-only context edits.
|
|
20
20
|
|
|
21
21
|
These changes reduce context growth, improve prompt-cache reuse, and leave more room for requirements, code, and reasoning.
|
|
22
22
|
|
|
23
|
+
## Context filtering
|
|
24
|
+
|
|
25
|
+
At `session_start`, optimizer snapshots the current branch. For model requests only, it hides older eligible `inspect` exchanges for the same normalized file path and exact returned symbol, and older same-file `read`/`inspect` exchanges superseded by a successful `write`. Both tool calls and results are hidden. There is no general `read` deduplication, and edits or shell commands do not invalidate earlier results.
|
|
26
|
+
|
|
27
|
+
Changes after startup are deferred until the next session start. Session tree navigation clears the snapshot. This transient filtering leaves raw history, the TUI, exports, and Pi's canonical context for native compaction unchanged.
|
|
28
|
+
|
|
29
|
+
Separately, when the agent settles after successful completion, eligible error results (except Bash errors) and recognized empty `ls`/`find` results are pruned with their tool calls through persistent, append-only context edits. These change future model context without rewriting raw history.
|
|
30
|
+
|
|
23
31
|
## Requirements
|
|
24
32
|
|
|
25
33
|
- Node.js 22.19 or newer
|