@oh-my-pi/pi-coding-agent 15.10.0 → 15.10.1
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 +75 -1
- package/dist/types/cli/dry-balance-cli.d.ts +15 -1
- package/dist/types/commit/analysis/conventional.d.ts +2 -2
- package/dist/types/commit/analysis/summary.d.ts +2 -2
- package/dist/types/commit/changelog/generate.d.ts +2 -2
- package/dist/types/commit/changelog/index.d.ts +2 -2
- package/dist/types/commit/map-reduce/index.d.ts +3 -3
- package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
- package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
- package/dist/types/commit/model-selection.d.ts +10 -4
- package/dist/types/config/api-key-resolver.d.ts +34 -0
- package/dist/types/config/model-registry.d.ts +17 -1
- package/dist/types/config/settings-schema.d.ts +9 -0
- package/dist/types/dap/config.d.ts +14 -1
- package/dist/types/dap/types.d.ts +10 -0
- package/dist/types/lsp/utils.d.ts +3 -2
- package/dist/types/modes/components/chat-block.d.ts +64 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -0
- package/dist/types/modes/components/overlay-box.d.ts +17 -0
- package/dist/types/modes/components/plan-review-overlay.d.ts +59 -0
- package/dist/types/modes/components/plan-toc.d.ts +41 -0
- package/dist/types/modes/components/read-tool-group.d.ts +2 -0
- package/dist/types/modes/components/transcript-container.d.ts +11 -0
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/controllers/event-controller.d.ts +0 -1
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
- package/dist/types/modes/controllers/input-controller.d.ts +1 -1
- package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
- package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +15 -5
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +18 -5
- package/dist/types/modes/utils/copy-targets.d.ts +21 -1
- package/dist/types/plan-mode/approved-plan.d.ts +27 -8
- package/dist/types/plan-mode/plan-protection.d.ts +4 -4
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +21 -0
- package/dist/types/session/messages.d.ts +12 -0
- package/dist/types/session/session-manager.d.ts +3 -1
- package/dist/types/slash-commands/types.d.ts +4 -6
- package/dist/types/task/executor.d.ts +7 -0
- package/dist/types/task/index.d.ts +1 -0
- package/dist/types/task/render.d.ts +3 -2
- package/dist/types/tools/archive-reader.d.ts +5 -0
- package/dist/types/tools/ast-edit.d.ts +3 -0
- package/dist/types/tools/ast-grep.d.ts +3 -0
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/find.d.ts +8 -4
- package/dist/types/tools/grouped-file-output.d.ts +95 -12
- package/dist/types/tools/memory-render.d.ts +4 -1
- package/dist/types/tools/plan-mode-guard.d.ts +8 -9
- package/dist/types/tools/render-utils.d.ts +5 -9
- package/dist/types/tools/search.d.ts +4 -0
- package/dist/types/tools/sqlite-reader.d.ts +1 -0
- package/dist/types/tools/todo.d.ts +3 -2
- package/dist/types/tools/write.d.ts +3 -0
- package/dist/types/tui/output-block.d.ts +16 -4
- package/dist/types/tui/status-line.d.ts +3 -0
- package/dist/types/utils/enhanced-paste.d.ts +20 -0
- package/dist/types/web/search/providers/kimi.d.ts +1 -1
- package/package.json +9 -9
- package/src/auto-thinking/classifier.ts +5 -1
- package/src/cli/dry-balance-cli.ts +52 -17
- package/src/cli/gallery-cli.ts +4 -1
- package/src/cli/gallery-fixtures/misc.ts +29 -0
- package/src/commit/analysis/conventional.ts +2 -2
- package/src/commit/analysis/summary.ts +2 -2
- package/src/commit/changelog/generate.ts +2 -2
- package/src/commit/changelog/index.ts +2 -2
- package/src/commit/map-reduce/index.ts +3 -3
- package/src/commit/map-reduce/map-phase.ts +2 -2
- package/src/commit/map-reduce/reduce-phase.ts +2 -2
- package/src/commit/model-selection.ts +33 -9
- package/src/commit/pipeline.ts +4 -4
- package/src/config/api-key-resolver.ts +58 -0
- package/src/config/model-registry.ts +25 -2
- package/src/config/settings-schema.ts +10 -0
- package/src/config/settings.ts +20 -2
- package/src/dap/config.ts +41 -2
- package/src/dap/defaults.json +1 -0
- package/src/dap/session.ts +1 -0
- package/src/dap/types.ts +10 -0
- package/src/debug/index.ts +40 -54
- package/src/edit/renderer.ts +82 -78
- package/src/eval/__tests__/llm-bridge.test.ts +90 -31
- package/src/eval/llm-bridge.ts +8 -3
- package/src/goals/tools/goal-tool.ts +36 -26
- package/src/internal-urls/docs-index.generated.ts +6 -6
- package/src/lsp/utils.ts +3 -2
- package/src/main.ts +9 -7
- package/src/memories/index.ts +12 -5
- package/src/mnemopi/backend.ts +5 -1
- package/src/modes/acp/acp-agent.ts +33 -26
- package/src/modes/components/assistant-message.ts +2 -9
- package/src/modes/components/chat-block.ts +111 -0
- package/src/modes/components/copy-selector.ts +1 -44
- package/src/modes/components/custom-editor.ts +23 -0
- package/src/modes/components/custom-message.ts +1 -3
- package/src/modes/components/execution-shared.ts +1 -2
- package/src/modes/components/hook-message.ts +1 -3
- package/src/modes/components/overlay-box.ts +108 -0
- package/src/modes/components/plan-review-overlay.ts +799 -0
- package/src/modes/components/plan-toc.ts +138 -0
- package/src/modes/components/read-tool-group.ts +20 -4
- package/src/modes/components/skill-message.ts +0 -1
- package/src/modes/components/tips.txt +1 -0
- package/src/modes/components/todo-reminder.ts +0 -2
- package/src/modes/components/tool-execution.ts +68 -88
- package/src/modes/components/transcript-container.ts +84 -24
- package/src/modes/components/user-message.ts +1 -2
- package/src/modes/controllers/command-controller-shared.ts +7 -6
- package/src/modes/controllers/command-controller.ts +57 -55
- package/src/modes/controllers/event-controller.ts +41 -40
- package/src/modes/controllers/extension-ui-controller.ts +10 -73
- package/src/modes/controllers/input-controller.ts +124 -119
- package/src/modes/controllers/mcp-command-controller.ts +69 -60
- package/src/modes/controllers/selector-controller.ts +23 -25
- package/src/modes/controllers/streaming-reveal.ts +212 -0
- package/src/modes/controllers/tan-command-controller.ts +173 -0
- package/src/modes/interactive-mode.ts +169 -94
- package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
- package/src/modes/theme/theme-schema.json +1 -1
- package/src/modes/theme/theme.ts +8 -4
- package/src/modes/types.ts +18 -7
- package/src/modes/utils/copy-targets.ts +133 -27
- package/src/modes/utils/ui-helpers.ts +44 -46
- package/src/plan-mode/approved-plan.ts +66 -43
- package/src/plan-mode/plan-protection.ts +4 -4
- package/src/prompts/system/background-tan-dispatch.md +8 -0
- package/src/prompts/system/plan-mode-active.md +67 -58
- package/src/prompts/system/plan-mode-approved.md +1 -1
- package/src/sdk.ts +11 -37
- package/src/session/agent-session.ts +82 -6
- package/src/session/messages.ts +26 -0
- package/src/session/session-manager.ts +13 -5
- package/src/slash-commands/builtin-registry.ts +36 -9
- package/src/slash-commands/types.ts +4 -6
- package/src/task/executor.ts +5 -2
- package/src/task/index.ts +4 -0
- package/src/task/render.ts +212 -147
- package/src/tools/archive-reader.ts +64 -0
- package/src/tools/ask.ts +119 -164
- package/src/tools/ast-edit.ts +98 -71
- package/src/tools/ast-grep.ts +37 -43
- package/src/tools/bash.ts +50 -6
- package/src/tools/debug.ts +20 -8
- package/src/tools/fetch.ts +297 -7
- package/src/tools/find.ts +44 -30
- package/src/tools/gh-renderer.ts +81 -42
- package/src/tools/grouped-file-output.ts +272 -48
- package/src/tools/image-gen.ts +150 -103
- package/src/tools/inspect-image-renderer.ts +63 -41
- package/src/tools/inspect-image.ts +8 -1
- package/src/tools/job.ts +3 -4
- package/src/tools/memory-render.ts +4 -1
- package/src/tools/plan-mode-guard.ts +21 -39
- package/src/tools/read.ts +23 -16
- package/src/tools/render-utils.ts +21 -37
- package/src/tools/resolve.ts +14 -0
- package/src/tools/search-tool-bm25.ts +36 -23
- package/src/tools/search.ts +80 -78
- package/src/tools/sqlite-reader.ts +9 -12
- package/src/tools/todo.ts +118 -52
- package/src/tools/write.ts +81 -62
- package/src/tui/output-block.ts +60 -13
- package/src/tui/status-line.ts +5 -1
- package/src/utils/commit-message-generator.ts +9 -1
- package/src/utils/enhanced-paste.ts +202 -0
- package/src/utils/title-generator.ts +2 -1
- package/src/web/search/providers/anthropic.ts +25 -19
- package/src/web/search/providers/exa.ts +11 -3
- package/src/web/search/providers/kimi.ts +28 -17
- package/src/web/search/providers/parallel.ts +35 -24
- package/src/web/search/providers/synthetic.ts +8 -6
- package/src/web/search/providers/tavily.ts +9 -8
- package/src/web/search/providers/zai.ts +8 -6
|
@@ -15,10 +15,14 @@ declare const findSchema: z.ZodObject<{
|
|
|
15
15
|
}, z.core.$strict>;
|
|
16
16
|
export type FindToolInput = z.infer<typeof findSchema>;
|
|
17
17
|
/**
|
|
18
|
-
* Group find matches
|
|
19
|
-
* tokens for shared path prefixes.
|
|
20
|
-
*
|
|
21
|
-
*
|
|
18
|
+
* Group find matches into a multi-level directory tree so the model doesn't pay
|
|
19
|
+
* repeated tokens for shared path prefixes. Single-child directory chains fold
|
|
20
|
+
* into one header (`# a/b/c/`), so a common prefix — including an absolute root
|
|
21
|
+
* for out-of-cwd results — collapses to a single line. Each level adds one `#`;
|
|
22
|
+
* files are listed bare under the deepest directory header that owns them.
|
|
23
|
+
*
|
|
24
|
+
* Order follows the input (mtime-desc for native glob): a directory appears when
|
|
25
|
+
* its first member is emitted, and a node's own files precede its subdirectories.
|
|
22
26
|
*/
|
|
23
27
|
export declare function formatFindGroupedOutput(paths: readonly string[]): string;
|
|
24
28
|
export interface FindToolDetails {
|
|
@@ -1,7 +1,55 @@
|
|
|
1
|
+
interface PathTreeNode {
|
|
2
|
+
/** Direct file leaves, in first-seen order. */
|
|
3
|
+
files: Array<{
|
|
4
|
+
name: string;
|
|
5
|
+
key: string;
|
|
6
|
+
}>;
|
|
7
|
+
/** Dedup set for `files` (a glob can surface the same path twice on retry). */
|
|
8
|
+
fileNames: Set<string>;
|
|
9
|
+
/** Child directories, in first-seen order. */
|
|
10
|
+
subdirs: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
node: PathTreeNode;
|
|
13
|
+
}>;
|
|
14
|
+
/** Dedup index for `subdirs`. */
|
|
15
|
+
dirIndex: Map<string, PathTreeNode>;
|
|
16
|
+
}
|
|
17
|
+
export interface PathTreeInput {
|
|
18
|
+
/** Path string; absolute, cwd-relative, or url-like. Backslashes are normalized. */
|
|
19
|
+
path: string;
|
|
20
|
+
/** Whether the leaf itself is a directory (trailing-slash match from find). */
|
|
21
|
+
isDir: boolean;
|
|
22
|
+
/** Opaque key carried onto file events for section lookup. Defaults to `path`. */
|
|
23
|
+
key?: string;
|
|
24
|
+
}
|
|
25
|
+
/** One node emitted while walking the tree: a folded directory or a file leaf. */
|
|
26
|
+
export interface GroupedTreeEvent {
|
|
27
|
+
kind: "dir" | "file";
|
|
28
|
+
/** 0-based nesting depth (root children are depth 0). */
|
|
29
|
+
depth: number;
|
|
30
|
+
/** Folded chain for dirs (e.g. `a/b/c`, no trailing slash); basename for files. */
|
|
31
|
+
name: string;
|
|
32
|
+
/** File key for `kind === "file"`; empty string for directories. */
|
|
33
|
+
key: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a directory tree from a flat list of paths. URL-like entries are kept
|
|
37
|
+
* whole as root-level file leaves (they have no meaningful directory structure).
|
|
38
|
+
* Absolute paths carry a leading empty segment so they share a common `/` root
|
|
39
|
+
* and fold like any other prefix.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildPathTree(entries: Iterable<PathTreeInput>): PathTreeNode;
|
|
42
|
+
/**
|
|
43
|
+
* Depth-first walk yielding directory and file events. Directories collapse their
|
|
44
|
+
* single-child chains (`a` → `a/b` → `a/b/c`) so a shared prefix becomes one
|
|
45
|
+
* header. Each node's direct files are emitted before its subdirectories, keeping
|
|
46
|
+
* a file unambiguously attached to the header above it.
|
|
47
|
+
*/
|
|
48
|
+
export declare function walkPathTree(node: PathTreeNode, depth?: number): Generator<GroupedTreeEvent>;
|
|
1
49
|
/**
|
|
2
50
|
* One file's contribution to a grouped file output. The header itself is generated
|
|
3
|
-
* by `formatGroupedFiles` (
|
|
4
|
-
*
|
|
51
|
+
* by `formatGroupedFiles` (one `#` per nesting level); use `headerSuffix` to tack
|
|
52
|
+
* on extras like ` (1 replacement)`.
|
|
5
53
|
*/
|
|
6
54
|
export interface GroupedFileSection {
|
|
7
55
|
/** Optional suffix appended to the file header. */
|
|
@@ -18,19 +66,54 @@ export interface GroupedFilesOutput {
|
|
|
18
66
|
display: string[];
|
|
19
67
|
}
|
|
20
68
|
/**
|
|
21
|
-
* Render a list of files as
|
|
22
|
-
* ast-edit, and the LSP diagnostic formatter.
|
|
69
|
+
* Render a list of files as a multi-level, prefix-folded directory tree shared by
|
|
70
|
+
* grep, ast-grep, ast-edit, and the LSP diagnostic formatter.
|
|
23
71
|
*
|
|
24
|
-
* Layout:
|
|
25
|
-
* #
|
|
26
|
-
* ##
|
|
72
|
+
* Layout (one `#` per level; the shared prefix folds into the top header):
|
|
73
|
+
* # packages/pkg/src/
|
|
74
|
+
* ## root.ts
|
|
27
75
|
* …body…
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* ## other.ts
|
|
76
|
+
* ## nested/
|
|
77
|
+
* ### child.ts
|
|
31
78
|
* …body…
|
|
32
79
|
*
|
|
33
|
-
* Files in the project root
|
|
34
|
-
*
|
|
80
|
+
* Files in the (folded) project root become single-`#` headers with no parent
|
|
81
|
+
* directory line. A blank line precedes every directory header and every
|
|
82
|
+
* root-level file so the renderers can split the output into collapsible groups.
|
|
35
83
|
*/
|
|
36
84
|
export declare function formatGroupedFiles(files: string[], renderFile: (filePath: string) => GroupedFileSection): GroupedFilesOutput;
|
|
85
|
+
/** Per-line classification of grouped output, used by renderers for hyperlinks. */
|
|
86
|
+
export interface GroupedLineContext {
|
|
87
|
+
/** Directory header, file header, or any non-header body/content line. */
|
|
88
|
+
kind: "dir" | "file" | "content";
|
|
89
|
+
/** Number of leading `#` for headers; 0 for content lines. */
|
|
90
|
+
depth: number;
|
|
91
|
+
/** Resolved absolute path of the dir/file a header points at (when resolvable). */
|
|
92
|
+
headerPath?: string;
|
|
93
|
+
/** For content lines, the absolute path of the owning file (line hyperlinks). */
|
|
94
|
+
filePath?: string;
|
|
95
|
+
/** Header is an internal/url-like target the caller resolves itself. */
|
|
96
|
+
isUrl?: boolean;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Walk grouped output lines, tracking a directory stack keyed by header depth, so
|
|
100
|
+
* each header and body line can be linked back to its absolute filesystem path.
|
|
101
|
+
* Reconstruction is stack-based (not per-blank-group) so nested directory headers
|
|
102
|
+
* resolve correctly across the whole output.
|
|
103
|
+
*
|
|
104
|
+
* `headerBase` is the directory the displayed (folded) header paths are relative
|
|
105
|
+
* to — for grep/ast tools that is the session cwd, since display paths are
|
|
106
|
+
* formatted relative to cwd regardless of the (sub)directory the search was
|
|
107
|
+
* scoped to. `fileScope` is the initial owning file for body lines that appear
|
|
108
|
+
* before any header (single-file scopes have no `#` headers); it defaults to
|
|
109
|
+
* `headerBase` and should be passed the scoped file's absolute path.
|
|
110
|
+
*/
|
|
111
|
+
export declare function classifyGroupedLines(lines: readonly string[], headerBase: string | undefined, fileScope?: string | undefined): GroupedLineContext[];
|
|
112
|
+
/**
|
|
113
|
+
* Split line indices into blank-line-separated groups, mirroring
|
|
114
|
+
* `splitGroupsByBlankLine`: when any blank line is present, break on runs of
|
|
115
|
+
* blanks; otherwise return a single group of the non-empty lines. Returning
|
|
116
|
+
* indices lets callers slice parallel arrays (raw lines, styled lines, contexts).
|
|
117
|
+
*/
|
|
118
|
+
export declare function groupLineIndicesByBlank(rawLines: readonly string[]): number[][];
|
|
119
|
+
export {};
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* These keep the transcript terse — one status line plus, for `retain`, one
|
|
6
6
|
* `Remember: …` line per stored item — instead of the generic JSON arg tree,
|
|
7
|
-
* which exploded multi-line memory blobs into an unreadable wall.
|
|
7
|
+
* which exploded multi-line memory blobs into an unreadable wall. The tool
|
|
8
|
+
* container is a transparent passthrough, so these renderers stay frameless:
|
|
9
|
+
* a status line with a couple of dim bullets reads far cleaner than boxing a
|
|
10
|
+
* one-line memory note.
|
|
8
11
|
*/
|
|
9
12
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
10
13
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { ToolSession } from ".";
|
|
2
2
|
/**
|
|
3
|
-
* Resolve a write/edit target to its absolute filesystem path
|
|
4
|
-
*
|
|
5
|
-
* In plan mode, transparently redirects `PLAN.md` aliases and targets whose
|
|
6
|
-
* basename matches the plan file's basename to the canonical plan file
|
|
7
|
-
* location at `state.planFilePath`. This lets `write` and `edit` accept the
|
|
8
|
-
* habitual plan filename after approval even when the active artifact has a
|
|
9
|
-
* titled path such as `local://APPROVED.md`.
|
|
10
|
-
*
|
|
11
|
-
* Outside plan mode (or when the basename does not match) this is a no-op.
|
|
3
|
+
* Resolve a write/edit target to its absolute filesystem path, honoring the
|
|
4
|
+
* `local://` and `vault://` schemes. Plain paths resolve against the session cwd.
|
|
12
5
|
*/
|
|
13
6
|
export declare function resolvePlanPath(session: ToolSession, targetPath: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Plan mode keeps the working tree read-only while letting the agent draft its
|
|
9
|
+
* plan. Writes and edits to the `local://` artifact sandbox are allowed (that is
|
|
10
|
+
* where the plan and any scratch notes live); anything that would touch the
|
|
11
|
+
* working tree — or rename/delete a file — is rejected.
|
|
12
|
+
*/
|
|
14
13
|
export declare function enforcePlanModeWrite(session: ToolSession, targetPath: string, options?: {
|
|
15
14
|
move?: string;
|
|
16
15
|
op?: "create" | "update" | "delete";
|
|
@@ -46,8 +46,8 @@ export declare const TRUNCATE_LENGTHS: {
|
|
|
46
46
|
/** Very short (task previews, badges) */
|
|
47
47
|
readonly SHORT: 40;
|
|
48
48
|
};
|
|
49
|
-
/**
|
|
50
|
-
export declare
|
|
49
|
+
/** Human-readable key currently bound to tool-output expansion, e.g. `Ctrl+O`. */
|
|
50
|
+
export declare function expandKeyHint(): string;
|
|
51
51
|
/**
|
|
52
52
|
* Get first N lines of text as preview, with each line truncated.
|
|
53
53
|
*/
|
|
@@ -163,18 +163,14 @@ export declare function capParseErrors(errors: string[] | undefined, limit?: num
|
|
|
163
163
|
errors: string[];
|
|
164
164
|
total: number;
|
|
165
165
|
};
|
|
166
|
-
/**
|
|
167
|
-
* Group `rawLines` by blank-line separators, mirroring the historical search /
|
|
168
|
-
* ast-grep / ast-edit renderer behavior: if any blank line is present, splits on
|
|
169
|
-
* runs of blank lines; otherwise collapses non-empty lines into a single group.
|
|
170
|
-
*/
|
|
171
|
-
export declare function splitGroupsByBlankLine(rawLines: string[]): string[][];
|
|
172
166
|
/**
|
|
173
167
|
* Standard width+expand keyed render cache used by every search-style tool
|
|
174
168
|
* renderer. `compute` re-runs only when the cache key changes; the returned
|
|
175
169
|
* Component is the canonical `{ render, invalidate }` pair.
|
|
176
170
|
*/
|
|
177
|
-
export declare function createCachedComponent(getExpanded: () => boolean, compute: (width: number, expanded: boolean) => string[]
|
|
171
|
+
export declare function createCachedComponent(getExpanded: () => boolean, compute: (width: number, expanded: boolean) => string[], options?: {
|
|
172
|
+
paddingX?: number;
|
|
173
|
+
}): Component;
|
|
178
174
|
/**
|
|
179
175
|
* Append the indented bullet list of parse errors (capped at
|
|
180
176
|
* {@link PARSE_ERRORS_LIMIT}) to `lines`, with an overflow summary line if the
|
|
@@ -47,6 +47,10 @@ export interface SearchToolDetails {
|
|
|
47
47
|
/** Absolute base directory used during search. Used by the renderer to resolve
|
|
48
48
|
* display-relative paths to absolute paths for OSC 8 hyperlinks. */
|
|
49
49
|
searchPath?: string;
|
|
50
|
+
/** Session cwd at search time. The renderer resolves the display-relative
|
|
51
|
+
* (cwd-relative) header/match paths against this for OSC 8 hyperlinks;
|
|
52
|
+
* `searchPath` is the scope label target, not the display-path base. */
|
|
53
|
+
cwd?: string;
|
|
50
54
|
/** User-supplied paths whose base directory was missing on disk. The tool
|
|
51
55
|
* skipped these and continued with the surviving entries; surfaced as a
|
|
52
56
|
* non-fatal warning in the renderer and in the model-facing text. */
|
|
@@ -146,14 +146,15 @@ export declare const TODO_STRIKE_HOLD_FRAMES = 2;
|
|
|
146
146
|
export declare const TODO_STRIKE_REVEAL_FRAMES = 12;
|
|
147
147
|
export declare const TODO_STRIKE_TOTAL_FRAMES: number;
|
|
148
148
|
export declare const todoToolRenderer: {
|
|
149
|
-
renderCall(args: TodoRenderArgs,
|
|
149
|
+
renderCall(args: TodoRenderArgs, options: RenderResultOptions, uiTheme: Theme): Component;
|
|
150
150
|
renderResult(result: {
|
|
151
151
|
content: Array<{
|
|
152
152
|
type: string;
|
|
153
153
|
text?: string;
|
|
154
154
|
}>;
|
|
155
155
|
details?: TodoToolDetails;
|
|
156
|
-
|
|
156
|
+
isError?: boolean;
|
|
157
|
+
}, options: RenderResultOptions, uiTheme: Theme, args?: TodoRenderArgs): Component;
|
|
157
158
|
mergeCallAndResult: boolean;
|
|
158
159
|
};
|
|
159
160
|
export {};
|
|
@@ -17,6 +17,9 @@ export interface WriteToolDetails {
|
|
|
17
17
|
meta?: OutputMeta;
|
|
18
18
|
/** Set when the file was auto-chmod'd because content begins with a `#!` shebang. */
|
|
19
19
|
madeExecutable?: boolean;
|
|
20
|
+
/** Absolute filesystem path the write resolved to. Used by the renderer to wrap
|
|
21
|
+
* the (possibly cwd-relative) header path in an OSC 8 `file://` hyperlink. */
|
|
22
|
+
resolvedPath?: string;
|
|
20
23
|
}
|
|
21
24
|
type WriteParams = WriteToolInput;
|
|
22
25
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Bordered output container with optional header and sections.
|
|
3
3
|
*/
|
|
4
4
|
import type { Component } from "@oh-my-pi/pi-tui";
|
|
5
|
-
import type { Theme } from "../modes/theme/theme";
|
|
5
|
+
import type { Theme, ThemeColor } from "../modes/theme/theme";
|
|
6
6
|
import type { State } from "./types";
|
|
7
7
|
export interface OutputBlockOptions {
|
|
8
8
|
header?: string;
|
|
@@ -11,11 +11,16 @@ export interface OutputBlockOptions {
|
|
|
11
11
|
sections?: Array<{
|
|
12
12
|
label?: string;
|
|
13
13
|
lines: string[];
|
|
14
|
+
separator?: boolean;
|
|
14
15
|
}>;
|
|
15
16
|
width: number;
|
|
16
17
|
applyBg?: boolean;
|
|
18
|
+
contentPaddingLeft?: number;
|
|
17
19
|
/** Animate the border with a sweeping dark segment (pending/running state). */
|
|
18
20
|
animate?: boolean;
|
|
21
|
+
/** Override the state-derived border color. Used for muted "legacy" tool
|
|
22
|
+
* frames that should not visually compete with framed-output tools. */
|
|
23
|
+
borderColor?: ThemeColor;
|
|
19
24
|
}
|
|
20
25
|
declare const FRAMED_BLOCK_COMPONENT: unique symbol;
|
|
21
26
|
export type FramedBlockComponent = Component & {
|
|
@@ -24,9 +29,9 @@ export type FramedBlockComponent = Component & {
|
|
|
24
29
|
export declare function markFramedBlockComponent<T extends Component>(component: T): T & FramedBlockComponent;
|
|
25
30
|
export declare function isFramedBlockComponent(component: Component): boolean;
|
|
26
31
|
/**
|
|
27
|
-
* Monotonic frame counter for animated borders, quantized to the TUI's ~
|
|
28
|
-
* render cap so the cache key advances once per
|
|
29
|
-
* smooth segment sweep, coarse enough to coalesce multiple render passes
|
|
32
|
+
* Monotonic frame counter for animated borders, quantized to the TUI's ~30fps
|
|
33
|
+
* render cap so the cache key advances once per animation frame — fine enough
|
|
34
|
+
* for a smooth segment sweep, coarse enough to coalesce multiple render passes
|
|
30
35
|
* land inside the same frame.
|
|
31
36
|
*/
|
|
32
37
|
export declare function borderShimmerTick(): number;
|
|
@@ -54,4 +59,11 @@ export declare class CachedOutputBlock {
|
|
|
54
59
|
/** Invalidate the cache, forcing a rebuild on next render. */
|
|
55
60
|
invalidate(): void;
|
|
56
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Build a self-framing tool component backed by a cached output block. The
|
|
64
|
+
* `build` callback returns the block options for a given width; the cache
|
|
65
|
+
* dedupes re-renders. Pass `borderColor: "borderMuted"` for the dim "legacy"
|
|
66
|
+
* look that does not compete with the state-colored framed tools.
|
|
67
|
+
*/
|
|
68
|
+
export declare function framedBlock(theme: Theme, build: (width: number) => OutputBlockOptions): Component;
|
|
57
69
|
export {};
|
|
@@ -5,6 +5,9 @@ import type { Theme, ThemeColor } from "../modes/theme/theme";
|
|
|
5
5
|
import type { ToolUIStatus } from "../tools/render-utils";
|
|
6
6
|
export interface StatusLineOptions {
|
|
7
7
|
icon?: ToolUIStatus;
|
|
8
|
+
/** Pre-rendered glyph that replaces the status icon (e.g. a magnifier for
|
|
9
|
+
* search-family tools). Takes precedence over `icon`. */
|
|
10
|
+
iconOverride?: string;
|
|
8
11
|
spinnerFrame?: number;
|
|
9
12
|
title: string;
|
|
10
13
|
titleColor?: ThemeColor;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
2
|
+
export interface Osc5522Packet {
|
|
3
|
+
metadata: Map<string, string>;
|
|
4
|
+
payload: string;
|
|
5
|
+
}
|
|
6
|
+
export interface EnhancedPasteHandlers {
|
|
7
|
+
write(data: string): void;
|
|
8
|
+
pasteText(text: string): void;
|
|
9
|
+
pasteImage(image: ImageContent): void | Promise<void>;
|
|
10
|
+
showStatus(message: string): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function isOsc5522Packet(data: string): boolean;
|
|
13
|
+
export declare function parseOsc5522Packet(data: string): Osc5522Packet | undefined;
|
|
14
|
+
export declare class EnhancedPasteController {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(handlers: EnhancedPasteHandlers);
|
|
17
|
+
enable(): void;
|
|
18
|
+
disable(): void;
|
|
19
|
+
handleInput(data: string): boolean;
|
|
20
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Uses Moonshot Kimi Code search API to retrieve web results.
|
|
5
5
|
* Endpoint: POST https://api.kimi.com/coding/v1/search
|
|
6
6
|
*/
|
|
7
|
-
import type
|
|
7
|
+
import { type AuthStorage } from "@oh-my-pi/pi-ai";
|
|
8
8
|
import type { SearchResponse } from "../../../web/search/types";
|
|
9
9
|
import type { SearchParams } from "./base";
|
|
10
10
|
import { SearchProvider } from "./base";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.10.
|
|
4
|
+
"version": "15.10.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.22.1",
|
|
48
48
|
"@babel/parser": "^7.29.7",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/hashline": "15.10.
|
|
51
|
-
"@oh-my-pi/omp-stats": "15.10.
|
|
52
|
-
"@oh-my-pi/pi-agent-core": "15.10.
|
|
53
|
-
"@oh-my-pi/pi-ai": "15.10.
|
|
54
|
-
"@oh-my-pi/pi-mnemopi": "15.10.
|
|
55
|
-
"@oh-my-pi/pi-natives": "15.10.
|
|
56
|
-
"@oh-my-pi/pi-tui": "15.10.
|
|
57
|
-
"@oh-my-pi/pi-utils": "15.10.
|
|
50
|
+
"@oh-my-pi/hashline": "15.10.1",
|
|
51
|
+
"@oh-my-pi/omp-stats": "15.10.1",
|
|
52
|
+
"@oh-my-pi/pi-agent-core": "15.10.1",
|
|
53
|
+
"@oh-my-pi/pi-ai": "15.10.1",
|
|
54
|
+
"@oh-my-pi/pi-mnemopi": "15.10.1",
|
|
55
|
+
"@oh-my-pi/pi-natives": "15.10.1",
|
|
56
|
+
"@oh-my-pi/pi-tui": "15.10.1",
|
|
57
|
+
"@oh-my-pi/pi-utils": "15.10.1",
|
|
58
58
|
"@opentelemetry/api": "^1.9.1",
|
|
59
59
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
60
60
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { type AssistantMessage, completeSimple, Effort, type Model } from "@oh-my-pi/pi-ai";
|
|
17
17
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
18
|
+
|
|
18
19
|
import type { ModelRegistry } from "../config/model-registry";
|
|
19
20
|
import { resolveRoleSelection } from "../config/model-resolver";
|
|
20
21
|
import type { Settings } from "../config/settings";
|
|
@@ -82,7 +83,10 @@ async function classifyOnline(input: string, deps: ClassifyDifficultyDeps): Prom
|
|
|
82
83
|
messages: [{ role: "user", content: input, timestamp: Date.now() }],
|
|
83
84
|
},
|
|
84
85
|
{
|
|
85
|
-
apiKey,
|
|
86
|
+
apiKey: deps.registry.resolver(model.provider, {
|
|
87
|
+
sessionId: deps.sessionId,
|
|
88
|
+
baseUrl: model.baseUrl,
|
|
89
|
+
}),
|
|
86
90
|
maxTokens,
|
|
87
91
|
disableReasoning: true,
|
|
88
92
|
metadata,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Api,
|
|
3
|
+
ApiKeyResolver,
|
|
3
4
|
AssistantMessage,
|
|
4
5
|
AssistantMessageEvent,
|
|
5
6
|
AssistantMessageEventStream,
|
|
7
|
+
AuthCredentialSnapshotEntry,
|
|
6
8
|
Context,
|
|
7
9
|
Model,
|
|
8
10
|
OAuthAccess,
|
|
@@ -59,6 +61,12 @@ export interface DryBalanceAuthStorage {
|
|
|
59
61
|
options?: DryBalanceAuthOptions,
|
|
60
62
|
): Promise<OAuthAccess | undefined>;
|
|
61
63
|
getOAuthAccesses?(provider: string, options?: DryBalanceAuthOptions): Promise<OAuthAccessResolution[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Force-refresh a single credential by id (step (b) of the auth-retry
|
|
66
|
+
* policy). The bench re-mints the failing account's token in place on a
|
|
67
|
+
* 401 rather than rotating accounts — it is measuring each account.
|
|
68
|
+
*/
|
|
69
|
+
forceRefreshCredentialById?(id: number, signal?: AbortSignal): Promise<AuthCredentialSnapshotEntry>;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
export interface DryBalanceModelRegistry {
|
|
@@ -152,6 +160,8 @@ export interface DryBalanceDependencies {
|
|
|
152
160
|
now?: () => number;
|
|
153
161
|
stdoutIsTTY?: boolean;
|
|
154
162
|
stderrIsTTY?: boolean;
|
|
163
|
+
stdoutColumns?: number;
|
|
164
|
+
stderrColumns?: number;
|
|
155
165
|
}
|
|
156
166
|
|
|
157
167
|
type DryBalanceAttemptResult =
|
|
@@ -181,6 +191,7 @@ type DryBalanceBenchTarget =
|
|
|
181
191
|
ok: true;
|
|
182
192
|
account: string;
|
|
183
193
|
accessToken: string;
|
|
194
|
+
credentialId?: number;
|
|
184
195
|
}
|
|
185
196
|
| {
|
|
186
197
|
ok: false;
|
|
@@ -310,10 +321,11 @@ function renderBenchStatusLine(
|
|
|
310
321
|
}
|
|
311
322
|
}
|
|
312
323
|
|
|
313
|
-
function createBenchProgressSink(
|
|
324
|
+
export function createBenchProgressSink(
|
|
314
325
|
total: number,
|
|
315
326
|
write: (text: string) => void,
|
|
316
327
|
interactive: boolean,
|
|
328
|
+
columns: number,
|
|
317
329
|
): DryBalanceBenchProgressSink {
|
|
318
330
|
const statuses: DryBalanceBenchProgressStatus[] = Array.from({ length: total }, () => ({ state: "waiting" }));
|
|
319
331
|
if (!interactive) {
|
|
@@ -333,13 +345,21 @@ function createBenchProgressSink(
|
|
|
333
345
|
let frame = 0;
|
|
334
346
|
let lineCount = 0;
|
|
335
347
|
let timer: NodeJS.Timeout | undefined;
|
|
348
|
+
const width = Number.isFinite(columns) && columns > 0 ? Math.trunc(columns) : 80;
|
|
336
349
|
const render = (): void => {
|
|
337
350
|
const lines = [
|
|
338
351
|
chalk.bold("bench requests"),
|
|
339
352
|
...statuses.map((status, index) => renderBenchStatusLine(status, index, total, frame)),
|
|
340
353
|
];
|
|
341
|
-
|
|
342
|
-
|
|
354
|
+
// Anchor every redraw at column 0 and terminate each row with CRLF: a
|
|
355
|
+
// bare `\n` only returns to column 0 when the tty performs ONLCR
|
|
356
|
+
// translation, which is off whenever the terminal is in raw mode — there
|
|
357
|
+
// the old column-preserving cursor-up staircased each frame into
|
|
358
|
+
// scrollback. Cap each line to the terminal width so a wrapped row never
|
|
359
|
+
// desyncs the `\x1b[<n>A` cursor-up from the logical line count.
|
|
360
|
+
const move = lineCount > 0 ? `\x1b[${lineCount}A` : "";
|
|
361
|
+
const body = lines.map(line => `\x1b[2K${truncateToWidth(line, width)}`).join("\r\n");
|
|
362
|
+
write(`${move}\r${body}\r\n`);
|
|
343
363
|
lineCount = lines.length;
|
|
344
364
|
};
|
|
345
365
|
render();
|
|
@@ -370,13 +390,23 @@ function createBenchProgressSink(
|
|
|
370
390
|
async function runBenchRequest(
|
|
371
391
|
model: Model<Api>,
|
|
372
392
|
sessionId: string,
|
|
373
|
-
|
|
374
|
-
|
|
393
|
+
target: Extract<DryBalanceBenchTarget, { ok: true }>,
|
|
394
|
+
authStorage: DryBalanceAuthStorage,
|
|
375
395
|
streamFn: DryBalanceStreamSimple,
|
|
376
396
|
now: () => number,
|
|
377
397
|
): Promise<DryBalanceBenchResult> {
|
|
398
|
+
const { account, accessToken, credentialId } = target;
|
|
378
399
|
const startedAt = now();
|
|
379
400
|
let firstTokenAt: number | undefined;
|
|
401
|
+
// Re-mint the cached token on a 401: a peer/broker may have rotated it out
|
|
402
|
+
// from under our snapshot (Anthropic rotates refresh tokens on every use).
|
|
403
|
+
// The bench measures one account, so the switch step intentionally declines.
|
|
404
|
+
const apiKey: ApiKeyResolver = async ({ lastChance, error }) => {
|
|
405
|
+
if (error === undefined) return accessToken;
|
|
406
|
+
if (lastChance || credentialId === undefined || !authStorage.forceRefreshCredentialById) return undefined;
|
|
407
|
+
const refreshed = await authStorage.forceRefreshCredentialById(credentialId);
|
|
408
|
+
return refreshed.credential.type === "oauth" ? refreshed.credential.access : undefined;
|
|
409
|
+
};
|
|
380
410
|
try {
|
|
381
411
|
const context: Context = {
|
|
382
412
|
messages: [
|
|
@@ -389,7 +419,7 @@ async function runBenchRequest(
|
|
|
389
419
|
],
|
|
390
420
|
};
|
|
391
421
|
const stream = streamFn(model, context, {
|
|
392
|
-
apiKey
|
|
422
|
+
apiKey,
|
|
393
423
|
sessionId,
|
|
394
424
|
maxTokens: resolveBenchMaxTokens(model),
|
|
395
425
|
temperature: 0.2,
|
|
@@ -454,7 +484,7 @@ async function resolveBenchTargets(
|
|
|
454
484
|
seen.add(key);
|
|
455
485
|
const account = extractAccount(entry);
|
|
456
486
|
if (entry.ok) {
|
|
457
|
-
targets.push({ ok: true, account, accessToken: entry.accessToken });
|
|
487
|
+
targets.push({ ok: true, account, accessToken: entry.accessToken, credentialId: entry.credentialId });
|
|
458
488
|
} else {
|
|
459
489
|
targets.push({ ok: false, account, error: entry.error });
|
|
460
490
|
}
|
|
@@ -465,6 +495,7 @@ async function resolveBenchTargets(
|
|
|
465
495
|
async function runBenchTargets(
|
|
466
496
|
model: Model<Api>,
|
|
467
497
|
targets: DryBalanceBenchTarget[],
|
|
498
|
+
authStorage: DryBalanceAuthStorage,
|
|
468
499
|
randomSessionId: () => string,
|
|
469
500
|
progress: DryBalanceBenchProgressSink | undefined,
|
|
470
501
|
streamFn: DryBalanceStreamSimple,
|
|
@@ -482,14 +513,7 @@ async function runBenchTargets(
|
|
|
482
513
|
return result;
|
|
483
514
|
}
|
|
484
515
|
progress?.markRunning(index, target.account);
|
|
485
|
-
const result = await runBenchRequest(
|
|
486
|
-
model,
|
|
487
|
-
randomSessionId(),
|
|
488
|
-
target.account,
|
|
489
|
-
target.accessToken,
|
|
490
|
-
streamFn,
|
|
491
|
-
now,
|
|
492
|
-
);
|
|
516
|
+
const result = await runBenchRequest(model, randomSessionId(), target, authStorage, streamFn, now);
|
|
493
517
|
progress?.complete(index, result);
|
|
494
518
|
return result;
|
|
495
519
|
}),
|
|
@@ -792,8 +816,19 @@ export async function runDryBalanceCommand(
|
|
|
792
816
|
const progressInteractive = command.flags.json
|
|
793
817
|
? (deps.stderrIsTTY ?? process.stderr.isTTY === true)
|
|
794
818
|
: (deps.stdoutIsTTY ?? process.stdout.isTTY === true);
|
|
795
|
-
|
|
796
|
-
|
|
819
|
+
const progressColumns = command.flags.json
|
|
820
|
+
? (deps.stderrColumns ?? process.stderr.columns ?? 80)
|
|
821
|
+
: (deps.stdoutColumns ?? process.stdout.columns ?? 80);
|
|
822
|
+
progress = createBenchProgressSink(targets.length, progressWrite, progressInteractive, progressColumns);
|
|
823
|
+
benchResults = await runBenchTargets(
|
|
824
|
+
model,
|
|
825
|
+
targets,
|
|
826
|
+
runtime.modelRegistry.authStorage,
|
|
827
|
+
randomSessionId,
|
|
828
|
+
progress,
|
|
829
|
+
streamFn,
|
|
830
|
+
now,
|
|
831
|
+
);
|
|
797
832
|
results = targets.map(target =>
|
|
798
833
|
target.ok ? { ok: true, account: target.account } : { ok: false, reason: target.error },
|
|
799
834
|
);
|
package/src/cli/gallery-cli.ts
CHANGED
|
@@ -196,7 +196,10 @@ export async function runGalleryCommand(args: GalleryCommandArgs): Promise<void>
|
|
|
196
196
|
const expanded = args.expanded ?? false;
|
|
197
197
|
const states = args.states && args.states.length > 0 ? args.states : [...GALLERY_STATES];
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
// Renderer-registry tools plus fixture-only tools (no dedicated renderer,
|
|
200
|
+
// e.g. `report_tool_issue` / custom extension tools) so the gallery covers
|
|
201
|
+
// the generic fallback + custom-tool branches too.
|
|
202
|
+
const allNames = Array.from(new Set([...Object.keys(toolRenderers), ...Object.keys(galleryFixtures)])).sort();
|
|
200
203
|
const names = args.tool ? allNames.filter(name => name === args.tool) : allNames;
|
|
201
204
|
if (args.tool && names.length === 0) {
|
|
202
205
|
process.stdout.write(`Unknown tool '${args.tool}'. Known tools: ${allNames.join(", ")}\n`);
|
|
@@ -218,4 +218,33 @@ export const miscFixtures: Record<string, GalleryFixture> = {
|
|
|
218
218
|
},
|
|
219
219
|
},
|
|
220
220
|
},
|
|
221
|
+
|
|
222
|
+
// Built-in tool with no dedicated renderer — exercises the generic fallback
|
|
223
|
+
// (`#formatToolExecution`) path so its padded, state-tinted block is QA'd.
|
|
224
|
+
report_tool_issue: {
|
|
225
|
+
label: "Report Tool Issue",
|
|
226
|
+
streamingArgs: { tool: "lsp" },
|
|
227
|
+
args: {
|
|
228
|
+
tool: "lsp",
|
|
229
|
+
report: "Rename returned no edit for an exported symbol that has 12 references",
|
|
230
|
+
},
|
|
231
|
+
result: { content: [{ type: "text", text: "Noted, thanks!" }] },
|
|
232
|
+
errorResult: {
|
|
233
|
+
content: [{ type: "text", text: "Could not record the report: issue tracker unreachable" }],
|
|
234
|
+
isError: true,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
|
|
238
|
+
// Stand-in for a custom/extension tool that ships no renderer — same generic
|
|
239
|
+
// fallback path most MCP/extension tools take.
|
|
240
|
+
custom: {
|
|
241
|
+
label: "Custom Tool",
|
|
242
|
+
streamingArgs: { query: "weather" },
|
|
243
|
+
args: { query: "weather in Tokyo", units: "metric" },
|
|
244
|
+
result: { content: [{ type: "text", text: "Tokyo: 22°C, partly cloudy, humidity 64%." }] },
|
|
245
|
+
errorResult: {
|
|
246
|
+
content: [{ type: "text", text: "Upstream provider returned 503 Service Unavailable" }],
|
|
247
|
+
isError: true,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
221
250
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { Api, ApiKey, Model } from "@oh-my-pi/pi-ai";
|
|
3
3
|
import { completeSimple } from "@oh-my-pi/pi-ai";
|
|
4
4
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
5
5
|
import analysisSystemPrompt from "../../commit/prompts/analysis-system.md" with { type: "text" };
|
|
@@ -14,7 +14,7 @@ const ConventionalAnalysisTool = createConventionalAnalysisTool(
|
|
|
14
14
|
|
|
15
15
|
export interface ConventionalAnalysisInput {
|
|
16
16
|
model: Model<Api>;
|
|
17
|
-
apiKey:
|
|
17
|
+
apiKey: ApiKey;
|
|
18
18
|
thinkingLevel?: ThinkingLevel;
|
|
19
19
|
contextFiles?: Array<{ path: string; content: string }>;
|
|
20
20
|
userContext?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { Api, AssistantMessage, Model } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { Api, ApiKey, 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
5
|
import * as z from "zod/v4";
|
|
@@ -19,7 +19,7 @@ const SummaryTool = {
|
|
|
19
19
|
|
|
20
20
|
export interface SummaryInput {
|
|
21
21
|
model: Model<Api>;
|
|
22
|
-
apiKey:
|
|
22
|
+
apiKey: ApiKey;
|
|
23
23
|
thinkingLevel?: ThinkingLevel;
|
|
24
24
|
commitType: string;
|
|
25
25
|
scope: string | null;
|