@oh-my-pi/pi-coding-agent 17.2.11 → 17.2.12
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 +13 -0
- package/dist/{CHANGELOG-d9xenpn9.md → CHANGELOG-k9ghy5sn.md} +13 -0
- package/dist/cli.js +10795 -10791
- package/dist/types/advisor/runtime.d.ts +1 -1
- package/dist/types/config/custom-models.d.ts +31 -0
- package/dist/types/config/model-config-values.d.ts +19 -0
- package/dist/types/config/model-patch.d.ts +93 -0
- package/dist/types/config/model-provider-discovery.d.ts +51 -0
- package/dist/types/config/model-registry.d.ts +5 -52
- package/dist/types/config/settings.d.ts +5 -3
- package/dist/types/debug/raw-sse-buffer.d.ts +9 -0
- package/dist/types/discovery/agent-plugin-format.d.ts +6 -13
- package/dist/types/discovery/contained-path.d.ts +2 -3
- package/dist/types/eval/executor-base.d.ts +8 -2
- package/dist/types/eval/kernel-session-registry.d.ts +60 -0
- package/dist/types/export/share.d.ts +1 -1
- package/dist/types/lsp/diagnostics.d.ts +96 -0
- package/dist/types/lsp/index.d.ts +7 -128
- package/dist/types/lsp/servers.d.ts +72 -0
- package/dist/types/lsp/tool.d.ts +42 -0
- package/dist/types/lsp/workspace-diagnostics.d.ts +12 -0
- package/dist/types/lsp/writethrough.d.ts +33 -0
- package/dist/types/mcp/transports/header-policy.d.ts +2 -1
- package/dist/types/modes/components/agent-hub-projection.d.ts +2 -7
- package/dist/types/modes/components/agent-hub-renderer.d.ts +0 -7
- package/dist/types/modes/theme/color.d.ts +19 -0
- package/dist/types/modes/theme/loader.d.ts +19 -0
- package/dist/types/modes/theme/schema.d.ts +175 -0
- package/dist/types/modes/theme/symbols.d.ts +28 -0
- package/dist/types/modes/theme/theme-class.d.ts +244 -0
- package/dist/types/modes/theme/theme.d.ts +9 -280
- package/dist/types/modes/theme/tui-adapters.d.ts +13 -0
- package/dist/types/registry/agent-registry.d.ts +1 -3
- package/dist/types/secrets/index.d.ts +3 -1
- package/dist/types/secrets/message-transform.d.ts +40 -0
- package/dist/types/secrets/obfuscator.d.ts +0 -108
- package/dist/types/secrets/placeholder-scan.d.ts +95 -0
- package/dist/types/secrets/placeholder.d.ts +94 -0
- package/dist/types/secrets/replacement.d.ts +82 -0
- package/dist/types/session/agent-session-types.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +1 -1
- package/dist/types/session/session-handoff.d.ts +3 -3
- package/dist/types/session/session-manager.d.ts +32 -0
- package/dist/types/session/session-provider-boundary.d.ts +1 -1
- package/dist/types/session/turn-recovery.d.ts +2 -2
- package/dist/types/slash-commands/builtin-collaboration.d.ts +2 -0
- package/dist/types/slash-commands/builtin-completions.d.ts +36 -0
- package/dist/types/slash-commands/builtin-control.d.ts +2 -0
- package/dist/types/slash-commands/builtin-lifecycle.d.ts +3 -0
- package/dist/types/slash-commands/builtin-marketplace.d.ts +11 -0
- package/dist/types/slash-commands/builtin-modes.d.ts +5 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
- package/dist/types/slash-commands/builtin-session.d.ts +2 -0
- package/dist/types/tools/gh-common.d.ts +69 -0
- package/dist/types/tools/gh-pr-checkout.d.ts +84 -0
- package/dist/types/tools/gh-pr-diff.d.ts +102 -0
- package/dist/types/tools/gh-run-watch.d.ts +78 -0
- package/dist/types/tools/gh-search.d.ts +61 -0
- package/dist/types/tools/gh-types.d.ts +340 -0
- package/dist/types/tools/gh-view.d.ts +88 -0
- package/dist/types/tools/gh.d.ts +4 -201
- package/dist/types/tools/read-archive.d.ts +16 -0
- package/dist/types/tools/read-format.d.ts +104 -0
- package/dist/types/tools/read-path-resolution.d.ts +19 -0
- package/dist/types/tools/read-pdf-images.d.ts +12 -0
- package/dist/types/tools/read-renderer.d.ts +24 -0
- package/dist/types/tools/read-selector.d.ts +27 -0
- package/dist/types/tools/read-sqlite.d.ts +16 -0
- package/dist/types/tools/read-summary.d.ts +19 -0
- package/dist/types/tools/read.d.ts +1 -23
- package/dist/types/tools/shell-tokenize.d.ts +2 -1
- package/dist/types/utils/changelog.d.ts +0 -5
- package/package.json +13 -13
- package/src/advisor/runtime.ts +12 -7
- package/src/config/custom-models.ts +188 -0
- package/src/config/model-config-values.ts +128 -0
- package/src/config/model-patch.ts +252 -0
- package/src/config/model-provider-discovery.ts +132 -0
- package/src/config/model-registry.ts +64 -704
- package/src/config/settings.ts +7 -3
- package/src/debug/raw-sse-buffer.ts +20 -0
- package/src/discovery/agent-plugin-format.ts +7 -7
- package/src/discovery/contained-path.ts +2 -5
- package/src/edit/hashline/diff.ts +5 -1
- package/src/eval/executor-base.ts +39 -6
- package/src/eval/jl/executor.ts +82 -371
- package/src/eval/kernel-session-registry.ts +398 -0
- package/src/eval/py/executor.ts +53 -261
- package/src/eval/rb/executor.ts +36 -279
- package/src/export/share.ts +2 -1
- package/src/lsp/diagnostics.ts +516 -0
- package/src/lsp/index.ts +20 -2819
- package/src/lsp/servers.ts +296 -0
- package/src/lsp/tool.ts +1352 -0
- package/src/lsp/workspace-diagnostics.ts +170 -0
- package/src/lsp/writethrough.ts +561 -0
- package/src/mcp/transports/header-policy.ts +1 -1
- package/src/modes/components/agent-hub-projection.ts +2 -2
- package/src/modes/components/agent-hub-renderer.ts +3 -7
- package/src/modes/controllers/command-controller.ts +4 -1
- package/src/modes/theme/color.ts +133 -0
- package/src/modes/theme/loader.ts +178 -0
- package/src/modes/theme/schema.ts +263 -0
- package/src/modes/theme/symbols.ts +1000 -0
- package/src/modes/theme/theme-class.ts +611 -0
- package/src/modes/theme/theme.ts +27 -2453
- package/src/modes/theme/tui-adapters.ts +279 -0
- package/src/registry/agent-registry.ts +2 -2
- package/src/secrets/index.ts +6 -12
- package/src/secrets/message-transform.ts +287 -0
- package/src/secrets/obfuscator.ts +39 -1303
- package/src/secrets/placeholder-scan.ts +506 -0
- package/src/secrets/placeholder.ts +309 -0
- package/src/secrets/replacement.ts +216 -0
- package/src/session/agent-session-types.ts +6 -0
- package/src/session/agent-session.ts +113 -7
- package/src/session/indexed-session-storage.ts +7 -2
- package/src/session/session-advisors.ts +32 -34
- package/src/session/session-handoff.ts +39 -20
- package/src/session/session-manager.ts +67 -3
- package/src/session/session-provider-boundary.ts +3 -6
- package/src/session/turn-recovery.ts +21 -12
- package/src/slash-commands/builtin-collaboration.ts +504 -0
- package/src/slash-commands/builtin-completions.ts +291 -0
- package/src/slash-commands/builtin-control.ts +78 -0
- package/src/slash-commands/builtin-lifecycle.ts +506 -0
- package/src/slash-commands/builtin-marketplace.ts +567 -0
- package/src/slash-commands/builtin-modes.ts +518 -0
- package/src/slash-commands/builtin-registry.ts +21 -3000
- package/src/slash-commands/builtin-session.ts +592 -0
- package/src/task/executor.ts +17 -14
- package/src/tools/gh-common.ts +288 -0
- package/src/tools/gh-pr-checkout.ts +679 -0
- package/src/tools/gh-pr-diff.ts +473 -0
- package/src/tools/gh-run-watch.ts +1015 -0
- package/src/tools/gh-search.ts +500 -0
- package/src/tools/gh-types.ts +379 -0
- package/src/tools/gh-view.ts +612 -0
- package/src/tools/gh.ts +109 -3821
- package/src/tools/read-archive.ts +209 -0
- package/src/tools/read-format.ts +593 -0
- package/src/tools/read-path-resolution.ts +36 -0
- package/src/tools/read-pdf-images.ts +250 -0
- package/src/tools/read-renderer.ts +289 -0
- package/src/tools/read-selector.ts +84 -0
- package/src/tools/read-sqlite.ts +215 -0
- package/src/tools/read-summary.ts +199 -0
- package/src/tools/read.ts +77 -1820
- package/src/tools/shell-tokenize.ts +1 -1
- package/src/utils/changelog.ts +1 -1
- package/src/utils/title-generator.ts +3 -1
- package/src/web/search/providers/zai.ts +12 -3
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import type { ToolSession } from "../sdk.js";
|
|
3
|
+
import { type LineEntry } from "../utils/block-context.js";
|
|
4
|
+
import { type LineRange } from "./path-utils.js";
|
|
5
|
+
import type { ReadToolDetails } from "./read.js";
|
|
6
|
+
export interface HashlineHeaderContext {
|
|
7
|
+
header: string;
|
|
8
|
+
tag: string;
|
|
9
|
+
fullText?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function formatReadHashlineHeader(displayPath: string, tag: string): string;
|
|
12
|
+
export declare function readHashlineHeaderContext(session: ToolSession, absolutePath: string, cwd: string): Promise<HashlineHeaderContext>;
|
|
13
|
+
export declare function hashlineHeaderContext(displayPath: string, tag: string): HashlineHeaderContext;
|
|
14
|
+
export declare function prependHashlineHeader(text: string, context: HashlineHeaderContext | undefined): string;
|
|
15
|
+
export declare function formatTextWithMode(text: string, startNum: number, shouldAddHashLines: boolean, shouldAddLineNumbers: boolean): string;
|
|
16
|
+
export declare const BRACKET_CONTEXT_ELLIPSIS = "\u2026";
|
|
17
|
+
export declare function formatLineEntriesWithMode(entries: readonly LineEntry[], shouldAddHashLines: boolean, shouldAddLineNumbers: boolean): string;
|
|
18
|
+
/**
|
|
19
|
+
* Decide whether the kept lines surrounding an elided range collapse to a
|
|
20
|
+
* single brace-pair line in the rendered summary. Returns true when the head
|
|
21
|
+
* line ends with `{` / `(` / `[` and the tail line is the matching closer
|
|
22
|
+
* (optionally followed by terminating punctuation like `;`, `,`, or further
|
|
23
|
+
* closers — e.g. `};`, `})`, `]);`).
|
|
24
|
+
*/
|
|
25
|
+
export declare function canMergeBracePair(headLine: string, tailLine: string): boolean;
|
|
26
|
+
export declare function formatSingleLine(line: number, text: string, shouldAddHashLines: boolean, shouldAddLineNumbers: boolean): string;
|
|
27
|
+
export declare function formatMergedBraceLine(startLine: number, endLine: number, headText: string, tailText: string, shouldAddHashLines: boolean, shouldAddLineNumbers: boolean): {
|
|
28
|
+
model: string;
|
|
29
|
+
display: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function countTextLines(text: string): number;
|
|
32
|
+
export declare function contiguousLineNumbers(startLine: number, count: number): number[];
|
|
33
|
+
export declare function lineNumbersFromSpans(spans: readonly {
|
|
34
|
+
startLine: number;
|
|
35
|
+
endLine: number;
|
|
36
|
+
}[]): number[];
|
|
37
|
+
/** Inclusive line range describing one elided span in a structural summary. */
|
|
38
|
+
export interface ElidedRange {
|
|
39
|
+
start: number;
|
|
40
|
+
end: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Footer appended to summarized reads telling the model how to recover the
|
|
44
|
+
* elided body. Without this hint, agents either ignore the `…`/`{ … }`
|
|
45
|
+
* markers or burn a turn guessing the right selector (see issue #1046). The
|
|
46
|
+
* footer demonstrates the multi-range selector syntax with concrete sample
|
|
47
|
+
* ranges drawn from the actual elision so the model re-reads only what it
|
|
48
|
+
* needs instead of falling back to `:raw` or whole-file reads.
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatSummaryElisionFooter(readPath: string, elidedRanges: ReadonlyArray<ElidedRange>, elidedLines: number): string;
|
|
51
|
+
export declare const READ_CHUNK_SIZE: number;
|
|
52
|
+
/**
|
|
53
|
+
* Context lines added around an explicit range read. Anchor-stale failures
|
|
54
|
+
* cluster on edits whose anchors land just outside the most recent read
|
|
55
|
+
* window, but the data (`scripts/session-stats/analyze_selector_reads.py`)
|
|
56
|
+
* shows most follow-up reads are disjoint hops, not adjacent extensions —
|
|
57
|
+
* so symmetric padding rarely pays for itself.
|
|
58
|
+
*
|
|
59
|
+
* Leading=1 catches accidental single-line reads where the anchor is the
|
|
60
|
+
* line immediately above the requested start. Trailing=3 buffers the
|
|
61
|
+
* common case where the agent asks for a narrow range and then needs the
|
|
62
|
+
* next few lines to disambiguate an anchor.
|
|
63
|
+
*/
|
|
64
|
+
export declare const RANGE_LEADING_CONTEXT_LINES = 1;
|
|
65
|
+
export declare const RANGE_TRAILING_CONTEXT_LINES = 3;
|
|
66
|
+
export declare function buildInMemoryTextResult(session: ToolSession, text: string, offset: number | undefined, limit: number | undefined, options: {
|
|
67
|
+
details?: ReadToolDetails;
|
|
68
|
+
sourcePath?: string;
|
|
69
|
+
sourceUrl?: string;
|
|
70
|
+
sourceInternal?: string;
|
|
71
|
+
entityLabel: string;
|
|
72
|
+
ignoreResultLimits?: boolean;
|
|
73
|
+
raw?: boolean;
|
|
74
|
+
immutable?: boolean;
|
|
75
|
+
}): AgentToolResult<ReadToolDetails>;
|
|
76
|
+
/**
|
|
77
|
+
* Render a multi-range read against in-memory text. Each range emits a
|
|
78
|
+
* formatted block with its own anchors / line numbers, blocks are joined
|
|
79
|
+
* with an elision separator, and ranges past EOF surface as `[…]` notices
|
|
80
|
+
* so the model can correct the next call. No leading/trailing context is
|
|
81
|
+
* added — multi-range callers always specify exact bounds.
|
|
82
|
+
*/
|
|
83
|
+
export declare function buildInMemoryMultiRangeResult(session: ToolSession, text: string, ranges: readonly LineRange[], options: {
|
|
84
|
+
details?: ReadToolDetails;
|
|
85
|
+
sourcePath?: string;
|
|
86
|
+
sourceUrl?: string;
|
|
87
|
+
sourceInternal?: string;
|
|
88
|
+
entityLabel: string;
|
|
89
|
+
raw?: boolean;
|
|
90
|
+
immutable?: boolean;
|
|
91
|
+
}): AgentToolResult<ReadToolDetails>;
|
|
92
|
+
export declare function decodeUtf8Text(bytes: Uint8Array): string | null;
|
|
93
|
+
export declare function prependSuffixResolutionNotice(text: string, suffixResolution?: {
|
|
94
|
+
from: string;
|
|
95
|
+
to: string;
|
|
96
|
+
}): string;
|
|
97
|
+
/**
|
|
98
|
+
* Tag Markdown reads for the TUI's formatted preview, gated on the opt-in
|
|
99
|
+
* `read.renderMarkdown` setting. Off by default; when disabled, no local
|
|
100
|
+
* read is tagged `text/markdown`, so the renderer output is identical to
|
|
101
|
+
* the pre-setting behavior. Internal-URL reads keep their protocol-supplied
|
|
102
|
+
* `contentType` and render as Markdown regardless of the setting.
|
|
103
|
+
*/
|
|
104
|
+
export declare function markMarkdownContentType(session: ToolSession, details: ReadToolDetails, filePath: string): ReadToolDetails;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ToolSession } from "../sdk.js";
|
|
2
|
+
export declare function isRemoteMountPath(absolutePath: string): boolean;
|
|
3
|
+
export declare function isNotFoundError(error: unknown): boolean;
|
|
4
|
+
/** Per-execute memo of suffix-glob lookups; `null` records a confirmed miss. */
|
|
5
|
+
export type SuffixMatchCache = Map<string, {
|
|
6
|
+
absolutePath: string;
|
|
7
|
+
displayPath: string;
|
|
8
|
+
} | null>;
|
|
9
|
+
/**
|
|
10
|
+
* Memoized {@link findUniqueWorkspaceSuffix} for a single read call. A missing
|
|
11
|
+
* path with archive/sqlite extensions probes the workspace once per stage
|
|
12
|
+
* (archive candidates, sqlite candidates, plain path) — each glob carries a
|
|
13
|
+
* 5s timeout, so repeated lookups of the same string stack into a long
|
|
14
|
+
* stall before erroring. The cache collapses repeats within one execute().
|
|
15
|
+
*/
|
|
16
|
+
export declare function findSuffixMatchCached(session: ToolSession, cache: SuffixMatchCache, rawPath: string, signal?: AbortSignal): Promise<{
|
|
17
|
+
absolutePath: string;
|
|
18
|
+
displayPath: string;
|
|
19
|
+
} | null>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import type { ToolSession } from "../sdk.js";
|
|
3
|
+
import type { ReadToolDetails } from "./read.js";
|
|
4
|
+
export declare function rewritePdfImagePlaceholders(markdown: string, pdfPath: string): string;
|
|
5
|
+
export declare function splitPdfImageMemberReadPath(readPath: string): {
|
|
6
|
+
pdfPath: string;
|
|
7
|
+
member: string;
|
|
8
|
+
} | null;
|
|
9
|
+
export declare function readPdfImageMember(session: ToolSession, autoResizeImages: boolean, absolutePdfPath: string, pdfDisplayPath: string, member: string, suffixResolution: {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
} | undefined, signal?: AbortSignal): Promise<AgentToolResult<ReadToolDetails>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Component } from "@oh-my-pi/pi-tui";
|
|
2
|
+
import type { RenderResultOptions } from "../extensibility/custom-tools/types.js";
|
|
3
|
+
import { type Theme } from "../modes/theme/theme.js";
|
|
4
|
+
import type { ReadToolDetails } from "./read.js";
|
|
5
|
+
interface ReadRenderArgs {
|
|
6
|
+
path?: unknown;
|
|
7
|
+
file_path?: unknown;
|
|
8
|
+
offset?: number;
|
|
9
|
+
limit?: number;
|
|
10
|
+
raw?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const readToolRenderer: {
|
|
13
|
+
renderCall(args: ReadRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
|
|
14
|
+
renderResult(result: {
|
|
15
|
+
content: Array<{
|
|
16
|
+
type: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
}>;
|
|
19
|
+
details?: ReadToolDetails;
|
|
20
|
+
isError?: boolean;
|
|
21
|
+
}, options: RenderResultOptions, uiTheme: Theme, args?: ReadRenderArgs): Component;
|
|
22
|
+
mergeCallAndResult: boolean;
|
|
23
|
+
};
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { LineRange } from "./path-utils.js";
|
|
2
|
+
/** Parsed representation of a path-embedded selector. */
|
|
3
|
+
export type ParsedSelector = {
|
|
4
|
+
kind: "none";
|
|
5
|
+
} | {
|
|
6
|
+
kind: "raw";
|
|
7
|
+
} | {
|
|
8
|
+
kind: "conflicts";
|
|
9
|
+
} | {
|
|
10
|
+
kind: "lines";
|
|
11
|
+
ranges: [LineRange, ...LineRange[]];
|
|
12
|
+
raw?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** Returns true when the selector requested verbatim/raw output (alone or combined with a range). */
|
|
15
|
+
export declare function isRawSelector(parsed: ParsedSelector): boolean;
|
|
16
|
+
/** Returns true when the selector requested multiple line ranges. */
|
|
17
|
+
export declare function isMultiRange(parsed: ParsedSelector): boolean;
|
|
18
|
+
export declare function parseSel(sel: string | undefined): ParsedSelector;
|
|
19
|
+
/**
|
|
20
|
+
* Convert a single-range selector to the offset/limit pair used by internal pagination.
|
|
21
|
+
* Returns the FIRST range only — multi-range callers MUST branch on `isMultiRange` before
|
|
22
|
+
* calling this helper.
|
|
23
|
+
*/
|
|
24
|
+
export declare function selToOffsetLimit(parsed: ParsedSelector): {
|
|
25
|
+
offset?: number;
|
|
26
|
+
limit?: number;
|
|
27
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
2
|
+
import type { ToolSession } from "../sdk.js";
|
|
3
|
+
import type { ReadToolDetails } from "./read.js";
|
|
4
|
+
import { type SuffixMatchCache } from "./read-path-resolution.js";
|
|
5
|
+
interface ResolvedSqliteReadPath {
|
|
6
|
+
absolutePath: string;
|
|
7
|
+
sqliteSubPath: string;
|
|
8
|
+
queryString: string;
|
|
9
|
+
suffixResolution?: {
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare function resolveSqliteReadPath(session: ToolSession, readPath: string, suffixCache: SuffixMatchCache, signal?: AbortSignal): Promise<ResolvedSqliteReadPath | null>;
|
|
15
|
+
export declare function readSqlite(resolvedSqlitePath: ResolvedSqliteReadPath, signal?: AbortSignal): Promise<AgentToolResult<ReadToolDetails>>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type SummaryResult } from "@oh-my-pi/pi-natives";
|
|
2
|
+
import type { ToolSession } from "../sdk.js";
|
|
3
|
+
import { type ElidedRange } from "./read-format.js";
|
|
4
|
+
/**
|
|
5
|
+
* Prose files (Markdown flavors and plain text) skip code-block summarization
|
|
6
|
+
* unless `read.summarize.prose` opts them in.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isProseSummaryPath(filePath: string): boolean;
|
|
9
|
+
export declare function routeReadThroughBridge(session: ToolSession, absolutePath: string, options?: {
|
|
10
|
+
line?: number;
|
|
11
|
+
limit?: number;
|
|
12
|
+
}): Promise<string> | undefined;
|
|
13
|
+
export declare function trySummarize(session: ToolSession, absolutePath: string, fileSize: number, signal?: AbortSignal): Promise<SummaryResult | null>;
|
|
14
|
+
export declare function renderSummary(session: ToolSession, summary: SummaryResult): {
|
|
15
|
+
text: string;
|
|
16
|
+
displayText: string;
|
|
17
|
+
elidedRanges: ElidedRange[];
|
|
18
|
+
elidedLines: number;
|
|
19
|
+
};
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolTier } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { Component } from "@oh-my-pi/pi-tui";
|
|
3
|
-
import type { RenderResultOptions } from "../extensibility/custom-tools/types.js";
|
|
4
|
-
import { type Theme } from "../modes/theme/theme.js";
|
|
5
2
|
import type { ToolSession } from "../sdk.js";
|
|
6
3
|
import { type TruncationResult } from "../session/streaming-output.js";
|
|
7
4
|
import { type OutputMeta } from "./output-meta.js";
|
|
5
|
+
export { readToolRenderer } from "./read-renderer.js";
|
|
8
6
|
declare const readSchema: import("@oh-my-pi/omptype").FluentType<{
|
|
9
7
|
path: string;
|
|
10
8
|
}, {
|
|
@@ -76,23 +74,3 @@ export declare class ReadTool implements AgentTool<typeof readSchema, ReadToolDe
|
|
|
76
74
|
syncInspectImageState(availableOverride?: boolean): boolean;
|
|
77
75
|
execute(_toolCallId: string, params: ReadParams, signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<ReadToolDetails>, _toolContext?: AgentToolContext): Promise<AgentToolResult<ReadToolDetails>>;
|
|
78
76
|
}
|
|
79
|
-
interface ReadRenderArgs {
|
|
80
|
-
path?: unknown;
|
|
81
|
-
file_path?: unknown;
|
|
82
|
-
offset?: number;
|
|
83
|
-
limit?: number;
|
|
84
|
-
raw?: boolean;
|
|
85
|
-
}
|
|
86
|
-
export declare const readToolRenderer: {
|
|
87
|
-
renderCall(args: ReadRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component;
|
|
88
|
-
renderResult(result: {
|
|
89
|
-
content: Array<{
|
|
90
|
-
type: string;
|
|
91
|
-
text?: string;
|
|
92
|
-
}>;
|
|
93
|
-
details?: ReadToolDetails;
|
|
94
|
-
isError?: boolean;
|
|
95
|
-
}, options: RenderResultOptions, uiTheme: Theme, args?: ReadRenderArgs): Component;
|
|
96
|
-
mergeCallAndResult: boolean;
|
|
97
|
-
};
|
|
98
|
-
export {};
|
|
@@ -17,7 +17,7 @@ export declare function tokenizeShellSegments(command: string): string[][];
|
|
|
17
17
|
*
|
|
18
18
|
* @see extractFlatShellCommandSegments
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
interface FlatShellCommandSegment {
|
|
21
21
|
/** Original segment text with quoting and escaping preserved. */
|
|
22
22
|
text: string;
|
|
23
23
|
/**
|
|
@@ -57,3 +57,4 @@ export declare function extractLeadingCdTarget(command: string): {
|
|
|
57
57
|
path: string;
|
|
58
58
|
rest: string;
|
|
59
59
|
} | null;
|
|
60
|
+
export {};
|
|
@@ -38,11 +38,6 @@ export declare function formatStartupChangelogSummary(selection: StartupChangelo
|
|
|
38
38
|
*/
|
|
39
39
|
export declare function resolveBundledChangelogPath(assetPath: string, moduleUrl: string | URL): string | URL;
|
|
40
40
|
export declare function parseChangelog(changelogPath: string | undefined): Promise<ChangelogEntry[]>;
|
|
41
|
-
/**
|
|
42
|
-
* Compare changelog entries by their parsed version parts.
|
|
43
|
-
* Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
44
|
-
*/
|
|
45
|
-
export declare function compareChangelogEntries(v1: ChangelogEntry, v2: ChangelogEntry): number;
|
|
46
41
|
/**
|
|
47
42
|
* Parse an omp changelog marker version into comparable parts.
|
|
48
43
|
*/
|
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": "17.2.
|
|
4
|
+
"version": "17.2.12",
|
|
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",
|
|
@@ -50,18 +50,18 @@
|
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@babel/parser": "^7.29.7",
|
|
53
|
-
"@oh-my-pi/hashline": "17.2.
|
|
54
|
-
"@oh-my-pi/omp-stats": "17.2.
|
|
55
|
-
"@oh-my-pi/omptype": "17.2.
|
|
56
|
-
"@oh-my-pi/pi-agent-core": "17.2.
|
|
57
|
-
"@oh-my-pi/pi-ai": "17.2.
|
|
58
|
-
"@oh-my-pi/pi-catalog": "17.2.
|
|
59
|
-
"@oh-my-pi/pi-mnemopi": "17.2.
|
|
60
|
-
"@oh-my-pi/pi-natives": "17.2.
|
|
61
|
-
"@oh-my-pi/pi-tui": "17.2.
|
|
62
|
-
"@oh-my-pi/pi-utils": "17.2.
|
|
63
|
-
"@oh-my-pi/pi-wire": "17.2.
|
|
64
|
-
"@oh-my-pi/snapcompact": "17.2.
|
|
53
|
+
"@oh-my-pi/hashline": "17.2.12",
|
|
54
|
+
"@oh-my-pi/omp-stats": "17.2.12",
|
|
55
|
+
"@oh-my-pi/omptype": "17.2.12",
|
|
56
|
+
"@oh-my-pi/pi-agent-core": "17.2.12",
|
|
57
|
+
"@oh-my-pi/pi-ai": "17.2.12",
|
|
58
|
+
"@oh-my-pi/pi-catalog": "17.2.12",
|
|
59
|
+
"@oh-my-pi/pi-mnemopi": "17.2.12",
|
|
60
|
+
"@oh-my-pi/pi-natives": "17.2.12",
|
|
61
|
+
"@oh-my-pi/pi-tui": "17.2.12",
|
|
62
|
+
"@oh-my-pi/pi-utils": "17.2.12",
|
|
63
|
+
"@oh-my-pi/pi-wire": "17.2.12",
|
|
64
|
+
"@oh-my-pi/snapcompact": "17.2.12",
|
|
65
65
|
"@opentelemetry/api": "^1.9.1",
|
|
66
66
|
"@opentelemetry/api-logs": "^0.220.0",
|
|
67
67
|
"@opentelemetry/context-async-hooks": "^2.9.0",
|
package/src/advisor/runtime.ts
CHANGED
|
@@ -5,7 +5,8 @@ import * as AIError from "@oh-my-pi/pi-ai/error";
|
|
|
5
5
|
import { raceWithSignal } from "@oh-my-pi/pi-ai/utils/abort";
|
|
6
6
|
import { type CursorExecResolvedCarrier, kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
|
|
7
7
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
|
-
import { obfuscateToolArguments
|
|
8
|
+
import { obfuscateToolArguments } from "../secrets/message-transform";
|
|
9
|
+
import type { SecretObfuscator } from "../secrets/obfuscator";
|
|
9
10
|
import {
|
|
10
11
|
formatExecutionSourcePreview,
|
|
11
12
|
formatSessionHistoryMarkdown,
|
|
@@ -970,14 +971,16 @@ export class AdvisorRuntime {
|
|
|
970
971
|
this.#wakeAllWaiters();
|
|
971
972
|
const failedMessages = this.agent.state.messages.slice(messageSnapshot);
|
|
972
973
|
const terminalFailure = this.#terminalAssistantFailure(messageSnapshot);
|
|
973
|
-
const
|
|
974
|
-
(terminalFailure !== undefined && isClassifierRefusal(terminalFailure)) ||
|
|
975
|
-
AIError.is(AIError.classify(err), AIError.Flag.ContentBlocked);
|
|
974
|
+
const rawErrorId = AIError.classify(err);
|
|
976
975
|
const terminalFailureId =
|
|
977
976
|
terminalFailure === undefined ? undefined : AIError.classifyMessage(terminalFailure);
|
|
977
|
+
const classifierRefusal =
|
|
978
|
+
(terminalFailure !== undefined && isClassifierRefusal(terminalFailure)) ||
|
|
979
|
+
(!AIError.is(rawErrorId, AIError.Flag.AccountPolicy) &&
|
|
980
|
+
AIError.is(rawErrorId, AIError.Flag.ContentBlocked));
|
|
978
981
|
const contextOverflow =
|
|
979
982
|
(terminalFailureId !== undefined && AIError.is(terminalFailureId, AIError.Flag.ContextOverflow)) ||
|
|
980
|
-
AIError.is(
|
|
983
|
+
AIError.is(rawErrorId, AIError.Flag.ContextOverflow);
|
|
981
984
|
// A terminal provider failure that is neither retriable nor an
|
|
982
985
|
// overflow (e.g. a blocked prompt) will fail identically on every
|
|
983
986
|
// retry — classify it before rollback so the batch is dropped after
|
|
@@ -1208,12 +1211,14 @@ export class AdvisorRuntime {
|
|
|
1208
1211
|
}
|
|
1209
1212
|
}
|
|
1210
1213
|
|
|
1211
|
-
/** Mirrors turn recovery's refusal classification
|
|
1214
|
+
/** Mirrors turn recovery's refusal classification without treating account eligibility as a model refusal. */
|
|
1212
1215
|
function isClassifierRefusal(message: AssistantMessage): boolean {
|
|
1213
1216
|
if (message.stopReason !== "error") return false;
|
|
1217
|
+
const id = AIError.classifyMessage(message);
|
|
1218
|
+
if (AIError.is(id, AIError.Flag.AccountPolicy)) return false;
|
|
1214
1219
|
const stopType = message.stopDetails?.type;
|
|
1215
1220
|
if (stopType === "refusal" || stopType === "sensitive") return true;
|
|
1216
|
-
return AIError.is(
|
|
1221
|
+
return AIError.is(id, AIError.Flag.ContentBlocked);
|
|
1217
1222
|
}
|
|
1218
1223
|
|
|
1219
1224
|
/**
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { Api, Model, ModelSpec, RemoteCompactionConfig } from "@oh-my-pi/pi-ai/types";
|
|
2
|
+
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
|
3
|
+
import {
|
|
4
|
+
getBundledModelReferenceIndex,
|
|
5
|
+
inheritReferenceThinking,
|
|
6
|
+
resolveModelReference,
|
|
7
|
+
} from "@oh-my-pi/pi-catalog/identity";
|
|
8
|
+
import { getVariantAliasSources, resolveVariantAlias } from "@oh-my-pi/pi-catalog/variant-collapse";
|
|
9
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
10
|
+
import { createLiveConfigHeaders, type HeaderSource } from "./model-config-values";
|
|
11
|
+
import { type ModelPatch, mergeCompat, mergeRemoteCompactionConfig } from "./model-patch";
|
|
12
|
+
import { parseModelString } from "./model-resolver";
|
|
13
|
+
import type { ModelOverride, ProviderAuthMode } from "./models-config-schema";
|
|
14
|
+
export interface CustomModelDefinitionLike extends ModelPatch {
|
|
15
|
+
id: string;
|
|
16
|
+
api?: Api;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
cost?: Model<Api>["cost"];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CustomModelBuildOptions {
|
|
22
|
+
useDefaults: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CustomModelOverlay extends ModelPatch {
|
|
26
|
+
id: string;
|
|
27
|
+
provider: string;
|
|
28
|
+
api: Api;
|
|
29
|
+
baseUrl: string;
|
|
30
|
+
cost?: Model<Api>["cost"];
|
|
31
|
+
isOAuth?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function mergeCustomModelHeaders(
|
|
35
|
+
providerHeaders: Record<string, string> | undefined,
|
|
36
|
+
modelHeaders: Record<string, string> | undefined,
|
|
37
|
+
authHeader: boolean | undefined,
|
|
38
|
+
apiKeyConfig: string | undefined,
|
|
39
|
+
): Record<string, string> | undefined {
|
|
40
|
+
return createLiveConfigHeaders([providerHeaders, modelHeaders], { authHeader, apiKeyConfig });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function mergeAuthHeaderSources(
|
|
44
|
+
sources: readonly HeaderSource[],
|
|
45
|
+
authHeader: boolean | undefined,
|
|
46
|
+
apiKeyConfig: string | undefined,
|
|
47
|
+
): Record<string, string> | undefined {
|
|
48
|
+
return createLiveConfigHeaders(sources, { authHeader, apiKeyConfig });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Decide whether a custom-yaml model should force OAuth-style request shaping.
|
|
53
|
+
* - Explicit `auth: oauth` → force on.
|
|
54
|
+
* endpoints are typically Claude-Code-style proxies (e.g. CLIProxyAPI) that expect
|
|
55
|
+
* the cloaked request shape regardless of how the proxy itself is authenticated.
|
|
56
|
+
* - Otherwise → unset.
|
|
57
|
+
*/
|
|
58
|
+
function resolveCustomModelIsOAuth(api: Api, providerAuth: ProviderAuthMode | undefined): boolean | undefined {
|
|
59
|
+
if (providerAuth === "oauth") return true;
|
|
60
|
+
if (providerAuth !== undefined) return undefined;
|
|
61
|
+
if (api === "anthropic-messages") return true;
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildCustomModelOverlay(
|
|
66
|
+
providerName: string,
|
|
67
|
+
providerBaseUrl: string,
|
|
68
|
+
providerApi: Api | undefined,
|
|
69
|
+
providerHeaders: Record<string, string> | undefined,
|
|
70
|
+
providerApiKey: string | undefined,
|
|
71
|
+
authHeader: boolean | undefined,
|
|
72
|
+
providerCompat: ModelSpec<Api>["compat"] | undefined,
|
|
73
|
+
providerAuth: ProviderAuthMode | undefined,
|
|
74
|
+
providerRemoteCompaction: RemoteCompactionConfig<Api> | undefined,
|
|
75
|
+
modelDef: CustomModelDefinitionLike,
|
|
76
|
+
): CustomModelOverlay | undefined {
|
|
77
|
+
const api = modelDef.api ?? providerApi;
|
|
78
|
+
if (!api) return undefined;
|
|
79
|
+
return {
|
|
80
|
+
id: modelDef.id,
|
|
81
|
+
provider: providerName,
|
|
82
|
+
api,
|
|
83
|
+
baseUrl: modelDef.baseUrl ?? providerBaseUrl,
|
|
84
|
+
name: modelDef.name,
|
|
85
|
+
reasoning: modelDef.reasoning,
|
|
86
|
+
thinking: modelDef.thinking,
|
|
87
|
+
input: modelDef.input,
|
|
88
|
+
supportsTools: modelDef.supportsTools,
|
|
89
|
+
cost: modelDef.cost,
|
|
90
|
+
contextWindow: modelDef.contextWindow,
|
|
91
|
+
maxTokens: modelDef.maxTokens,
|
|
92
|
+
omitMaxOutputTokens: modelDef.omitMaxOutputTokens,
|
|
93
|
+
headers: mergeCustomModelHeaders(providerHeaders, modelDef.headers, authHeader, providerApiKey),
|
|
94
|
+
compat: mergeCompat(providerCompat, modelDef.compat),
|
|
95
|
+
contextPromotionTarget: modelDef.contextPromotionTarget,
|
|
96
|
+
compactionModel: modelDef.compactionModel,
|
|
97
|
+
remoteCompaction: mergeRemoteCompactionConfig(providerRemoteCompaction, modelDef.remoteCompaction),
|
|
98
|
+
premiumMultiplier: modelDef.premiumMultiplier,
|
|
99
|
+
isOAuth: resolveCustomModelIsOAuth(api, providerAuth),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function applyStandaloneCustomModelPolicies(model: CustomModelOverlay): CustomModelOverlay {
|
|
104
|
+
if (model.id !== "gpt-5.4" || model.provider === "github-copilot" || model.contextWindow !== undefined) {
|
|
105
|
+
return model;
|
|
106
|
+
}
|
|
107
|
+
return { ...model, contextWindow: 1_000_000 };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function finalizeCustomModel(model: CustomModelOverlay, options: CustomModelBuildOptions): Model<Api> {
|
|
111
|
+
const resolvedModel = options.useDefaults ? applyStandaloneCustomModelPolicies(model) : model;
|
|
112
|
+
const reference = options.useDefaults
|
|
113
|
+
? resolveModelReference(resolvedModel.id, getBundledModelReferenceIndex())
|
|
114
|
+
: undefined;
|
|
115
|
+
const cost =
|
|
116
|
+
resolvedModel.cost ??
|
|
117
|
+
reference?.cost ??
|
|
118
|
+
(options.useDefaults ? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } : undefined);
|
|
119
|
+
const input = resolvedModel.input ?? reference?.input ?? (options.useDefaults ? ["text"] : undefined);
|
|
120
|
+
const supportsTools = resolvedModel.supportsTools ?? reference?.supportsTools;
|
|
121
|
+
return buildModel({
|
|
122
|
+
id: resolvedModel.id,
|
|
123
|
+
name: resolvedModel.name ?? (options.useDefaults ? resolvedModel.id : undefined),
|
|
124
|
+
api: resolvedModel.api,
|
|
125
|
+
provider: resolvedModel.provider,
|
|
126
|
+
baseUrl: resolvedModel.baseUrl,
|
|
127
|
+
reasoning: resolvedModel.reasoning ?? reference?.reasoning ?? (options.useDefaults ? false : undefined),
|
|
128
|
+
thinking: inheritReferenceThinking(resolvedModel.thinking, reference, resolvedModel.provider),
|
|
129
|
+
input: input as ("text" | "image")[],
|
|
130
|
+
...(supportsTools !== undefined ? { supportsTools } : {}),
|
|
131
|
+
cost,
|
|
132
|
+
contextWindow: resolvedModel.contextWindow ?? reference?.contextWindow ?? (options.useDefaults ? 128000 : null),
|
|
133
|
+
maxTokens: resolvedModel.maxTokens ?? reference?.maxTokens ?? (options.useDefaults ? 16384 : null),
|
|
134
|
+
headers: resolvedModel.headers,
|
|
135
|
+
omitMaxOutputTokens: resolvedModel.omitMaxOutputTokens ?? reference?.omitMaxOutputTokens,
|
|
136
|
+
compat: mergeCompat(reference?.compatConfig, resolvedModel.compat),
|
|
137
|
+
contextPromotionTarget: resolvedModel.contextPromotionTarget,
|
|
138
|
+
compactionModel: resolvedModel.compactionModel,
|
|
139
|
+
remoteCompaction: resolvedModel.remoteCompaction,
|
|
140
|
+
premiumMultiplier: resolvedModel.premiumMultiplier,
|
|
141
|
+
isOAuth: resolvedModel.isOAuth,
|
|
142
|
+
} as ModelSpec<Api>);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function normalizeSuppressedSelector(
|
|
146
|
+
selector: string,
|
|
147
|
+
hasLiveModel?: (provider: string, id: string) => boolean,
|
|
148
|
+
): string {
|
|
149
|
+
const trimmed = selector.trim();
|
|
150
|
+
if (!trimmed) return trimmed;
|
|
151
|
+
const parsed = parseModelString(trimmed, {
|
|
152
|
+
allowMaxSuffix: true,
|
|
153
|
+
allowAutoAlias: true,
|
|
154
|
+
isLiteralModelId: (provider, id) => hasLiveModel?.(provider, id) === true,
|
|
155
|
+
});
|
|
156
|
+
if (!parsed) return trimmed;
|
|
157
|
+
// Retired effort-tier variant ids normalize to their collapsed logical id
|
|
158
|
+
// so persisted suppressions keyed by raw member ids still bind.
|
|
159
|
+
const aliasId = resolveVariantAlias(parsed.provider, parsed.id);
|
|
160
|
+
return `${parsed.provider}/${aliasId ?? parsed.id}`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Look up a model's override, falling back to entries keyed by retired
|
|
165
|
+
* effort-tier variant ids (models.yml authored before collapsing). A raw key
|
|
166
|
+
* only re-binds when no live model holds that id.
|
|
167
|
+
*/
|
|
168
|
+
export function resolveModelOverrideWithAliases(
|
|
169
|
+
overrides: Map<string, ModelOverride>,
|
|
170
|
+
model: Model<Api>,
|
|
171
|
+
hasLiveModel: (provider: string, id: string) => boolean,
|
|
172
|
+
): ModelOverride | undefined {
|
|
173
|
+
const direct = overrides.get(model.id);
|
|
174
|
+
if (direct) return direct;
|
|
175
|
+
for (const rawId of getVariantAliasSources(model.provider, model.id)) {
|
|
176
|
+
if (hasLiveModel(model.provider, rawId)) continue;
|
|
177
|
+
const remapped = overrides.get(rawId);
|
|
178
|
+
if (remapped) {
|
|
179
|
+
logger.debug("model override re-keyed through variant alias", {
|
|
180
|
+
provider: model.provider,
|
|
181
|
+
from: rawId,
|
|
182
|
+
to: model.id,
|
|
183
|
+
});
|
|
184
|
+
return remapped;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|