tinker-agent 1.3.0 → 1.5.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/CHANGELOG.md +39 -1
- package/README.md +271 -72
- package/bin/tinker.js +75 -25
- package/package.json +12 -3
- package/src/agent/runtime-session.ts +113 -15
- package/src/cli/command-line.ts +291 -0
- package/src/cli/config.ts +158 -262
- package/src/cli/index.ts +33 -21
- package/src/cli/main.ts +213 -0
- package/src/cli/model-profiles.ts +226 -72
- package/src/cli/output.ts +113 -0
- package/src/cli/package-metadata.ts +36 -0
- package/src/cli/prompt-source.ts +229 -0
- package/src/cli/public-cli-contract.ts +69 -0
- package/src/cli/public-config-contract.ts +732 -0
- package/src/cli/run-runner.ts +17 -12
- package/src/cli/runner-dependencies.ts +108 -0
- package/src/cli/tui-memory.ts +67 -0
- package/src/cli/tui-runner.tsx +79 -49
- package/src/context/context-policy.ts +2 -2
- package/src/events/stdout-event-printer.ts +1 -0
- package/src/mcp/mcp-manager.ts +2 -19
- package/src/mcp/mcp-tool-executor.ts +3 -4
- package/src/memory/contracts.ts +148 -0
- package/src/memory/embedding-client.ts +105 -0
- package/src/memory/memory-coordinator.ts +556 -0
- package/src/memory/memory-extractor.ts +231 -0
- package/src/memory/memory-log.ts +88 -0
- package/src/memory/memory-search-tool.ts +100 -0
- package/src/memory/memory-store.ts +687 -0
- package/src/memory/vector.ts +153 -0
- package/src/model/fake-model-client.ts +971 -3
- package/src/model/model-context-profile.ts +0 -30
- package/src/observation/observation-builder.ts +20 -0
- package/src/session/session-store.ts +123 -0
- package/src/tools/bash.ts +8 -25
- package/src/tools/grep.ts +9 -1
- package/src/tools/registry.ts +19 -1
- package/src/tools/ripgrep.ts +24 -27
- package/src/tools/types.ts +16 -0
- package/src/tools/web-fetch/index.ts +2 -15
- package/src/tui/app.tsx +72 -2
- package/src/tui/clipboard.ts +22 -0
- package/src/tui/components/footer.tsx +9 -4
- package/src/tui/components/memory-browser.tsx +151 -0
- package/src/tui/components/prompt-input.tsx +6 -3
- package/src/tui/event-store.ts +9 -2
- package/src/tui/slash-commands.ts +88 -24
- package/src/tui/workspace-file-search.ts +78 -71
|
@@ -1,90 +1,97 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
2
|
import { RIPGREP_MISSING_ERROR, findRipgrepCommand } from "../tools/ripgrep";
|
|
3
|
-
|
|
4
|
-
const FILE_SEARCH_TIMEOUT_MS = 20_000;
|
|
5
|
-
const FILE_SEARCH_MAX_BUFFER_BYTES = 20_000_000;
|
|
3
|
+
import { DEFAULT_PUBLIC_TOOLING_CONFIG } from "../cli/public-config-contract";
|
|
6
4
|
|
|
7
5
|
export type WorkspaceFileLister = (
|
|
8
6
|
workspaceRoot: string,
|
|
9
7
|
signal: AbortSignal,
|
|
10
8
|
) => Promise<readonly string[]>;
|
|
11
9
|
|
|
12
|
-
export
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
export type WorkspaceFileListerOptions = {
|
|
11
|
+
readonly command?: string;
|
|
12
|
+
readonly timeoutMs?: number;
|
|
13
|
+
readonly maxBufferBytes?: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function createWorkspaceFileLister(
|
|
17
|
+
options: WorkspaceFileListerOptions = {},
|
|
18
|
+
): WorkspaceFileLister {
|
|
19
|
+
const command = findRipgrepCommand(options.command);
|
|
20
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_PUBLIC_TOOLING_CONFIG.grepTimeoutMs;
|
|
21
|
+
const maxBufferBytes =
|
|
22
|
+
options.maxBufferBytes ?? DEFAULT_PUBLIC_TOOLING_CONFIG.grepMaxBufferBytes;
|
|
23
|
+
|
|
24
|
+
return (workspaceRoot, signal) =>
|
|
25
|
+
new Promise((resolve, reject) => {
|
|
26
|
+
if (signal.aborted) {
|
|
27
|
+
reject(new Error("Workspace file search was cancelled."));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
execFile(
|
|
32
|
+
command,
|
|
33
|
+
[
|
|
34
|
+
"--files",
|
|
35
|
+
"--hidden",
|
|
36
|
+
"--glob",
|
|
37
|
+
"!**/node_modules/**",
|
|
38
|
+
"--glob",
|
|
39
|
+
"!**/.git/**",
|
|
40
|
+
"--glob",
|
|
41
|
+
"!**/.tinker/**",
|
|
42
|
+
],
|
|
43
|
+
{
|
|
44
|
+
cwd: workspaceRoot,
|
|
45
|
+
encoding: "utf8",
|
|
46
|
+
maxBuffer: maxBufferBytes,
|
|
47
|
+
signal,
|
|
48
|
+
timeout: timeoutMs,
|
|
49
|
+
},
|
|
50
|
+
(error, stdout, stderr) => {
|
|
51
|
+
if (signal.aborted) {
|
|
52
|
+
reject(error ?? new Error("Workspace file search was cancelled."));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
56
|
+
if (error === null) {
|
|
57
|
+
resolve(splitPaths(stdout));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
48
60
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
const execError = error as Error & {
|
|
62
|
+
code?: number | string;
|
|
63
|
+
killed?: boolean;
|
|
64
|
+
signal?: string | null;
|
|
65
|
+
};
|
|
54
66
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
if (execError.code === 1 && stderr.trim() === "") {
|
|
68
|
+
resolve(splitPaths(stdout));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
if (execError.code === "ENOENT") {
|
|
73
|
+
reject(new Error(RIPGREP_MISSING_ERROR));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
64
76
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
),
|
|
70
|
-
);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
77
|
+
if (execError.killed === true || typeof execError.signal === "string") {
|
|
78
|
+
reject(new Error(`Workspace file search timed out after ${timeoutMs}ms.`));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
+
if (execError.message.includes("maxBuffer")) {
|
|
83
|
+
reject(new Error(`Workspace file list exceeded ${maxBufferBytes} bytes.`));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const detail = stderr.trim() === "" ? execError.message : stderr.trim();
|
|
88
|
+
reject(new Error(`Workspace file search failed: ${detail}`));
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
82
93
|
|
|
83
|
-
|
|
84
|
-
reject(new Error(`Workspace file search failed: ${detail}`));
|
|
85
|
-
},
|
|
86
|
-
);
|
|
87
|
-
});
|
|
94
|
+
export const listWorkspaceFiles = createWorkspaceFileLister();
|
|
88
95
|
|
|
89
96
|
function splitPaths(stdout: string): string[] {
|
|
90
97
|
return stdout
|