@oh-my-pi/pi-coding-agent 15.0.1 → 15.1.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 +94 -1
- package/examples/custom-tools/README.md +11 -7
- package/examples/custom-tools/hello/index.ts +2 -2
- package/examples/extensions/README.md +19 -8
- package/examples/extensions/api-demo.ts +15 -19
- package/examples/extensions/hello.ts +5 -6
- package/examples/extensions/plan-mode.ts +1 -1
- package/examples/extensions/reload-runtime.ts +4 -3
- package/examples/extensions/with-deps/index.ts +4 -3
- package/examples/sdk/06-extensions.ts +4 -2
- package/package.json +8 -18
- package/src/autoresearch/tools/init-experiment.ts +38 -41
- package/src/autoresearch/tools/log-experiment.ts +32 -41
- package/src/autoresearch/tools/run-experiment.ts +3 -3
- package/src/autoresearch/tools/update-notes.ts +11 -11
- package/src/commands/commit.ts +10 -0
- package/src/commit/agentic/tools/analyze-file.ts +4 -4
- package/src/commit/agentic/tools/git-file-diff.ts +4 -4
- package/src/commit/agentic/tools/git-hunk.ts +5 -5
- package/src/commit/agentic/tools/git-overview.ts +4 -4
- package/src/commit/agentic/tools/propose-changelog.ts +13 -13
- package/src/commit/agentic/tools/propose-commit.ts +6 -6
- package/src/commit/agentic/tools/recent-commits.ts +3 -3
- package/src/commit/agentic/tools/schemas.ts +28 -28
- package/src/commit/agentic/tools/split-commit.ts +22 -21
- package/src/commit/analysis/summary.ts +4 -4
- package/src/commit/changelog/generate.ts +7 -11
- package/src/commit/shared-llm.ts +22 -34
- package/src/config/config-file.ts +35 -13
- package/src/config/model-registry.ts +40 -191
- package/src/config/models-config-schema.ts +166 -0
- package/src/config/settings-schema.ts +29 -0
- package/src/discovery/claude-plugins.ts +19 -7
- package/src/edit/index.ts +2 -2
- package/src/edit/modes/apply-patch.ts +7 -6
- package/src/edit/modes/patch.ts +18 -25
- package/src/edit/modes/replace.ts +18 -20
- package/src/eval/js/shared/rewrite-imports.ts +131 -10
- package/src/eval/py/executor.ts +233 -623
- package/src/eval/py/kernel.ts +27 -2
- package/src/eval/py/runner.py +42 -11
- package/src/eval/py/runtime.ts +1 -0
- package/src/exa/factory.ts +5 -4
- package/src/exa/mcp-client.ts +1 -1
- package/src/exa/researcher.ts +9 -20
- package/src/exa/search.ts +26 -52
- package/src/exa/types.ts +1 -1
- package/src/exa/websets.ts +54 -53
- package/src/exec/bash-executor.ts +2 -1
- package/src/extensibility/custom-commands/loader.ts +5 -3
- package/src/extensibility/custom-commands/types.ts +4 -2
- package/src/extensibility/custom-tools/loader.ts +5 -3
- package/src/extensibility/custom-tools/types.ts +7 -6
- package/src/extensibility/custom-tools/wrapper.ts +1 -1
- package/src/extensibility/extensions/get-commands-handler.ts +77 -0
- package/src/extensibility/extensions/loader.ts +7 -3
- package/src/extensibility/extensions/types.ts +9 -5
- package/src/extensibility/extensions/wrapper.ts +1 -2
- package/src/extensibility/hooks/loader.ts +3 -1
- package/src/extensibility/hooks/tool-wrapper.ts +1 -1
- package/src/extensibility/hooks/types.ts +4 -2
- package/src/extensibility/plugins/legacy-pi-compat.ts +78 -31
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/typebox.ts +391 -0
- package/src/goals/tools/goal-tool.ts +6 -12
- package/src/hashline/input.ts +2 -1
- package/src/hashline/parser.ts +27 -3
- package/src/hashline/types.ts +4 -4
- package/src/hindsight/state.ts +2 -2
- package/src/index.ts +0 -2
- package/src/internal-urls/docs-index.generated.ts +15 -15
- package/src/internal-urls/router.ts +8 -0
- package/src/internal-urls/types.ts +21 -0
- package/src/lsp/config.ts +15 -6
- package/src/lsp/defaults.json +6 -2
- package/src/lsp/types.ts +30 -38
- package/src/mcp/manager.ts +1 -1
- package/src/mcp/tool-bridge.ts +1 -1
- package/src/modes/acp/acp-agent.ts +248 -50
- package/src/modes/components/session-observer-overlay.ts +12 -1
- package/src/modes/components/status-line/segments.ts +39 -4
- package/src/modes/controllers/command-controller.ts +27 -2
- package/src/modes/controllers/event-controller.ts +3 -4
- package/src/modes/controllers/extension-ui-controller.ts +3 -2
- package/src/modes/interactive-mode.ts +1 -1
- package/src/modes/rpc/host-tools.ts +1 -1
- package/src/modes/rpc/host-uris.ts +235 -0
- package/src/modes/rpc/rpc-client.ts +1 -1
- package/src/modes/rpc/rpc-mode.ts +27 -1
- package/src/modes/rpc/rpc-types.ts +58 -1
- package/src/modes/runtime-init.ts +2 -1
- package/src/modes/theme/defaults/dark-poimandres.json +1 -0
- package/src/modes/theme/defaults/light-poimandres.json +1 -0
- package/src/modes/theme/theme.ts +117 -117
- package/src/modes/types.ts +1 -1
- package/src/modes/utils/context-usage.ts +2 -2
- package/src/prompts/tools/github.md +4 -4
- package/src/prompts/tools/hashline.md +22 -26
- package/src/prompts/tools/read.md +55 -37
- package/src/sdk.ts +31 -8
- package/src/session/agent-session.ts +74 -104
- package/src/session/messages.ts +16 -51
- package/src/session/session-manager.ts +22 -2
- package/src/session/streaming-output.ts +16 -6
- package/src/task/discovery.ts +5 -2
- package/src/task/executor.ts +210 -87
- package/src/task/index.ts +15 -11
- package/src/task/render.ts +32 -5
- package/src/task/types.ts +54 -39
- package/src/tools/ask.ts +12 -12
- package/src/tools/ast-edit.ts +11 -15
- package/src/tools/ast-grep.ts +9 -10
- package/src/tools/bash-command-fixup.ts +47 -0
- package/src/tools/bash.ts +48 -38
- package/src/tools/browser/render.ts +2 -2
- package/src/tools/browser.ts +39 -53
- package/src/tools/calculator.ts +12 -11
- package/src/tools/checkpoint.ts +7 -7
- package/src/tools/debug.ts +40 -43
- package/src/tools/eval.ts +16 -10
- package/src/tools/find.ts +10 -13
- package/src/tools/gh.ts +108 -132
- package/src/tools/hindsight-recall.ts +4 -6
- package/src/tools/hindsight-reflect.ts +5 -5
- package/src/tools/hindsight-retain.ts +15 -17
- package/src/tools/image-gen.ts +31 -81
- package/src/tools/index.ts +4 -1
- package/src/tools/inspect-image.ts +8 -9
- package/src/tools/irc.ts +15 -27
- package/src/tools/job.ts +30 -28
- package/src/tools/output-meta.ts +26 -0
- package/src/tools/read.ts +39 -12
- package/src/tools/recipe/index.ts +7 -9
- package/src/tools/render-mermaid.ts +12 -12
- package/src/tools/report-tool-issue.ts +4 -4
- package/src/tools/resolve.ts +11 -11
- package/src/tools/review.ts +14 -26
- package/src/tools/search-tool-bm25.ts +7 -9
- package/src/tools/search.ts +19 -22
- package/src/tools/ssh.ts +10 -9
- package/src/tools/todo-write.ts +26 -34
- package/src/tools/vim.ts +10 -26
- package/src/tools/write.ts +25 -5
- package/src/tools/yield.ts +100 -54
- package/src/web/search/index.ts +9 -24
- package/src/web/search/providers/anthropic.ts +5 -0
- package/src/web/search/providers/exa.ts +3 -0
- package/src/web/search/providers/gemini.ts +5 -0
- package/src/web/search/providers/jina.ts +5 -2
- package/src/web/search/providers/zai.ts +5 -2
- package/src/prompts/compaction/branch-summary-context.md +0 -5
- package/src/prompts/compaction/branch-summary-preamble.md +0 -2
- package/src/prompts/compaction/branch-summary.md +0 -30
- package/src/prompts/compaction/compaction-short-summary.md +0 -9
- package/src/prompts/compaction/compaction-summary-context.md +0 -5
- package/src/prompts/compaction/compaction-summary.md +0 -38
- package/src/prompts/compaction/compaction-turn-prefix.md +0 -17
- package/src/prompts/compaction/compaction-update-summary.md +0 -45
- package/src/prompts/system/auto-handoff-threshold-focus.md +0 -1
- package/src/prompts/system/file-operations.md +0 -10
- package/src/prompts/system/handoff-document.md +0 -49
- package/src/prompts/system/summarization-system.md +0 -3
- package/src/session/compaction/branch-summarization.ts +0 -324
- package/src/session/compaction/compaction.ts +0 -1420
- package/src/session/compaction/errors.ts +0 -31
- package/src/session/compaction/index.ts +0 -8
- package/src/session/compaction/pruning.ts +0 -91
- package/src/session/compaction/utils.ts +0 -184
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
5
|
-
import
|
|
5
|
+
import * as z from "zod/v4";
|
|
6
6
|
import type { ToolDefinition } from "../../extensibility/extensions";
|
|
7
7
|
import type { Theme } from "../../modes/theme/theme";
|
|
8
8
|
import { replaceTabs, truncateToWidth } from "../../tools/render-utils";
|
|
@@ -36,46 +36,37 @@ import type {
|
|
|
36
36
|
|
|
37
37
|
const EXPERIMENT_TOOL_NAMES = ["init_experiment", "run_experiment", "log_experiment", "update_notes"];
|
|
38
38
|
|
|
39
|
-
const logExperimentSchema =
|
|
40
|
-
metric:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
status:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
}),
|
|
67
|
-
),
|
|
68
|
-
flag_runs: Type.Optional(
|
|
69
|
-
Type.Array(
|
|
70
|
-
Type.Object({
|
|
71
|
-
run_id: Type.Number({ description: "Run id (#) of a previously logged run to flag as suspect." }),
|
|
72
|
-
reason: Type.String({
|
|
73
|
-
description: "Why this earlier run is suspect (e.g. reward-hacked, broken metric).",
|
|
74
|
-
}),
|
|
39
|
+
const logExperimentSchema = z.object({
|
|
40
|
+
metric: z
|
|
41
|
+
.number()
|
|
42
|
+
.describe("Primary metric value for this run. May differ from the parsed value; deviation is recorded."),
|
|
43
|
+
status: z.enum(["keep", "discard", "crash", "checks_failed"] as const).describe("Outcome for this run."),
|
|
44
|
+
description: z.string().describe("Short description of the experiment."),
|
|
45
|
+
metrics: z.record(z.string(), z.number()).describe("Secondary metrics for this run.").optional(),
|
|
46
|
+
asi: z
|
|
47
|
+
.object({})
|
|
48
|
+
.passthrough()
|
|
49
|
+
.describe("Free-form structured metadata captured for this run (hypothesis, learnings, etc.).")
|
|
50
|
+
.optional(),
|
|
51
|
+
commit: z
|
|
52
|
+
.string()
|
|
53
|
+
.describe("Override the commit hash recorded for this run. Defaults to the current HEAD.")
|
|
54
|
+
.optional(),
|
|
55
|
+
justification: z
|
|
56
|
+
.string()
|
|
57
|
+
.describe(
|
|
58
|
+
"Required when the run modifies paths outside scope or inside off-limits and you still want it kept. Free-form explanation.",
|
|
59
|
+
)
|
|
60
|
+
.optional(),
|
|
61
|
+
flag_runs: z
|
|
62
|
+
.array(
|
|
63
|
+
z.object({
|
|
64
|
+
run_id: z.number().describe("Run id (#) of a previously logged run to flag as suspect."),
|
|
65
|
+
reason: z.string().describe("Why this earlier run is suspect (e.g. reward-hacked, broken metric)."),
|
|
75
66
|
}),
|
|
76
|
-
|
|
77
|
-
)
|
|
78
|
-
|
|
67
|
+
)
|
|
68
|
+
.describe("Mark earlier runs as flagged. Flagged runs are excluded from baseline and best-metric math.")
|
|
69
|
+
.optional(),
|
|
79
70
|
});
|
|
80
71
|
|
|
81
72
|
export function createLogExperimentTool(
|
|
@@ -3,7 +3,7 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
5
5
|
import { formatBytes } from "@oh-my-pi/pi-utils";
|
|
6
|
-
import
|
|
6
|
+
import * as z from "zod/v4";
|
|
7
7
|
import type { ToolDefinition } from "../../extensibility/extensions";
|
|
8
8
|
import type { Theme } from "../../modes/theme/theme";
|
|
9
9
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateTail } from "../../session/streaming-output";
|
|
@@ -26,8 +26,8 @@ import { openAutoresearchStorageIfExists } from "../storage";
|
|
|
26
26
|
import type { AutoresearchToolFactoryOptions, RunDetails, RunExperimentProgressDetails } from "../types";
|
|
27
27
|
import { DEFAULT_HARNESS_COMMAND } from "./init-experiment";
|
|
28
28
|
|
|
29
|
-
const runExperimentSchema =
|
|
30
|
-
timeout_seconds:
|
|
29
|
+
const runExperimentSchema = z.object({
|
|
30
|
+
timeout_seconds: z.number().describe("Timeout in seconds. Defaults to 600.").optional(),
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
interface ProcessExecutionResult {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Text } from "@oh-my-pi/pi-tui";
|
|
2
|
-
import
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
3
|
import type { ToolDefinition } from "../../extensibility/extensions";
|
|
4
4
|
import type { Theme } from "../../modes/theme/theme";
|
|
5
5
|
import { replaceTabs, truncateToWidth } from "../../tools/render-utils";
|
|
@@ -8,16 +8,16 @@ import { buildExperimentState } from "../state";
|
|
|
8
8
|
import { openAutoresearchStorageIfExists } from "../storage";
|
|
9
9
|
import type { AutoresearchToolFactoryOptions } from "../types";
|
|
10
10
|
|
|
11
|
-
const updateNotesSchema =
|
|
12
|
-
body:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
append_idea:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
const updateNotesSchema = z.object({
|
|
12
|
+
body: z
|
|
13
|
+
.string()
|
|
14
|
+
.describe("Replacement markdown body for the active autoresearch session's notes (your durable playbook)."),
|
|
15
|
+
append_idea: z
|
|
16
|
+
.string()
|
|
17
|
+
.describe(
|
|
18
|
+
"When set, append this string as a new bullet under an Ideas section instead of replacing the body. `body` is ignored.",
|
|
19
|
+
)
|
|
20
|
+
.optional(),
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
interface UpdateNotesDetails {
|
package/src/commands/commit.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate and optionally push a commit with changelog updates.
|
|
3
3
|
*/
|
|
4
|
+
import { postmortem } from "@oh-my-pi/pi-utils";
|
|
4
5
|
import { Command, Flags } from "@oh-my-pi/pi-utils/cli";
|
|
5
6
|
import { runCommitCommand } from "../commit";
|
|
6
7
|
import type { CommitCommandArgs } from "../commit/types";
|
|
@@ -31,6 +32,15 @@ export default class Commit extends Command {
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
await initTheme();
|
|
35
|
+
// The agentic commit flow opens HTTP/2 keep-alive sockets to the model
|
|
36
|
+
// provider (via `installH2Fetch`) and spins up an AgentSession with
|
|
37
|
+
// background async-job + extension machinery. `session.dispose()` releases
|
|
38
|
+
// what it can, but Bun's fetch keeps idle connections warm and a few
|
|
39
|
+
// timers (Settings autosave, OAuth refresh) stay armed long enough to
|
|
40
|
+
// pin the event loop after the commit is already written. Mirror the
|
|
41
|
+
// `runPrintMode` exit pattern from `main.ts` so the CLI returns to the
|
|
42
|
+
// shell instead of stranding the user on Ctrl+C (issue #1041).
|
|
34
43
|
await runCommitCommand(cmd);
|
|
44
|
+
await postmortem.quit(0);
|
|
35
45
|
}
|
|
36
46
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
2
|
-
import
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
3
|
import analyzeFilePrompt from "../../../commit/agentic/prompts/analyze-file.md" with { type: "text" };
|
|
4
4
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
5
5
|
import type { NumstatEntry } from "../../../commit/types";
|
|
@@ -12,9 +12,9 @@ import type { TaskParams } from "../../../task/types";
|
|
|
12
12
|
import type { ToolSession } from "../../../tools";
|
|
13
13
|
import { getFilePriority } from "./git-file-diff";
|
|
14
14
|
|
|
15
|
-
const analyzeFileSchema =
|
|
16
|
-
files:
|
|
17
|
-
goal:
|
|
15
|
+
const analyzeFileSchema = z.object({
|
|
16
|
+
files: z.array(z.string().describe("File path")).min(1),
|
|
17
|
+
goal: z.string().describe("Optional analysis focus").optional(),
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
const analyzeFileOutputSchema = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
3
3
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
4
4
|
import * as git from "../../../utils/git";
|
|
@@ -131,9 +131,9 @@ function processDiffs(files: string[], diffs: Map<string, string>): { result: st
|
|
|
131
131
|
return { result: parts.join("\n\n"), truncatedFiles };
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
const gitFileDiffSchema =
|
|
135
|
-
files:
|
|
136
|
-
staged:
|
|
134
|
+
const gitFileDiffSchema = z.object({
|
|
135
|
+
files: z.array(z.string().describe("Files to diff")).min(1).max(10),
|
|
136
|
+
staged: z.boolean().describe("Use staged changes (default: true)").optional(),
|
|
137
137
|
});
|
|
138
138
|
|
|
139
139
|
export function createGitFileDiffTool(cwd: string, state: CommitAgentState): CustomTool<typeof gitFileDiffSchema> {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { DiffHunk, FileHunks } from "../../../commit/types";
|
|
3
3
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
4
4
|
import * as git from "../../../utils/git";
|
|
5
5
|
|
|
6
|
-
const gitHunkSchema =
|
|
7
|
-
file:
|
|
8
|
-
hunks:
|
|
9
|
-
staged:
|
|
6
|
+
const gitHunkSchema = z.object({
|
|
7
|
+
file: z.string().describe("File path"),
|
|
8
|
+
hunks: z.array(z.number().describe("1-based hunk indices")).min(1).optional(),
|
|
9
|
+
staged: z.boolean().describe("Use staged changes (default: true)").optional(),
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
function selectHunks(fileHunks: FileHunks, requested?: number[]): DiffHunk[] {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CommitAgentState, GitOverviewSnapshot } from "../../../commit/agentic/state";
|
|
3
3
|
import { extractScopeCandidates } from "../../../commit/analysis/scope";
|
|
4
4
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
@@ -42,9 +42,9 @@ function filterExcludedFiles(files: string[]): { filtered: string[]; excluded: s
|
|
|
42
42
|
return { filtered, excluded };
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const gitOverviewSchema =
|
|
46
|
-
staged:
|
|
47
|
-
include_untracked:
|
|
45
|
+
const gitOverviewSchema = z.object({
|
|
46
|
+
staged: z.boolean().describe("Use staged changes (default: true)").optional(),
|
|
47
|
+
include_untracked: z.boolean().describe("Include untracked files when staged=false").optional(),
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
export function createGitOverviewTool(cwd: string, state: CommitAgentState): CustomTool<typeof gitOverviewSchema> {
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
3
3
|
import { CHANGELOG_CATEGORIES, type ChangelogCategory } from "../../../commit/types";
|
|
4
4
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
5
5
|
|
|
6
|
-
const changelogEntryProperties = CHANGELOG_CATEGORIES.reduce<Record<ChangelogCategory,
|
|
6
|
+
const changelogEntryProperties = CHANGELOG_CATEGORIES.reduce<Record<ChangelogCategory, z.ZodType>>(
|
|
7
7
|
(acc, category) => {
|
|
8
|
-
acc[category] =
|
|
8
|
+
acc[category] = z.array(z.string()).optional();
|
|
9
9
|
return acc;
|
|
10
10
|
},
|
|
11
|
-
{} as Record<ChangelogCategory,
|
|
11
|
+
{} as Record<ChangelogCategory, z.ZodType>,
|
|
12
12
|
);
|
|
13
13
|
|
|
14
|
-
const changelogEntriesSchema =
|
|
15
|
-
const changelogDeletionsSchema =
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
const changelogEntriesSchema = z.object(changelogEntryProperties);
|
|
15
|
+
const changelogDeletionsSchema = z
|
|
16
|
+
.object(changelogEntryProperties)
|
|
17
|
+
.describe("Entries to remove from existing changelog sections (case-insensitive match)");
|
|
18
18
|
|
|
19
|
-
const changelogEntrySchema =
|
|
20
|
-
path:
|
|
19
|
+
const changelogEntrySchema = z.object({
|
|
20
|
+
path: z.string(),
|
|
21
21
|
entries: changelogEntriesSchema,
|
|
22
|
-
deletions:
|
|
22
|
+
deletions: changelogDeletionsSchema.optional(),
|
|
23
23
|
});
|
|
24
24
|
|
|
25
|
-
const proposeChangelogSchema =
|
|
26
|
-
entries:
|
|
25
|
+
const proposeChangelogSchema = z.object({
|
|
26
|
+
entries: z.array(changelogEntrySchema),
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
interface ChangelogResponse {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CommitAgentState } from "../../../commit/agentic/state";
|
|
3
3
|
import {
|
|
4
4
|
capDetails,
|
|
@@ -15,12 +15,12 @@ import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
|
15
15
|
import * as git from "../../../utils/git";
|
|
16
16
|
import { commitTypeSchema, detailSchema } from "./schemas.js";
|
|
17
17
|
|
|
18
|
-
const proposeCommitSchema =
|
|
18
|
+
const proposeCommitSchema = z.object({
|
|
19
19
|
type: commitTypeSchema,
|
|
20
|
-
scope:
|
|
21
|
-
summary:
|
|
22
|
-
details:
|
|
23
|
-
issue_refs:
|
|
20
|
+
scope: z.union([z.string(), z.null()]),
|
|
21
|
+
summary: z.string(),
|
|
22
|
+
details: z.array(detailSchema),
|
|
23
|
+
issue_refs: z.array(z.string()),
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
interface ProposalResponse {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
3
3
|
import * as git from "../../../utils/git";
|
|
4
4
|
|
|
5
|
-
const recentCommitsSchema =
|
|
6
|
-
count:
|
|
5
|
+
const recentCommitsSchema = z.object({
|
|
6
|
+
count: z.number().min(1).max(50).describe("Number of commits to fetch").optional(),
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
interface RecentCommitStats {
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
|
|
3
|
-
export const commitTypeSchema =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
]);
|
|
3
|
+
export const commitTypeSchema = z.enum([
|
|
4
|
+
"feat",
|
|
5
|
+
"fix",
|
|
6
|
+
"refactor",
|
|
7
|
+
"perf",
|
|
8
|
+
"docs",
|
|
9
|
+
"test",
|
|
10
|
+
"build",
|
|
11
|
+
"ci",
|
|
12
|
+
"chore",
|
|
13
|
+
"style",
|
|
14
|
+
"revert",
|
|
15
|
+
] as const);
|
|
16
16
|
|
|
17
|
-
export const detailSchema =
|
|
18
|
-
text:
|
|
19
|
-
changelog_category:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
])
|
|
29
|
-
|
|
30
|
-
user_visible:
|
|
17
|
+
export const detailSchema = z.object({
|
|
18
|
+
text: z.string(),
|
|
19
|
+
changelog_category: z
|
|
20
|
+
.union([
|
|
21
|
+
z.literal("Added"),
|
|
22
|
+
z.literal("Changed"),
|
|
23
|
+
z.literal("Fixed"),
|
|
24
|
+
z.literal("Deprecated"),
|
|
25
|
+
z.literal("Removed"),
|
|
26
|
+
z.literal("Security"),
|
|
27
|
+
z.literal("Breaking Changes"),
|
|
28
|
+
])
|
|
29
|
+
.optional(),
|
|
30
|
+
user_visible: z.boolean().optional(),
|
|
31
31
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
2
|
import type { CommitAgentState, SplitCommitGroup, SplitCommitPlan } from "../../../commit/agentic/state";
|
|
3
3
|
import { computeDependencyOrder } from "../../../commit/agentic/topo-sort";
|
|
4
4
|
import {
|
|
@@ -15,31 +15,32 @@ import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
|
15
15
|
import * as git from "../../../utils/git";
|
|
16
16
|
import { commitTypeSchema, detailSchema } from "./schemas.js";
|
|
17
17
|
|
|
18
|
-
const hunkSelectorSchema =
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const hunkSelectorSchema = z.discriminatedUnion("type", [
|
|
19
|
+
z.object({ type: z.literal("all") }),
|
|
20
|
+
z.object({ type: z.literal("indices"), indices: z.array(z.number()).min(1) }),
|
|
21
|
+
z.object({ type: z.literal("lines"), start: z.number(), end: z.number() }),
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
|
-
const fileChangeSchema =
|
|
25
|
-
path:
|
|
24
|
+
const fileChangeSchema = z.object({
|
|
25
|
+
path: z.string(),
|
|
26
26
|
hunks: hunkSelectorSchema,
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
const splitCommitSchema =
|
|
30
|
-
commits:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
29
|
+
const splitCommitSchema = z.object({
|
|
30
|
+
commits: z
|
|
31
|
+
.array(
|
|
32
|
+
z.object({
|
|
33
|
+
changes: z.array(fileChangeSchema).min(1),
|
|
34
|
+
type: commitTypeSchema,
|
|
35
|
+
scope: z.union([z.string(), z.null()]),
|
|
36
|
+
summary: z.string(),
|
|
37
|
+
details: z.array(detailSchema).optional(),
|
|
38
|
+
issue_refs: z.array(z.string()).optional(),
|
|
39
|
+
rationale: z.string().optional(),
|
|
40
|
+
dependencies: z.array(z.number()).optional(),
|
|
41
|
+
}),
|
|
42
|
+
)
|
|
43
|
+
.min(2),
|
|
43
44
|
});
|
|
44
45
|
|
|
45
46
|
interface SplitCommitResponse {
|
|
@@ -2,7 +2,7 @@ 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
4
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import
|
|
5
|
+
import * as z from "zod/v4";
|
|
6
6
|
import summarySystemPrompt from "../../commit/prompts/summary-system.md" with { type: "text" };
|
|
7
7
|
import summaryUserPrompt from "../../commit/prompts/summary-user.md" with { type: "text" };
|
|
8
8
|
import type { CommitSummary } from "../../commit/types";
|
|
@@ -12,8 +12,8 @@ import { extractTextContent, extractToolCall } from "../utils";
|
|
|
12
12
|
const SummaryTool = {
|
|
13
13
|
name: "create_commit_summary",
|
|
14
14
|
description: "Generate the summary line for a conventional commit message.",
|
|
15
|
-
parameters:
|
|
16
|
-
summary:
|
|
15
|
+
parameters: z.object({
|
|
16
|
+
summary: z.string(),
|
|
17
17
|
}),
|
|
18
18
|
};
|
|
19
19
|
|
|
@@ -83,7 +83,7 @@ function renderSummaryPrompt({
|
|
|
83
83
|
function parseSummaryFromResponse(message: AssistantMessage, commitType: string, scope: string | null): CommitSummary {
|
|
84
84
|
const toolCall = extractToolCall(message, "create_commit_summary");
|
|
85
85
|
if (toolCall) {
|
|
86
|
-
const parsed = validateToolCall([SummaryTool], toolCall) as
|
|
86
|
+
const parsed = validateToolCall([SummaryTool], toolCall) as z.infer<(typeof SummaryTool)["parameters"]>;
|
|
87
87
|
return { summary: stripTypePrefix(parsed.summary, commitType, scope) };
|
|
88
88
|
}
|
|
89
89
|
const text = extractTextContent(message);
|
|
@@ -2,27 +2,23 @@ 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
4
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
5
|
-
import
|
|
5
|
+
import * as z from "zod/v4";
|
|
6
6
|
import changelogSystemPrompt from "../../commit/prompts/changelog-system.md" with { type: "text" };
|
|
7
7
|
import changelogUserPrompt from "../../commit/prompts/changelog-user.md" with { type: "text" };
|
|
8
8
|
import { CHANGELOG_CATEGORIES, type ChangelogCategory, type ChangelogGenerationResult } from "../../commit/types";
|
|
9
9
|
import { toReasoningEffort } from "../../thinking";
|
|
10
10
|
import { extractTextContent, extractToolCall, parseJsonPayload } from "../utils";
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
(
|
|
14
|
-
|
|
15
|
-
return acc;
|
|
16
|
-
},
|
|
17
|
-
{} as Record<ChangelogCategory, TSchema>,
|
|
18
|
-
);
|
|
12
|
+
const changelogEntryShape = Object.fromEntries(
|
|
13
|
+
CHANGELOG_CATEGORIES.map(c => [c, z.array(z.string()).optional()] as const),
|
|
14
|
+
) as Record<ChangelogCategory, z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
19
15
|
|
|
20
|
-
const changelogEntriesSchema =
|
|
16
|
+
const changelogEntriesSchema = z.object(changelogEntryShape);
|
|
21
17
|
|
|
22
18
|
export const changelogTool = {
|
|
23
19
|
name: "create_changelog_entries",
|
|
24
20
|
description: "Generate changelog entries grouped by Keep a Changelog categories.",
|
|
25
|
-
parameters:
|
|
21
|
+
parameters: z.object({
|
|
26
22
|
entries: changelogEntriesSchema,
|
|
27
23
|
}),
|
|
28
24
|
};
|
|
@@ -72,7 +68,7 @@ export async function generateChangelogEntries({
|
|
|
72
68
|
function parseChangelogResponse(message: AssistantMessage): ChangelogGenerationResult {
|
|
73
69
|
const toolCall = extractToolCall(message, "create_changelog_entries");
|
|
74
70
|
if (toolCall) {
|
|
75
|
-
const parsed = validateToolCall([changelogTool], toolCall) as
|
|
71
|
+
const parsed = validateToolCall([changelogTool], toolCall) as z.infer<(typeof changelogTool)["parameters"]>;
|
|
76
72
|
return { entries: parsed.entries ?? {} };
|
|
77
73
|
}
|
|
78
74
|
|
package/src/commit/shared-llm.ts
CHANGED
|
@@ -1,48 +1,36 @@
|
|
|
1
1
|
import type { AssistantMessage } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import { validateToolCall } from "@oh-my-pi/pi-ai";
|
|
3
|
-
import
|
|
3
|
+
import * as z from "zod/v4";
|
|
4
4
|
import type { ChangelogCategory, ConventionalAnalysis } from "./types";
|
|
5
5
|
import { extractTextContent, extractToolCall, normalizeAnalysis, parseJsonPayload } from "./utils";
|
|
6
6
|
|
|
7
|
+
const changelogCategoryLiteral = z.enum([
|
|
8
|
+
"Added",
|
|
9
|
+
"Changed",
|
|
10
|
+
"Fixed",
|
|
11
|
+
"Deprecated",
|
|
12
|
+
"Removed",
|
|
13
|
+
"Security",
|
|
14
|
+
"Breaking Changes",
|
|
15
|
+
]);
|
|
16
|
+
|
|
7
17
|
/**
|
|
8
|
-
* Shared
|
|
18
|
+
* Shared Zod schema for the `create_conventional_analysis` tool used by
|
|
9
19
|
* both the single-pass analysis call and the map-reduce reduce phase. Schemas
|
|
10
20
|
* are identical across phases — only the surrounding tool `description`
|
|
11
21
|
* differs to reflect the input the phase is summarizing.
|
|
12
22
|
*/
|
|
13
|
-
export const conventionalAnalysisParameters =
|
|
14
|
-
type:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Type.Literal("style"),
|
|
22
|
-
Type.Literal("perf"),
|
|
23
|
-
Type.Literal("build"),
|
|
24
|
-
Type.Literal("ci"),
|
|
25
|
-
Type.Literal("revert"),
|
|
26
|
-
]),
|
|
27
|
-
scope: Type.Union([Type.String(), Type.Null()]),
|
|
28
|
-
details: Type.Array(
|
|
29
|
-
Type.Object({
|
|
30
|
-
text: Type.String(),
|
|
31
|
-
changelog_category: Type.Optional(
|
|
32
|
-
Type.Union([
|
|
33
|
-
Type.Literal("Added"),
|
|
34
|
-
Type.Literal("Changed"),
|
|
35
|
-
Type.Literal("Fixed"),
|
|
36
|
-
Type.Literal("Deprecated"),
|
|
37
|
-
Type.Literal("Removed"),
|
|
38
|
-
Type.Literal("Security"),
|
|
39
|
-
Type.Literal("Breaking Changes"),
|
|
40
|
-
]),
|
|
41
|
-
),
|
|
42
|
-
user_visible: Type.Optional(Type.Boolean()),
|
|
23
|
+
export const conventionalAnalysisParameters = z.object({
|
|
24
|
+
type: z.enum(["feat", "fix", "refactor", "docs", "test", "chore", "style", "perf", "build", "ci", "revert"]),
|
|
25
|
+
scope: z.union([z.string(), z.null()]),
|
|
26
|
+
details: z.array(
|
|
27
|
+
z.object({
|
|
28
|
+
text: z.string(),
|
|
29
|
+
changelog_category: changelogCategoryLiteral.optional(),
|
|
30
|
+
user_visible: z.boolean().optional(),
|
|
43
31
|
}),
|
|
44
32
|
),
|
|
45
|
-
issue_refs:
|
|
33
|
+
issue_refs: z.array(z.string()),
|
|
46
34
|
});
|
|
47
35
|
|
|
48
36
|
export interface ConventionalAnalysisTool {
|
|
@@ -80,7 +68,7 @@ export function parseConventionalAnalysisResponse(
|
|
|
80
68
|
): ConventionalAnalysis {
|
|
81
69
|
const toolCall = extractToolCall(message, tool.name);
|
|
82
70
|
if (toolCall) {
|
|
83
|
-
const parsed = validateToolCall([tool], toolCall) as
|
|
71
|
+
const parsed = validateToolCall([tool], toolCall) as z.infer<typeof conventionalAnalysisParameters>;
|
|
84
72
|
return normalizeAnalysis(parsed);
|
|
85
73
|
}
|
|
86
74
|
const text = extractTextContent(message);
|