@oh-my-pi/pi-coding-agent 13.19.0 → 14.0.3
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 +277 -2
- package/package.json +86 -20
- package/scripts/format-prompts.ts +2 -2
- package/src/autoresearch/apply-contract-to-state.ts +24 -0
- package/src/autoresearch/contract.ts +0 -44
- package/src/autoresearch/dashboard.ts +1 -2
- package/src/autoresearch/git.ts +91 -0
- package/src/autoresearch/helpers.ts +49 -0
- package/src/autoresearch/index.ts +28 -187
- package/src/autoresearch/prompt.md +26 -9
- package/src/autoresearch/state.ts +0 -6
- package/src/autoresearch/tools/init-experiment.ts +202 -117
- package/src/autoresearch/tools/log-experiment.ts +83 -125
- package/src/autoresearch/tools/run-experiment.ts +48 -10
- package/src/autoresearch/types.ts +2 -2
- package/src/capability/index.ts +4 -2
- package/src/cli/file-processor.ts +3 -3
- package/src/cli/grep-cli.ts +8 -8
- package/src/cli/grievances-cli.ts +78 -0
- package/src/cli/read-cli.ts +67 -0
- package/src/cli/setup-cli.ts +4 -4
- package/src/cli/update-cli.ts +3 -3
- package/src/cli.ts +2 -0
- package/src/commands/grep.ts +6 -1
- package/src/commands/grievances.ts +20 -0
- package/src/commands/read.ts +33 -0
- package/src/commit/agentic/agent.ts +5 -5
- package/src/commit/agentic/index.ts +3 -4
- package/src/commit/agentic/tools/analyze-file.ts +3 -3
- package/src/commit/agentic/validation.ts +1 -1
- package/src/commit/analysis/conventional.ts +4 -4
- package/src/commit/analysis/summary.ts +3 -3
- package/src/commit/changelog/generate.ts +4 -4
- package/src/commit/map-reduce/map-phase.ts +4 -4
- package/src/commit/map-reduce/reduce-phase.ts +4 -4
- package/src/commit/pipeline.ts +3 -4
- package/src/config/model-registry.ts +17 -3
- package/src/config/prompt-templates.ts +44 -226
- package/src/config/resolve-config-value.ts +4 -2
- package/src/config/settings-schema.ts +54 -2
- package/src/config/settings.ts +25 -26
- package/src/dap/client.ts +674 -0
- package/src/dap/config.ts +150 -0
- package/src/dap/defaults.json +211 -0
- package/src/dap/index.ts +4 -0
- package/src/dap/session.ts +1255 -0
- package/src/dap/types.ts +600 -0
- package/src/debug/log-viewer.ts +3 -2
- package/src/discovery/builtin.ts +1 -2
- package/src/discovery/codex.ts +2 -2
- package/src/discovery/github.ts +2 -1
- package/src/discovery/helpers.ts +2 -2
- package/src/discovery/opencode.ts +2 -2
- package/src/edit/diff.ts +818 -0
- package/src/edit/index.ts +309 -0
- package/src/edit/line-hash.ts +67 -0
- package/src/edit/modes/chunk.ts +454 -0
- package/src/{patch → edit/modes}/hashline.ts +741 -361
- package/src/{patch/applicator.ts → edit/modes/patch.ts} +420 -117
- package/src/{patch/fuzzy.ts → edit/modes/replace.ts} +519 -197
- package/src/{patch → edit}/normalize.ts +97 -76
- package/src/{patch/shared.ts → edit/renderer.ts} +181 -108
- package/src/exec/bash-executor.ts +4 -2
- package/src/exec/idle-timeout-watchdog.ts +126 -0
- package/src/exec/non-interactive-env.ts +5 -0
- package/src/extensibility/custom-commands/bundled/ci-green/index.ts +2 -2
- package/src/extensibility/custom-commands/bundled/review/index.ts +36 -15
- package/src/extensibility/custom-commands/loader.ts +1 -2
- package/src/extensibility/custom-tools/loader.ts +34 -11
- package/src/extensibility/extensions/loader.ts +9 -4
- package/src/extensibility/extensions/runner.ts +24 -1
- package/src/extensibility/extensions/types.ts +1 -1
- package/src/extensibility/hooks/loader.ts +5 -6
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/extensibility/plugins/doctor.ts +2 -1
- package/src/extensibility/slash-commands.ts +3 -7
- package/src/index.ts +2 -1
- package/src/internal-urls/docs-index.generated.ts +11 -11
- package/src/ipy/executor.ts +58 -17
- package/src/ipy/gateway-coordinator.ts +6 -4
- package/src/ipy/kernel.ts +45 -22
- package/src/ipy/runtime.ts +2 -2
- package/src/lsp/client.ts +7 -4
- package/src/lsp/clients/lsp-linter-client.ts +4 -4
- package/src/lsp/config.ts +20 -4
- package/src/lsp/defaults.json +688 -154
- package/src/lsp/index.ts +234 -45
- package/src/lsp/lspmux.ts +2 -2
- package/src/lsp/startup-events.ts +13 -0
- package/src/lsp/types.ts +12 -1
- package/src/lsp/utils.ts +8 -1
- package/src/main.ts +102 -46
- package/src/memories/index.ts +4 -5
- package/src/modes/acp/acp-agent.ts +563 -163
- package/src/modes/acp/acp-event-mapper.ts +9 -1
- package/src/modes/acp/acp-mode.ts +4 -2
- package/src/modes/components/agent-dashboard.ts +3 -4
- package/src/modes/components/diff.ts +6 -7
- package/src/modes/components/read-tool-group.ts +6 -12
- package/src/modes/components/session-observer-overlay.ts +21 -12
- package/src/modes/components/settings-defs.ts +5 -0
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/btw-controller.ts +2 -2
- package/src/modes/controllers/command-controller.ts +3 -2
- package/src/modes/controllers/input-controller.ts +12 -8
- package/src/modes/index.ts +20 -2
- package/src/modes/interactive-mode.ts +94 -37
- package/src/modes/rpc/host-tools.ts +186 -0
- package/src/modes/rpc/rpc-client.ts +178 -13
- package/src/modes/rpc/rpc-mode.ts +73 -3
- package/src/modes/rpc/rpc-types.ts +53 -1
- package/src/modes/theme/theme.ts +80 -8
- package/src/modes/types.ts +2 -2
- package/src/prompts/review-request.md +6 -0
- package/src/prompts/system/system-prompt.md +2 -1
- package/src/prompts/tools/chunk-edit.md +223 -0
- package/src/prompts/tools/debug.md +43 -0
- package/src/prompts/tools/grep.md +3 -0
- package/src/prompts/tools/lsp.md +5 -5
- package/src/prompts/tools/read-chunk.md +17 -0
- package/src/prompts/tools/read.md +19 -5
- package/src/sdk.ts +190 -154
- package/src/secrets/obfuscator.ts +1 -1
- package/src/session/agent-session.ts +306 -256
- package/src/session/agent-storage.ts +12 -12
- package/src/session/compaction/branch-summarization.ts +3 -3
- package/src/session/compaction/compaction.ts +5 -6
- package/src/session/compaction/utils.ts +3 -3
- package/src/session/history-storage.ts +62 -19
- package/src/session/messages.ts +3 -3
- package/src/session/session-dump-format.ts +203 -0
- package/src/session/session-storage.ts +4 -2
- package/src/session/streaming-output.ts +1 -1
- package/src/session/tool-choice-queue.ts +213 -0
- package/src/slash-commands/builtin-registry.ts +56 -8
- package/src/ssh/connection-manager.ts +2 -2
- package/src/ssh/sshfs-mount.ts +5 -5
- package/src/stt/downloader.ts +4 -4
- package/src/stt/recorder.ts +4 -4
- package/src/stt/transcriber.ts +2 -2
- package/src/system-prompt.ts +21 -13
- package/src/task/agents.ts +5 -6
- package/src/task/commands.ts +2 -5
- package/src/task/executor.ts +4 -4
- package/src/task/index.ts +3 -4
- package/src/task/template.ts +2 -2
- package/src/task/worktree.ts +4 -4
- package/src/tools/ask.ts +2 -3
- package/src/tools/ast-edit.ts +7 -7
- package/src/tools/ast-grep.ts +7 -7
- package/src/tools/auto-generated-guard.ts +36 -41
- package/src/tools/await-tool.ts +2 -2
- package/src/tools/bash.ts +5 -23
- package/src/tools/browser.ts +4 -5
- package/src/tools/calculator.ts +2 -3
- package/src/tools/cancel-job.ts +2 -2
- package/src/tools/checkpoint.ts +3 -3
- package/src/tools/debug.ts +1007 -0
- package/src/tools/exit-plan-mode.ts +2 -3
- package/src/tools/fetch.ts +67 -3
- package/src/tools/find.ts +4 -5
- package/src/tools/fs-cache-invalidation.ts +5 -0
- package/src/tools/gemini-image.ts +13 -5
- package/src/tools/gh.ts +10 -11
- package/src/tools/grep.ts +57 -9
- package/src/tools/index.ts +44 -22
- package/src/tools/inspect-image.ts +4 -4
- package/src/tools/output-meta.ts +1 -1
- package/src/tools/python.ts +19 -6
- package/src/tools/read.ts +198 -67
- package/src/tools/render-mermaid.ts +2 -3
- package/src/tools/render-utils.ts +20 -6
- package/src/tools/renderers.ts +3 -1
- package/src/tools/report-tool-issue.ts +80 -0
- package/src/tools/resolve.ts +70 -39
- package/src/tools/search-tool-bm25.ts +2 -2
- package/src/tools/ssh.ts +2 -2
- package/src/tools/todo-write.ts +2 -2
- package/src/tools/tool-timeouts.ts +1 -0
- package/src/tools/write.ts +5 -6
- package/src/tui/tree-list.ts +3 -1
- package/src/utils/clipboard.ts +80 -0
- package/src/utils/commit-message-generator.ts +2 -3
- package/src/utils/edit-mode.ts +49 -0
- package/src/utils/file-display-mode.ts +6 -5
- package/src/utils/file-mentions.ts +8 -7
- package/src/utils/git.ts +4 -4
- package/src/utils/image-loading.ts +98 -0
- package/src/utils/title-generator.ts +2 -3
- package/src/utils/tools-manager.ts +6 -6
- package/src/web/scrapers/choosealicense.ts +1 -1
- package/src/web/search/index.ts +3 -3
- package/src/autoresearch/command-initialize.md +0 -34
- package/src/patch/diff.ts +0 -433
- package/src/patch/index.ts +0 -888
- package/src/patch/parser.ts +0 -532
- package/src/patch/types.ts +0 -292
- package/src/prompts/agents/oracle.md +0 -77
- package/src/tools/pending-action.ts +0 -49
- package/src/utils/child-process.ts +0 -88
- package/src/utils/frontmatter.ts +0 -117
- package/src/utils/image-input.ts +0 -274
- package/src/utils/mime.ts +0 -53
- package/src/utils/prompt-format.ts +0 -170
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read CLI command handler.
|
|
3
|
+
*
|
|
4
|
+
* Handles `omp read` subcommand — emits chunk-mode read output for files,
|
|
5
|
+
* and delegates URL reads through the read tool pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import * as path from "node:path";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { Settings } from "../config/settings";
|
|
10
|
+
import { formatChunkedRead, resolveAnchorStyle } from "../edit/modes/chunk";
|
|
11
|
+
import { getLanguageFromPath } from "../modes/theme/theme";
|
|
12
|
+
import type { ToolSession } from "../tools";
|
|
13
|
+
import { parseReadUrlTarget } from "../tools/fetch";
|
|
14
|
+
import { ReadTool } from "../tools/read";
|
|
15
|
+
|
|
16
|
+
export interface ReadCommandArgs {
|
|
17
|
+
path: string;
|
|
18
|
+
sel?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function createCliReadSession(cwd: string, settings: Settings): ToolSession {
|
|
22
|
+
return {
|
|
23
|
+
cwd,
|
|
24
|
+
hasUI: false,
|
|
25
|
+
hasEditTool: true,
|
|
26
|
+
getSessionFile: () => null,
|
|
27
|
+
getSessionSpawns: () => null,
|
|
28
|
+
settings,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function runReadCommand(cmd: ReadCommandArgs): Promise<void> {
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
const parsedUrlTarget = parseReadUrlTarget(cmd.path, cmd.sel);
|
|
35
|
+
if (parsedUrlTarget) {
|
|
36
|
+
const settings = await Settings.init({ cwd });
|
|
37
|
+
const tool = new ReadTool(createCliReadSession(cwd, settings));
|
|
38
|
+
const result = await tool.execute("cli-read", { path: cmd.path, sel: cmd.sel });
|
|
39
|
+
const text = result.content.find((content): content is { type: "text"; text: string } => content.type === "text");
|
|
40
|
+
console.log(text?.text ?? "");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const filePath = path.resolve(cmd.path);
|
|
45
|
+
const file = Bun.file(filePath);
|
|
46
|
+
if (!(await file.exists())) {
|
|
47
|
+
console.error(chalk.red(`Error: File not found: ${cmd.path}`));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const readPath = cmd.sel ? `${filePath}:${cmd.sel}` : filePath;
|
|
52
|
+
const language = getLanguageFromPath(filePath);
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const result = await formatChunkedRead({
|
|
56
|
+
filePath,
|
|
57
|
+
readPath,
|
|
58
|
+
cwd,
|
|
59
|
+
language,
|
|
60
|
+
anchorStyle: resolveAnchorStyle(),
|
|
61
|
+
});
|
|
62
|
+
console.log(result.text);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error(chalk.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/cli/setup-cli.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles `omp setup <component>` to install dependencies for optional features.
|
|
5
5
|
*/
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import { APP_NAME, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
7
|
+
import { $which, APP_NAME, getPythonEnvDir } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { $ } from "bun";
|
|
9
9
|
import chalk from "chalk";
|
|
10
10
|
import { theme } from "../modes/theme/theme";
|
|
@@ -90,12 +90,12 @@ async function checkPythonSetup(): Promise<PythonCheckResult> {
|
|
|
90
90
|
managedEnvPath: MANAGED_PYTHON_ENV,
|
|
91
91
|
};
|
|
92
92
|
|
|
93
|
-
const systemPythonPath =
|
|
93
|
+
const systemPythonPath = $which("python") ?? $which("python3");
|
|
94
94
|
const managedPath = managedPythonPath();
|
|
95
95
|
const hasManagedEnv = await Bun.file(managedPath).exists();
|
|
96
96
|
|
|
97
|
-
result.uvPath =
|
|
98
|
-
result.pipPath =
|
|
97
|
+
result.uvPath = $which("uv") ?? undefined;
|
|
98
|
+
result.pipPath = $which("pip3") ?? $which("pip") ?? undefined;
|
|
99
99
|
|
|
100
100
|
const candidates = [systemPythonPath, hasManagedEnv ? managedPath : undefined].filter(
|
|
101
101
|
(candidate): candidate is string => !!candidate,
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import { pipeline } from "node:stream/promises";
|
|
10
|
-
import { APP_NAME, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
|
|
10
|
+
import { $which, APP_NAME, isEnoent, VERSION } from "@oh-my-pi/pi-utils";
|
|
11
11
|
import { $ } from "bun";
|
|
12
12
|
import chalk from "chalk";
|
|
13
13
|
import { theme } from "../modes/theme/theme";
|
|
@@ -36,7 +36,7 @@ export function parseUpdateArgs(args: string[]): { force: boolean; check: boolea
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
async function getBunGlobalBinDir(): Promise<string | undefined> {
|
|
39
|
-
if (
|
|
39
|
+
if (!$which("bun")) return undefined;
|
|
40
40
|
try {
|
|
41
41
|
const result = await $`bun pm bin -g`.quiet().nothrow();
|
|
42
42
|
if (result.exitCode !== 0) return undefined;
|
|
@@ -167,7 +167,7 @@ function getBinaryName(): string {
|
|
|
167
167
|
* Resolve the path that `omp` maps to in the user's PATH.
|
|
168
168
|
*/
|
|
169
169
|
function resolveOmpPath(): string | undefined {
|
|
170
|
-
return
|
|
170
|
+
return $which(APP_NAME) ?? undefined;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
package/src/cli.ts
CHANGED
|
@@ -48,6 +48,8 @@ const commands: CommandEntry[] = [
|
|
|
48
48
|
{ name: "commit", load: () => import("./commands/commit").then(m => m.default) },
|
|
49
49
|
{ name: "config", load: () => import("./commands/config").then(m => m.default) },
|
|
50
50
|
{ name: "grep", load: () => import("./commands/grep").then(m => m.default) },
|
|
51
|
+
{ name: "grievances", load: () => import("./commands/grievances").then(m => m.default) },
|
|
52
|
+
{ name: "read", load: () => import("./commands/read").then(m => m.default) },
|
|
51
53
|
{ name: "jupyter", load: () => import("./commands/jupyter").then(m => m.default) },
|
|
52
54
|
{ name: "plugin", load: () => import("./commands/plugin").then(m => m.default) },
|
|
53
55
|
{ name: "setup", load: () => import("./commands/setup").then(m => m.default) },
|
package/src/commands/grep.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test grep tool.
|
|
3
3
|
*/
|
|
4
|
+
import { GrepOutputMode } from "@oh-my-pi/pi-natives";
|
|
4
5
|
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
6
|
import { type GrepCommandArgs, runGrepCommand } from "../cli/grep-cli";
|
|
6
7
|
import { initTheme } from "../modes/theme/theme";
|
|
@@ -25,7 +26,11 @@ export default class Grep extends Command {
|
|
|
25
26
|
async run(): Promise<void> {
|
|
26
27
|
const { args, flags } = await this.parse(Grep);
|
|
27
28
|
|
|
28
|
-
const mode: GrepCommandArgs["mode"] = flags.count
|
|
29
|
+
const mode: GrepCommandArgs["mode"] = flags.count
|
|
30
|
+
? GrepOutputMode.Count
|
|
31
|
+
: flags.files
|
|
32
|
+
? GrepOutputMode.FilesWithMatches
|
|
33
|
+
: GrepOutputMode.Content;
|
|
29
34
|
|
|
30
35
|
const cmd: GrepCommandArgs = {
|
|
31
36
|
pattern: args.pattern ?? "",
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View recently reported tool issues from automated QA.
|
|
3
|
+
*/
|
|
4
|
+
import { Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
|
+
import { listGrievances } from "../cli/grievances-cli";
|
|
6
|
+
|
|
7
|
+
export default class Grievances extends Command {
|
|
8
|
+
static description = "View reported tool issues (auto-QA grievances)";
|
|
9
|
+
|
|
10
|
+
static flags = {
|
|
11
|
+
limit: Flags.integer({ char: "n", description: "Number of recent issues to show", default: 20 }),
|
|
12
|
+
tool: Flags.string({ char: "t", description: "Filter by tool name" }),
|
|
13
|
+
json: Flags.boolean({ char: "j", description: "Output as JSON", default: false }),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
async run(): Promise<void> {
|
|
17
|
+
const { flags } = await this.parse(Grievances);
|
|
18
|
+
await listGrievances({ limit: flags.limit, tool: flags.tool, json: flags.json });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunk-mode read tool.
|
|
3
|
+
*/
|
|
4
|
+
import { Args, Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
|
+
import { type ReadCommandArgs, runReadCommand } from "../cli/read-cli";
|
|
6
|
+
import { initTheme } from "../modes/theme/theme";
|
|
7
|
+
|
|
8
|
+
export default class Read extends Command {
|
|
9
|
+
static description = "Read a file as a chunk tree";
|
|
10
|
+
|
|
11
|
+
static args = {
|
|
12
|
+
path: Args.string({ description: "File path to read", required: true }),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
static flags = {
|
|
16
|
+
sel: Flags.string({
|
|
17
|
+
char: "s",
|
|
18
|
+
description: "Chunk selector or line range (e.g. class_Foo.fn_bar, L10-L20)",
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
async run(): Promise<void> {
|
|
23
|
+
const { args, flags } = await this.parse(Read);
|
|
24
|
+
|
|
25
|
+
const cmd: ReadCommandArgs = {
|
|
26
|
+
path: args.path ?? "",
|
|
27
|
+
sel: flags.sel,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
await initTheme();
|
|
31
|
+
await runReadCommand(cmd);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { INTENT_FIELD, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { Markdown } from "@oh-my-pi/pi-tui";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import chalk from "chalk";
|
|
5
6
|
import typesDescriptionPrompt from "../../commit/prompts/types-description.md" with { type: "text" };
|
|
6
7
|
import type { ModelRegistry } from "../../config/model-registry";
|
|
7
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
8
8
|
import type { Settings } from "../../config/settings";
|
|
9
9
|
import { getMarkdownTheme } from "../../modes/theme/theme";
|
|
10
10
|
import { createAgentSession } from "../../sdk";
|
|
@@ -36,8 +36,8 @@ export interface ExistingChangelogEntries {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export async function runCommitAgentSession(input: CommitAgentInput): Promise<CommitAgentState> {
|
|
39
|
-
const typesDescription =
|
|
40
|
-
const systemPrompt =
|
|
39
|
+
const typesDescription = prompt.render(typesDescriptionPrompt);
|
|
40
|
+
const systemPrompt = prompt.render(agentSystemPrompt, {
|
|
41
41
|
types_description: typesDescription,
|
|
42
42
|
});
|
|
43
43
|
const state: CommitAgentState = { diffText: input.diffText };
|
|
@@ -149,7 +149,7 @@ export async function runCommitAgentSession(input: CommitAgentInput): Promise<Co
|
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
try {
|
|
152
|
-
const
|
|
152
|
+
const agentUserMessage = prompt.render(agentUserPrompt, {
|
|
153
153
|
user_context: input.userContext,
|
|
154
154
|
changelog_targets: input.changelogTargets.length > 0 ? input.changelogTargets.join("\n") : undefined,
|
|
155
155
|
existing_changelog_entries: input.existingChangelogEntries,
|
|
@@ -158,7 +158,7 @@ export async function runCommitAgentSession(input: CommitAgentInput): Promise<Co
|
|
|
158
158
|
let retryCount = 0;
|
|
159
159
|
const needsChangelog = input.requireChangelog && input.changelogTargets.length > 0;
|
|
160
160
|
|
|
161
|
-
await session.prompt(
|
|
161
|
+
await session.prompt(agentUserMessage, {
|
|
162
162
|
attribution: "agent",
|
|
163
163
|
expandPromptTemplates: false,
|
|
164
164
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import { $env, getProjectDir, isEnoent } from "@oh-my-pi/pi-utils";
|
|
3
|
+
import { $env, getProjectDir, isEnoent, prompt } from "@oh-my-pi/pi-utils";
|
|
4
4
|
import { applyChangelogProposals } from "../../commit/changelog";
|
|
5
5
|
import { detectChangelogBoundaries } from "../../commit/changelog/detect";
|
|
6
6
|
import { parseUnreleasedSection } from "../../commit/changelog/parse";
|
|
@@ -8,7 +8,6 @@ import { formatCommitMessage } from "../../commit/message";
|
|
|
8
8
|
import { resolvePrimaryModel, resolveSmolModel } from "../../commit/model-selection";
|
|
9
9
|
import type { CommitCommandArgs, ConventionalAnalysis } from "../../commit/types";
|
|
10
10
|
import { ModelRegistry } from "../../config/model-registry";
|
|
11
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
12
11
|
import { Settings } from "../../config/settings";
|
|
13
12
|
import { discoverAuthStorage, discoverContextFiles } from "../../sdk";
|
|
14
13
|
import * as git from "../../utils/git";
|
|
@@ -305,8 +304,8 @@ async function confirmSplitCommitPlan(plan: SplitCommitPlan): Promise<boolean> {
|
|
|
305
304
|
}
|
|
306
305
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
307
306
|
try {
|
|
308
|
-
const
|
|
309
|
-
const answer = await rl.question(
|
|
307
|
+
const splitConfirmQuestion = prompt.render(splitConfirmPrompt, { count: plan.commits.length });
|
|
308
|
+
const answer = await rl.question(splitConfirmQuestion);
|
|
310
309
|
return ["y", "yes"].includes(answer.trim().toLowerCase());
|
|
311
310
|
} finally {
|
|
312
311
|
rl.close();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
1
2
|
import { Type } from "@sinclair/typebox";
|
|
2
3
|
import analyzeFilePrompt from "../../../commit/agentic/prompts/analyze-file.md" with { type: "text" };
|
|
3
4
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
4
5
|
import type { NumstatEntry } from "../../../commit/types";
|
|
5
6
|
import type { ModelRegistry } from "../../../config/model-registry";
|
|
6
|
-
import { renderPromptTemplate } from "../../../config/prompt-templates";
|
|
7
7
|
import type { Settings } from "../../../config/settings";
|
|
8
8
|
import type { CustomTool, CustomToolContext } from "../../../extensibility/custom-tools/types";
|
|
9
9
|
import type { AuthStorage } from "../../../session/auth-storage";
|
|
@@ -66,7 +66,7 @@ export function createAnalyzeFileTool(options: {
|
|
|
66
66
|
const numstat = options.state.overview?.numstat ?? [];
|
|
67
67
|
const tasks = params.files.map((file, index) => {
|
|
68
68
|
const relatedFiles = formatRelatedFiles(params.files, file, numstat);
|
|
69
|
-
const
|
|
69
|
+
const assignment = prompt.render(analyzeFilePrompt, {
|
|
70
70
|
file,
|
|
71
71
|
goal: params.goal,
|
|
72
72
|
related_files: relatedFiles,
|
|
@@ -74,7 +74,7 @@ export function createAnalyzeFileTool(options: {
|
|
|
74
74
|
return {
|
|
75
75
|
id: `AnalyzeFile${index + 1}`,
|
|
76
76
|
description: `Analyze ${file}`,
|
|
77
|
-
assignment
|
|
77
|
+
assignment,
|
|
78
78
|
};
|
|
79
79
|
});
|
|
80
80
|
const taskParams: TaskParams = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { stripTypePrefix } from "../../commit/analysis/summary";
|
|
2
2
|
import { validateSummary } from "../../commit/analysis/validation";
|
|
3
3
|
import type { CommitType, ConventionalDetail } from "../../commit/types";
|
|
4
|
-
import { normalizeUnicode } from "../../
|
|
4
|
+
import { normalizeUnicode } from "../../edit/normalize";
|
|
5
5
|
|
|
6
6
|
export const SUMMARY_MAX_CHARS = 72;
|
|
7
7
|
export const MAX_DETAIL_ITEMS = 6;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, AssistantMessage, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple, validateToolCall } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { Type } from "@sinclair/typebox";
|
|
5
6
|
import analysisSystemPrompt from "../../commit/prompts/analysis-system.md" with { type: "text" };
|
|
6
7
|
import analysisUserPrompt from "../../commit/prompts/analysis-user.md" with { type: "text" };
|
|
7
8
|
import type { ChangelogCategory, ConventionalAnalysis } from "../../commit/types";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { extractTextContent, extractToolCall, normalizeAnalysis, parseJsonPayload } from "../utils";
|
|
11
11
|
|
|
@@ -76,7 +76,7 @@ export async function generateConventionalAnalysis({
|
|
|
76
76
|
stat,
|
|
77
77
|
diff,
|
|
78
78
|
}: ConventionalAnalysisInput): Promise<ConventionalAnalysis> {
|
|
79
|
-
const
|
|
79
|
+
const userContent = prompt.render(analysisUserPrompt, {
|
|
80
80
|
context_files: contextFiles && contextFiles.length > 0 ? contextFiles : undefined,
|
|
81
81
|
user_context: userContext,
|
|
82
82
|
types_description: typesDescription,
|
|
@@ -89,8 +89,8 @@ export async function generateConventionalAnalysis({
|
|
|
89
89
|
const response = await completeSimple(
|
|
90
90
|
model,
|
|
91
91
|
{
|
|
92
|
-
systemPrompt:
|
|
93
|
-
messages: [{ role: "user", content:
|
|
92
|
+
systemPrompt: prompt.render(analysisSystemPrompt),
|
|
93
|
+
messages: [{ role: "user", content: userContent, timestamp: Date.now() }],
|
|
94
94
|
tools: [ConventionalAnalysisTool],
|
|
95
95
|
},
|
|
96
96
|
{ apiKey, maxTokens: 2400, reasoning: toReasoningEffort(thinkingLevel) },
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, AssistantMessage, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple, validateToolCall } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { Type } from "@sinclair/typebox";
|
|
5
6
|
import summarySystemPrompt from "../../commit/prompts/summary-system.md" with { type: "text" };
|
|
6
7
|
import summaryUserPrompt from "../../commit/prompts/summary-user.md" with { type: "text" };
|
|
7
8
|
import type { CommitSummary } from "../../commit/types";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { extractTextContent, extractToolCall } from "../utils";
|
|
11
11
|
|
|
@@ -44,7 +44,7 @@ export async function generateSummary({
|
|
|
44
44
|
userContext,
|
|
45
45
|
}: SummaryInput): Promise<CommitSummary> {
|
|
46
46
|
const systemPrompt = renderSummaryPrompt({ commitType, scope, maxChars });
|
|
47
|
-
const userPrompt =
|
|
47
|
+
const userPrompt = prompt.render(summaryUserPrompt, {
|
|
48
48
|
user_context: userContext,
|
|
49
49
|
details: details.join("\n"),
|
|
50
50
|
stat,
|
|
@@ -73,7 +73,7 @@ function renderSummaryPrompt({
|
|
|
73
73
|
maxChars: number;
|
|
74
74
|
}): string {
|
|
75
75
|
const scopePrefix = scope ? `(${scope})` : "";
|
|
76
|
-
return
|
|
76
|
+
return prompt.render(summarySystemPrompt, {
|
|
77
77
|
commit_type: commitType,
|
|
78
78
|
scope_prefix: scopePrefix,
|
|
79
79
|
chars: String(maxChars),
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, AssistantMessage, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple, validateToolCall } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { type TSchema, Type } from "@sinclair/typebox";
|
|
5
6
|
import changelogSystemPrompt from "../../commit/prompts/changelog-system.md" with { type: "text" };
|
|
6
7
|
import changelogUserPrompt from "../../commit/prompts/changelog-user.md" with { type: "text" };
|
|
7
8
|
import { CHANGELOG_CATEGORIES, type ChangelogCategory, type ChangelogGenerationResult } from "../../commit/types";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { extractTextContent, extractToolCall, parseJsonPayload } from "../utils";
|
|
11
11
|
|
|
@@ -48,7 +48,7 @@ export async function generateChangelogEntries({
|
|
|
48
48
|
stat,
|
|
49
49
|
diff,
|
|
50
50
|
}: ChangelogPromptInput): Promise<ChangelogGenerationResult> {
|
|
51
|
-
const
|
|
51
|
+
const userContent = prompt.render(changelogUserPrompt, {
|
|
52
52
|
changelog_path: changelogPath,
|
|
53
53
|
is_package_changelog: isPackageChangelog,
|
|
54
54
|
existing_entries: existingEntries,
|
|
@@ -58,8 +58,8 @@ export async function generateChangelogEntries({
|
|
|
58
58
|
const response = await completeSimple(
|
|
59
59
|
model,
|
|
60
60
|
{
|
|
61
|
-
systemPrompt:
|
|
62
|
-
messages: [{ role: "user", content:
|
|
61
|
+
systemPrompt: prompt.render(changelogSystemPrompt),
|
|
62
|
+
messages: [{ role: "user", content: userContent, timestamp: Date.now() }],
|
|
63
63
|
tools: [changelogTool],
|
|
64
64
|
},
|
|
65
65
|
{ apiKey, maxTokens: 1200, reasoning: toReasoningEffort(thinkingLevel) },
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, AssistantMessage, Message, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import fileObserverSystemPrompt from "../../commit/prompts/file-observer-system.md" with { type: "text" };
|
|
5
6
|
import fileObserverUserPrompt from "../../commit/prompts/file-observer-user.md" with { type: "text" };
|
|
6
7
|
import type { FileDiff, FileObservation } from "../../commit/types";
|
|
7
8
|
import { isExcludedFile } from "../../commit/utils/exclusions";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { truncateToTokenLimit } from "./utils";
|
|
11
11
|
|
|
@@ -38,7 +38,7 @@ export async function runMapPhase({
|
|
|
38
38
|
config,
|
|
39
39
|
}: MapPhaseInput): Promise<FileObservation[]> {
|
|
40
40
|
const filtered = files.filter(file => !isExcludedFile(file.filename));
|
|
41
|
-
const systemPrompt =
|
|
41
|
+
const systemPrompt = prompt.render(fileObserverSystemPrompt);
|
|
42
42
|
const maxFileTokens = config?.maxFileTokens ?? MAX_FILE_TOKENS;
|
|
43
43
|
const maxConcurrency = config?.maxConcurrency ?? MAX_CONCURRENCY;
|
|
44
44
|
const timeoutMs = config?.timeoutMs ?? MAP_PHASE_TIMEOUT_MS;
|
|
@@ -56,14 +56,14 @@ export async function runMapPhase({
|
|
|
56
56
|
|
|
57
57
|
const contextHeader = generateContextHeader(filtered, file.filename);
|
|
58
58
|
const truncated = truncateToTokenLimit(file.content, maxFileTokens);
|
|
59
|
-
const
|
|
59
|
+
const userContent = prompt.render(fileObserverUserPrompt, {
|
|
60
60
|
filename: file.filename,
|
|
61
61
|
diff: truncated,
|
|
62
62
|
context_header: contextHeader,
|
|
63
63
|
});
|
|
64
64
|
const request = {
|
|
65
65
|
systemPrompt,
|
|
66
|
-
messages: [{ role: "user", content:
|
|
66
|
+
messages: [{ role: "user", content: userContent, timestamp: Date.now() }] as Message[],
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const response = await withRetry(
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
2
|
import type { Api, AssistantMessage, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple, validateToolCall } from "@oh-my-pi/pi-ai";
|
|
4
|
+
import { prompt } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { Type } from "@sinclair/typebox";
|
|
5
6
|
import reduceSystemPrompt from "../../commit/prompts/reduce-system.md" with { type: "text" };
|
|
6
7
|
import reduceUserPrompt from "../../commit/prompts/reduce-user.md" with { type: "text" };
|
|
7
8
|
import type { ChangelogCategory, ConventionalAnalysis, FileObservation } from "../../commit/types";
|
|
8
|
-
import { renderPromptTemplate } from "../../config/prompt-templates";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { extractTextContent, extractToolCall, normalizeAnalysis, parseJsonPayload } from "../utils";
|
|
11
11
|
|
|
@@ -67,7 +67,7 @@ export async function runReducePhase({
|
|
|
67
67
|
scopeCandidates,
|
|
68
68
|
typesDescription,
|
|
69
69
|
}: ReducePhaseInput): Promise<ConventionalAnalysis> {
|
|
70
|
-
const
|
|
70
|
+
const userContent = prompt.render(reduceUserPrompt, {
|
|
71
71
|
types_description: typesDescription,
|
|
72
72
|
observations: observations.flatMap(obs => obs.observations.map(line => `- ${obs.file}: ${line}`)).join("\n"),
|
|
73
73
|
stat,
|
|
@@ -76,8 +76,8 @@ export async function runReducePhase({
|
|
|
76
76
|
const response = await completeSimple(
|
|
77
77
|
model,
|
|
78
78
|
{
|
|
79
|
-
systemPrompt:
|
|
80
|
-
messages: [{ role: "user", content:
|
|
79
|
+
systemPrompt: prompt.render(reduceSystemPrompt),
|
|
80
|
+
messages: [{ role: "user", content: userContent, timestamp: Date.now() }],
|
|
81
81
|
tools: [ReduceTool],
|
|
82
82
|
},
|
|
83
83
|
{ apiKey, maxTokens: 2400, reasoning: toReasoningEffort(thinkingLevel) },
|
package/src/commit/pipeline.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
3
3
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
4
|
-
import { getProjectDir, logger } from "@oh-my-pi/pi-utils";
|
|
4
|
+
import { getProjectDir, logger, prompt } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import { ModelRegistry } from "../config/model-registry";
|
|
6
|
-
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
7
6
|
import { Settings } from "../config/settings";
|
|
8
7
|
import { discoverAuthStorage } from "../sdk";
|
|
9
8
|
import { loadProjectContextFiles } from "../system-prompt";
|
|
@@ -26,7 +25,7 @@ import type { CommitCommandArgs, ConventionalAnalysis } from "./types";
|
|
|
26
25
|
|
|
27
26
|
const SUMMARY_MAX_CHARS = 72;
|
|
28
27
|
const RECENT_COMMITS_COUNT = 8;
|
|
29
|
-
const TYPES_DESCRIPTION =
|
|
28
|
+
const TYPES_DESCRIPTION = prompt.render(typesDescriptionPrompt);
|
|
30
29
|
|
|
31
30
|
/**
|
|
32
31
|
* Execute the omp commit pipeline for staged changes.
|
|
@@ -236,7 +235,7 @@ async function generateSummaryWithRetry(input: {
|
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
function buildRetryContext(base: string | undefined, errors: string[]): string {
|
|
239
|
-
return
|
|
238
|
+
return prompt.render(summaryRetryPrompt, {
|
|
240
239
|
base_context: base,
|
|
241
240
|
errors: errors.join("; "),
|
|
242
241
|
});
|
|
@@ -947,7 +947,10 @@ export class ModelRegistry {
|
|
|
947
947
|
}
|
|
948
948
|
const models = this.#applyProviderModelOverrides(
|
|
949
949
|
providerConfig.provider,
|
|
950
|
-
this.#
|
|
950
|
+
this.#normalizeDiscoverableModels(
|
|
951
|
+
providerConfig,
|
|
952
|
+
this.#applyProviderCompat(providerConfig.compat, cache.models),
|
|
953
|
+
),
|
|
951
954
|
);
|
|
952
955
|
cachedModels.push(...models);
|
|
953
956
|
this.#providerDiscoveryStates.set(providerConfig.provider, {
|
|
@@ -967,11 +970,19 @@ export class ModelRegistry {
|
|
|
967
970
|
return models.map(model => ({ ...model, compat: mergeCompat(model.compat, compat) }));
|
|
968
971
|
}
|
|
969
972
|
|
|
973
|
+
#normalizeDiscoverableModels(providerConfig: DiscoveryProviderConfig, models: Model<Api>[]): Model<Api>[] {
|
|
974
|
+
if (providerConfig.provider !== "ollama" || providerConfig.api !== "openai-responses") {
|
|
975
|
+
return models;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
return models.map(model => (model.api === "openai-completions" ? { ...model, api: "openai-responses" } : model));
|
|
979
|
+
}
|
|
980
|
+
|
|
970
981
|
#addImplicitDiscoverableProviders(configuredProviders: Set<string>): void {
|
|
971
982
|
if (!configuredProviders.has("ollama")) {
|
|
972
983
|
this.#discoverableProviders.push({
|
|
973
984
|
provider: "ollama",
|
|
974
|
-
api: "openai-
|
|
985
|
+
api: "openai-responses",
|
|
975
986
|
baseUrl: Bun.env.OLLAMA_BASE_URL || "http://127.0.0.1:11434",
|
|
976
987
|
discovery: { type: "ollama" },
|
|
977
988
|
optional: true,
|
|
@@ -1203,7 +1214,10 @@ export class ModelRegistry {
|
|
|
1203
1214
|
}
|
|
1204
1215
|
return this.#applyProviderModelOverrides(
|
|
1205
1216
|
providerId,
|
|
1206
|
-
this.#
|
|
1217
|
+
this.#normalizeDiscoverableModels(
|
|
1218
|
+
providerConfig,
|
|
1219
|
+
this.#applyProviderCompat(providerConfig.compat, result.models),
|
|
1220
|
+
),
|
|
1207
1221
|
);
|
|
1208
1222
|
}
|
|
1209
1223
|
|