@oh-my-pi/pi-coding-agent 13.11.0 → 13.12.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 +86 -0
- package/package.json +7 -7
- package/src/capability/rule.ts +4 -0
- package/src/cli/commands/init-xdg.ts +27 -0
- package/src/cli/config-cli.ts +8 -3
- package/src/cli/shell-cli.ts +1 -1
- package/src/commands/config.ts +1 -1
- package/src/config/model-registry.ts +160 -26
- package/src/config/model-resolver.ts +84 -21
- package/src/config/settings-schema.ts +812 -647
- package/src/discovery/helpers.ts +11 -2
- package/src/exa/index.ts +1 -11
- package/src/exa/search.ts +1 -122
- package/src/exec/bash-executor.ts +62 -25
- package/src/extensibility/custom-tools/types.ts +2 -3
- package/src/extensibility/extensions/types.ts +2 -0
- package/src/extensibility/hooks/types.ts +2 -0
- package/src/index.ts +6 -6
- package/src/internal-urls/docs-index.generated.ts +3 -3
- package/src/lsp/config.ts +1 -0
- package/src/lsp/defaults.json +3 -3
- package/src/memories/index.ts +20 -7
- package/src/memories/storage.ts +46 -32
- package/src/modes/components/agent-dashboard.ts +23 -35
- package/src/modes/components/assistant-message.ts +25 -2
- package/src/modes/components/btw-panel.ts +104 -0
- package/src/modes/components/settings-defs.ts +5 -1
- package/src/modes/components/settings-selector.ts +6 -6
- package/src/modes/controllers/btw-controller.ts +193 -0
- package/src/modes/controllers/command-controller.ts +3 -1
- package/src/modes/controllers/event-controller.ts +4 -0
- package/src/modes/controllers/extension-ui-controller.ts +6 -0
- package/src/modes/controllers/input-controller.ts +10 -1
- package/src/modes/controllers/selector-controller.ts +18 -17
- package/src/modes/interactive-mode.ts +22 -0
- package/src/modes/prompt-action-autocomplete.ts +17 -3
- package/src/modes/rpc/rpc-client.ts +30 -19
- package/src/modes/theme/theme.ts +28 -36
- package/src/modes/types.ts +4 -0
- package/src/modes/utils/ui-helpers.ts +3 -0
- package/src/patch/hashline.ts +120 -16
- package/src/prompts/system/btw-user.md +8 -0
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/tools/code-search.md +45 -0
- package/src/prompts/tools/hashline.md +3 -0
- package/src/prompts/tools/read.md +2 -2
- package/src/sdk.ts +36 -40
- package/src/session/agent-session.ts +65 -37
- package/src/session/blob-store.ts +32 -0
- package/src/session/compaction/compaction.ts +27 -6
- package/src/session/history-storage.ts +2 -2
- package/src/session/session-manager.ts +116 -44
- package/src/session/streaming-output.ts +17 -54
- package/src/slash-commands/builtin-registry.ts +11 -0
- package/src/system-prompt.ts +4 -17
- package/src/task/agents.ts +1 -1
- package/src/task/executor.ts +1 -1
- package/src/task/index.ts +9 -8
- package/src/tools/browser.ts +11 -0
- package/src/tools/exit-plan-mode.ts +6 -0
- package/src/tools/fetch.ts +1 -1
- package/src/tools/output-meta.ts +104 -9
- package/src/tools/read.ts +13 -26
- package/src/utils/title-generator.ts +70 -92
- package/src/utils/tools-manager.ts +1 -1
- package/src/web/scrapers/index.ts +7 -7
- package/src/web/scrapers/utils.ts +1 -0
- package/src/web/search/code-search.ts +385 -0
- package/src/web/search/index.ts +25 -280
- package/src/web/search/provider.ts +1 -1
- package/src/web/search/types.ts +28 -0
- package/src/exa/company.ts +0 -26
- package/src/exa/linkedin.ts +0 -26
package/src/modes/theme/theme.ts
CHANGED
|
@@ -177,16 +177,14 @@ export type SymbolKey =
|
|
|
177
177
|
| "lang.archive"
|
|
178
178
|
| "lang.binary"
|
|
179
179
|
// Settings tab icons
|
|
180
|
-
| "tab.
|
|
181
|
-
| "tab.
|
|
182
|
-
| "tab.
|
|
180
|
+
| "tab.appearance"
|
|
181
|
+
| "tab.model"
|
|
182
|
+
| "tab.interaction"
|
|
183
|
+
| "tab.context"
|
|
184
|
+
| "tab.editing"
|
|
183
185
|
| "tab.tools"
|
|
184
|
-
| "tab.
|
|
185
|
-
| "tab.
|
|
186
|
-
| "tab.bash"
|
|
187
|
-
| "tab.lsp"
|
|
188
|
-
| "tab.ttsr"
|
|
189
|
-
| "tab.status";
|
|
186
|
+
| "tab.tasks"
|
|
187
|
+
| "tab.providers";
|
|
190
188
|
|
|
191
189
|
type SymbolMap = Record<SymbolKey, string>;
|
|
192
190
|
|
|
@@ -338,16 +336,14 @@ const UNICODE_SYMBOLS: SymbolMap = {
|
|
|
338
336
|
"lang.archive": "🗜",
|
|
339
337
|
"lang.binary": "⚙",
|
|
340
338
|
// Settings tabs
|
|
341
|
-
"tab.
|
|
342
|
-
"tab.
|
|
343
|
-
"tab.
|
|
339
|
+
"tab.appearance": "🎨",
|
|
340
|
+
"tab.model": "🤖",
|
|
341
|
+
"tab.interaction": "⌨",
|
|
342
|
+
"tab.context": "📋",
|
|
343
|
+
"tab.editing": "💻",
|
|
344
344
|
"tab.tools": "🔧",
|
|
345
|
-
"tab.
|
|
346
|
-
"tab.
|
|
347
|
-
"tab.bash": "💻",
|
|
348
|
-
"tab.lsp": "📝",
|
|
349
|
-
"tab.ttsr": "⏱",
|
|
350
|
-
"tab.status": "📊",
|
|
345
|
+
"tab.tasks": "📦",
|
|
346
|
+
"tab.providers": "🌐",
|
|
351
347
|
};
|
|
352
348
|
|
|
353
349
|
const NERD_SYMBOLS: SymbolMap = {
|
|
@@ -591,16 +587,14 @@ const NERD_SYMBOLS: SymbolMap = {
|
|
|
591
587
|
"lang.archive": "\u{F187}",
|
|
592
588
|
"lang.binary": "\u{F019A}",
|
|
593
589
|
// Settings tab icons
|
|
594
|
-
"tab.
|
|
595
|
-
"tab.
|
|
596
|
-
"tab.
|
|
590
|
+
"tab.appearance": "",
|
|
591
|
+
"tab.model": "",
|
|
592
|
+
"tab.interaction": "",
|
|
593
|
+
"tab.context": "",
|
|
594
|
+
"tab.editing": "",
|
|
597
595
|
"tab.tools": "",
|
|
598
|
-
"tab.
|
|
599
|
-
"tab.
|
|
600
|
-
"tab.bash": "",
|
|
601
|
-
"tab.lsp": "",
|
|
602
|
-
"tab.ttsr": "",
|
|
603
|
-
"tab.status": "",
|
|
596
|
+
"tab.tasks": "",
|
|
597
|
+
"tab.providers": "",
|
|
604
598
|
};
|
|
605
599
|
|
|
606
600
|
const ASCII_SYMBOLS: SymbolMap = {
|
|
@@ -750,16 +744,14 @@ const ASCII_SYMBOLS: SymbolMap = {
|
|
|
750
744
|
"lang.archive": "zip",
|
|
751
745
|
"lang.binary": "bin",
|
|
752
746
|
// Settings tab icons
|
|
753
|
-
"tab.
|
|
754
|
-
"tab.
|
|
755
|
-
"tab.
|
|
747
|
+
"tab.appearance": "[A]",
|
|
748
|
+
"tab.model": "[M]",
|
|
749
|
+
"tab.interaction": "[I]",
|
|
750
|
+
"tab.context": "[X]",
|
|
751
|
+
"tab.editing": "[E]",
|
|
756
752
|
"tab.tools": "[T]",
|
|
757
|
-
"tab.
|
|
758
|
-
"tab.
|
|
759
|
-
"tab.bash": "[B]",
|
|
760
|
-
"tab.lsp": "[L]",
|
|
761
|
-
"tab.ttsr": "[R]",
|
|
762
|
-
"tab.status": "[=]",
|
|
753
|
+
"tab.tasks": "[K]",
|
|
754
|
+
"tab.providers": "[P]",
|
|
763
755
|
};
|
|
764
756
|
|
|
765
757
|
const SYMBOL_PRESETS: Record<SymbolPreset, SymbolMap> = {
|
package/src/modes/types.ts
CHANGED
|
@@ -56,6 +56,7 @@ export interface InteractiveModeContext {
|
|
|
56
56
|
pendingMessagesContainer: Container;
|
|
57
57
|
statusContainer: Container;
|
|
58
58
|
todoContainer: Container;
|
|
59
|
+
btwContainer: Container;
|
|
59
60
|
editor: CustomEditor;
|
|
60
61
|
editorContainer: Container;
|
|
61
62
|
statusLine: StatusLineComponent;
|
|
@@ -205,6 +206,9 @@ export interface InteractiveModeContext {
|
|
|
205
206
|
handleDequeue(): void;
|
|
206
207
|
handleBackgroundCommand(): void;
|
|
207
208
|
handleImagePaste(): Promise<boolean>;
|
|
209
|
+
handleBtwCommand(question: string): Promise<void>;
|
|
210
|
+
hasActiveBtw(): boolean;
|
|
211
|
+
handleBtwEscape(): boolean;
|
|
208
212
|
cycleThinkingLevel(): void;
|
|
209
213
|
cycleRoleModel(options?: { temporary?: boolean }): Promise<void>;
|
|
210
214
|
toggleToolOutputExpansion(): void;
|
|
@@ -232,6 +232,9 @@ export class UiHelpers {
|
|
|
232
232
|
this.ctx.addMessageToChat(message);
|
|
233
233
|
const lastChild = this.ctx.chatContainer.children[this.ctx.chatContainer.children.length - 1];
|
|
234
234
|
const assistantComponent = lastChild instanceof AssistantMessageComponent ? lastChild : undefined;
|
|
235
|
+
if (assistantComponent) {
|
|
236
|
+
assistantComponent.setUsageInfo(message.usage);
|
|
237
|
+
}
|
|
235
238
|
readGroup = null;
|
|
236
239
|
const hasErrorStop = message.stopReason === "aborted" || message.stopReason === "error";
|
|
237
240
|
const errorMessage = hasErrorStop
|
package/src/patch/hashline.ts
CHANGED
|
@@ -744,11 +744,130 @@ export interface CompactHashlineDiffOptions {
|
|
|
744
744
|
maxOutputLines?: number;
|
|
745
745
|
}
|
|
746
746
|
|
|
747
|
-
const NUMBERED_DIFF_LINE_RE = /^([ +-])(\d+)\|(.*)$/;
|
|
747
|
+
const NUMBERED_DIFF_LINE_RE = /^([ +-])(\s*\d+)\|(.*)$/;
|
|
748
|
+
const HASHLINE_PREVIEW_PLACEHOLDER = " ";
|
|
748
749
|
|
|
749
750
|
type DiffRunKind = " " | "+" | "-" | "meta";
|
|
750
751
|
type DiffRun = { kind: DiffRunKind; lines: string[] };
|
|
751
752
|
|
|
753
|
+
interface ParsedNumberedDiffLine {
|
|
754
|
+
kind: " " | "+" | "-";
|
|
755
|
+
lineNumber: number;
|
|
756
|
+
lineWidth: number;
|
|
757
|
+
content: string;
|
|
758
|
+
raw: string;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
interface CompactPreviewCounters {
|
|
762
|
+
oldLine?: number;
|
|
763
|
+
newLine?: number;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
function parseNumberedDiffLine(line: string): ParsedNumberedDiffLine | undefined {
|
|
767
|
+
const match = NUMBERED_DIFF_LINE_RE.exec(line);
|
|
768
|
+
if (!match) return undefined;
|
|
769
|
+
|
|
770
|
+
const kind = match[1];
|
|
771
|
+
if (kind !== " " && kind !== "+" && kind !== "-") return undefined;
|
|
772
|
+
|
|
773
|
+
const lineField = match[2];
|
|
774
|
+
const lineNumber = Number(lineField.trim());
|
|
775
|
+
if (!Number.isInteger(lineNumber)) return undefined;
|
|
776
|
+
|
|
777
|
+
return { kind, lineNumber, lineWidth: lineField.length, content: match[3], raw: line };
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function syncOldLineCounters(counters: CompactPreviewCounters, lineNumber: number): void {
|
|
781
|
+
if (counters.oldLine === undefined || counters.newLine === undefined) {
|
|
782
|
+
counters.oldLine = lineNumber;
|
|
783
|
+
counters.newLine = lineNumber;
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
const delta = lineNumber - counters.oldLine;
|
|
788
|
+
counters.oldLine = lineNumber;
|
|
789
|
+
counters.newLine += delta;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
function syncNewLineCounters(counters: CompactPreviewCounters, lineNumber: number): void {
|
|
793
|
+
if (counters.oldLine === undefined || counters.newLine === undefined) {
|
|
794
|
+
counters.oldLine = lineNumber;
|
|
795
|
+
counters.newLine = lineNumber;
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const delta = lineNumber - counters.newLine;
|
|
800
|
+
counters.oldLine += delta;
|
|
801
|
+
counters.newLine = lineNumber;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
function formatCompactHashlineLine(kind: " " | "+", lineNumber: number, width: number, content: string): string {
|
|
805
|
+
const padded = String(lineNumber).padStart(width, " ");
|
|
806
|
+
return `${kind}${padded}#${computeLineHash(lineNumber, content)}|${content}`;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
function formatCompactRemovedLine(lineNumber: number, width: number, content: string): string {
|
|
810
|
+
const padded = String(lineNumber).padStart(width, " ");
|
|
811
|
+
return `-${padded}${HASHLINE_PREVIEW_PLACEHOLDER}|${content}`;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
function formatCompactPreviewLine(line: string, counters: CompactPreviewCounters): { kind: DiffRunKind; text: string } {
|
|
815
|
+
const parsed = parseNumberedDiffLine(line);
|
|
816
|
+
if (!parsed) return { kind: "meta", text: line };
|
|
817
|
+
|
|
818
|
+
if (parsed.content === "...") {
|
|
819
|
+
if (parsed.kind === "+") {
|
|
820
|
+
syncNewLineCounters(counters, parsed.lineNumber);
|
|
821
|
+
} else {
|
|
822
|
+
syncOldLineCounters(counters, parsed.lineNumber);
|
|
823
|
+
}
|
|
824
|
+
return { kind: parsed.kind, text: parsed.raw };
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
switch (parsed.kind) {
|
|
828
|
+
case "+": {
|
|
829
|
+
syncNewLineCounters(counters, parsed.lineNumber);
|
|
830
|
+
const newLine = counters.newLine;
|
|
831
|
+
if (newLine === undefined) return { kind: "+", text: parsed.raw };
|
|
832
|
+
const text = formatCompactHashlineLine("+", newLine, parsed.lineWidth, parsed.content);
|
|
833
|
+
counters.newLine = newLine + 1;
|
|
834
|
+
return { kind: "+", text };
|
|
835
|
+
}
|
|
836
|
+
case "-": {
|
|
837
|
+
syncOldLineCounters(counters, parsed.lineNumber);
|
|
838
|
+
const text = formatCompactRemovedLine(parsed.lineNumber, parsed.lineWidth, parsed.content);
|
|
839
|
+
counters.oldLine = parsed.lineNumber + 1;
|
|
840
|
+
return { kind: "-", text };
|
|
841
|
+
}
|
|
842
|
+
case " ": {
|
|
843
|
+
syncOldLineCounters(counters, parsed.lineNumber);
|
|
844
|
+
const newLine = counters.newLine;
|
|
845
|
+
if (newLine === undefined) return { kind: " ", text: parsed.raw };
|
|
846
|
+
const text = formatCompactHashlineLine(" ", newLine, parsed.lineWidth, parsed.content);
|
|
847
|
+
counters.oldLine = parsed.lineNumber + 1;
|
|
848
|
+
counters.newLine = newLine + 1;
|
|
849
|
+
return { kind: " ", text };
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
function splitDiffRuns(lines: string[]): DiffRun[] {
|
|
855
|
+
const runs: DiffRun[] = [];
|
|
856
|
+
const counters: CompactPreviewCounters = {};
|
|
857
|
+
|
|
858
|
+
for (const line of lines) {
|
|
859
|
+
const formatted = formatCompactPreviewLine(line, counters);
|
|
860
|
+
const prev = runs[runs.length - 1];
|
|
861
|
+
if (prev && prev.kind === formatted.kind) {
|
|
862
|
+
prev.lines.push(formatted.text);
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
runs.push({ kind: formatted.kind, lines: [formatted.text] });
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
return runs;
|
|
869
|
+
}
|
|
870
|
+
|
|
752
871
|
function collapseFromStart(lines: string[], maxLines: number, label: string): string[] {
|
|
753
872
|
if (lines.length <= maxLines) return lines;
|
|
754
873
|
const hidden = lines.length - maxLines;
|
|
@@ -767,21 +886,6 @@ function collapseFromMiddle(lines: string[], maxLines: number, label: string): s
|
|
|
767
886
|
return [...lines.slice(0, maxLines), ` ... ${hidden} more ${label} lines`, ...lines.slice(-maxLines)];
|
|
768
887
|
}
|
|
769
888
|
|
|
770
|
-
function splitDiffRuns(lines: string[]): DiffRun[] {
|
|
771
|
-
const runs: DiffRun[] = [];
|
|
772
|
-
for (const line of lines) {
|
|
773
|
-
const match = NUMBERED_DIFF_LINE_RE.exec(line);
|
|
774
|
-
const kind = (match?.[1] as " " | "+" | "-" | undefined) ?? "meta";
|
|
775
|
-
const prev = runs[runs.length - 1];
|
|
776
|
-
if (prev && prev.kind === kind) {
|
|
777
|
-
prev.lines.push(line);
|
|
778
|
-
continue;
|
|
779
|
-
}
|
|
780
|
-
runs.push({ kind, lines: [line] });
|
|
781
|
-
}
|
|
782
|
-
return runs;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
889
|
/**
|
|
786
890
|
* Build a compact diff preview suitable for model-visible tool responses.
|
|
787
891
|
*
|
|
@@ -297,6 +297,7 @@ When a tool call fails, read the full error before doing anything else. When a f
|
|
|
297
297
|
- You **MUST** exhaust tools/context/files first — explore.
|
|
298
298
|
## 7. Verification
|
|
299
299
|
- Test everything rigorously → Future contributor cannot break behavior without failure. Prefer unit/e2e.
|
|
300
|
+
- You **MUST NOT** rely on mocks — they invent behaviors that never happen in production and hide real bugs.
|
|
300
301
|
- You **SHOULD** run only tests you added/modified unless asked otherwise.
|
|
301
302
|
- You **MUST NOT** yield without proof when non-trivial work, self-assessment is deceptive: tests, linters, type checks, repro steps… exhaust all external verification.
|
|
302
303
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
Search code snippets, and technical content.
|
|
2
|
+
This tool behaves more like grep than natural-language web search.
|
|
3
|
+
|
|
4
|
+
<instruction>
|
|
5
|
+
- Query with exact symbols, identifiers, error strings, CLI flags, filenames, import paths, and short code fragments
|
|
6
|
+
- Start with the smallest distinctive token; widen or add one nearby token only if the first query is too broad
|
|
7
|
+
- Prefer exact syntax when punctuation carries meaning, such as `Promise.withResolvers`, `useEffect(`, `--watch`, or `"direnv loading"`
|
|
8
|
+
- Keep `query` terse; remove filler words, prose, and request framing
|
|
9
|
+
- Use `code_context` only for a few disambiguating tokens such as language, library, framework, repo, runtime, or API name
|
|
10
|
+
- If a multi-word literal matters exactly, quote the shortest stable phrase first, then refine
|
|
11
|
+
- When looking for usage examples of a specific API, search the symbol first; add surrounding call syntax only when needed
|
|
12
|
+
</instruction>
|
|
13
|
+
|
|
14
|
+
<parameters>
|
|
15
|
+
- query: Grep-style code search query; use exact tokens, short fragments, or short quoted phrases
|
|
16
|
+
- code_context: Optional disambiguation tokens only, not a sentence
|
|
17
|
+
</parameters>
|
|
18
|
+
|
|
19
|
+
<examples>
|
|
20
|
+
Good queries:
|
|
21
|
+
- `Promise.withResolvers`
|
|
22
|
+
- `DIRENV_LOG_FORMAT`
|
|
23
|
+
- `"direnv loading"`
|
|
24
|
+
- `useState` with `code_context: react hooks`
|
|
25
|
+
- `app.get(` with `code_context: express`
|
|
26
|
+
- `ERR_REQUIRE_ESM` with `code_context: node`
|
|
27
|
+
|
|
28
|
+
Bad queries:
|
|
29
|
+
- `Need the official or source-backed way to silence direnv loading output`
|
|
30
|
+
- `How do I use Promise.withResolvers in Bun?`
|
|
31
|
+
- `find examples of React state hooks in TypeScript projects`
|
|
32
|
+
- `search GitHub for express routing docs`
|
|
33
|
+
</examples>
|
|
34
|
+
|
|
35
|
+
<avoid>
|
|
36
|
+
- Do not use this tool for broad conceptual research, comparisons, or authoritative sourcing; use `web_search`, `web_search_deep`, or `fetch` instead
|
|
37
|
+
- Do not put full-sentence instructions into `query` or `code_context`
|
|
38
|
+
- Do not pack many weak terms into one query; one strong token plus minimal context usually works better
|
|
39
|
+
</avoid>
|
|
40
|
+
|
|
41
|
+
<critical>
|
|
42
|
+
- `query` should be grep-style code search, not a natural-language request
|
|
43
|
+
- `code_context` is optional and should stay short
|
|
44
|
+
- If you need explanations, best practices, or comprehensive answers, use broader web search tools instead of this one
|
|
45
|
+
</critical>
|
|
@@ -184,4 +184,7 @@ Use a trailing `""` to preserve the blank line between sibling declarations.
|
|
|
184
184
|
- **Never target shared boundary lines.** Do not use `replace` spans that start, end, or pivot on a line that closes one construct and opens/separates another, such as `},{`, `}),`, `} else {`, or `} catch (err) {`. Those lines are not owned by a single block. Move the range inward to body-only lines, or widen it to consume one whole owned construct including its true trailing delimiter.
|
|
185
185
|
- **`lines` must not extend past `end`.** `lines` replaces exactly `pos..end`. Content after `end` survives. If you include lines in `lines` that exist after `end`, they will appear twice. Either extend `end` to cover all lines you are re-emitting, or remove the extra lines from `lines`.
|
|
186
186
|
- `lines` entries **MUST** be literal file content with indentation copied exactly from the `read` output. If the file uses tabs, use a real tab character.
|
|
187
|
+
- After any successful `edit` call on a file, the next change to that same file **MUST** start with a fresh `read`. Do not chain a second `edit` call off stale mental state, even if the intended range is nearby.
|
|
188
|
+
- If you need a second change in the same local region, default to one wider `replace` over the whole owned block instead of a sequence of micro-edits on adjacent lines. Repeated small patches in a moving region are unstable.
|
|
189
|
+
- If a local region is already malformed or a prior patch partially landed, stop nibbling at it. Re-read the file and replace the full owned block from a stable boundary; for a small file, prefer rewriting the file over stacking more tiny repairs.
|
|
187
190
|
</critical>
|
|
@@ -4,10 +4,10 @@ Reads files from local filesystem or internal URLs.
|
|
|
4
4
|
- Reads up to {{DEFAULT_LIMIT}} lines default
|
|
5
5
|
- Use `offset` and `limit` for large files; max {{DEFAULT_MAX_LINES}} lines per call
|
|
6
6
|
{{#if IS_HASHLINE_MODE}}
|
|
7
|
-
-
|
|
7
|
+
- Filesystem output is CID prefixed: `LINE#ID:content`
|
|
8
8
|
{{else}}
|
|
9
9
|
{{#if IS_LINE_NUMBER_MODE}}
|
|
10
|
-
-
|
|
10
|
+
- Filesystem output is line-number-prefixed
|
|
11
11
|
{{/if}}
|
|
12
12
|
{{/if}}
|
|
13
13
|
- Supports images (PNG, JPG) and PDFs
|
package/src/sdk.ts
CHANGED
|
@@ -89,10 +89,13 @@ import {
|
|
|
89
89
|
GrepTool,
|
|
90
90
|
getSearchTools,
|
|
91
91
|
HIDDEN_TOOLS,
|
|
92
|
+
isCodeSearchProviderId,
|
|
93
|
+
isSearchProviderPreference,
|
|
92
94
|
loadSshTool,
|
|
93
95
|
PythonTool,
|
|
94
96
|
ReadTool,
|
|
95
97
|
ResolveTool,
|
|
98
|
+
setPreferredCodeSearchProvider,
|
|
96
99
|
setPreferredImageProvider,
|
|
97
100
|
setPreferredSearchProvider,
|
|
98
101
|
type Tool,
|
|
@@ -224,17 +227,17 @@ export {
|
|
|
224
227
|
BashTool,
|
|
225
228
|
// Tool classes and factories
|
|
226
229
|
BUILTIN_TOOLS,
|
|
227
|
-
HIDDEN_TOOLS,
|
|
228
230
|
createTools,
|
|
229
231
|
EditTool,
|
|
230
232
|
FindTool,
|
|
231
233
|
GrepTool,
|
|
234
|
+
HIDDEN_TOOLS,
|
|
232
235
|
loadSshTool,
|
|
233
236
|
PythonTool,
|
|
234
237
|
ReadTool,
|
|
235
238
|
ResolveTool,
|
|
236
|
-
WriteTool,
|
|
237
239
|
type ToolSession,
|
|
240
|
+
WriteTool,
|
|
238
241
|
};
|
|
239
242
|
|
|
240
243
|
// Helper Functions
|
|
@@ -628,8 +631,20 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
628
631
|
options.skills === undefined ? discoverSkills(cwd, agentDir, skillsSettings) : undefined;
|
|
629
632
|
|
|
630
633
|
// Initialize provider preferences from settings
|
|
631
|
-
|
|
632
|
-
|
|
634
|
+
const webSearchProvider = settings.get("providers.webSearch");
|
|
635
|
+
if (typeof webSearchProvider === "string" && isSearchProviderPreference(webSearchProvider)) {
|
|
636
|
+
setPreferredSearchProvider(webSearchProvider);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const codeSearchProvider = settings.get("providers.codeSearch");
|
|
640
|
+
if (typeof codeSearchProvider === "string" && isCodeSearchProviderId(codeSearchProvider)) {
|
|
641
|
+
setPreferredCodeSearchProvider(codeSearchProvider);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const imageProvider = settings.get("providers.image");
|
|
645
|
+
if (imageProvider === "auto" || imageProvider === "gemini" || imageProvider === "openrouter") {
|
|
646
|
+
setPreferredImageProvider(imageProvider);
|
|
647
|
+
}
|
|
633
648
|
|
|
634
649
|
const sessionManager = options.sessionManager ?? logger.time("sessionManager", SessionManager.create, cwd);
|
|
635
650
|
const sessionId = sessionManager.getSessionId();
|
|
@@ -687,19 +702,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
687
702
|
}
|
|
688
703
|
}
|
|
689
704
|
|
|
690
|
-
// For subagent sessions using GitHub Copilot, add X-Initiator header
|
|
691
|
-
// to ensure proper billing (agent-initiated vs user-initiated)
|
|
692
705
|
const taskDepth = options.taskDepth ?? 0;
|
|
693
|
-
const forceCopilotAgentInitiator = taskDepth > 0;
|
|
694
|
-
if (forceCopilotAgentInitiator && model?.provider === "github-copilot") {
|
|
695
|
-
model = {
|
|
696
|
-
...model,
|
|
697
|
-
headers: {
|
|
698
|
-
...model.headers,
|
|
699
|
-
"X-Initiator": "agent",
|
|
700
|
-
},
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
706
|
|
|
704
707
|
let thinkingLevel = options.thinkingLevel;
|
|
705
708
|
|
|
@@ -962,19 +965,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
962
965
|
customTools.push(...(geminiImageTools as unknown as CustomTool[]));
|
|
963
966
|
}
|
|
964
967
|
|
|
965
|
-
// Add
|
|
966
|
-
|
|
967
|
-
if (exaSettings.enabled && exaSettings.enableSearch) {
|
|
968
|
-
const exaSearchTools = await logger.timeAsync("getSearchTools", getSearchTools, {
|
|
969
|
-
enableLinkedin: exaSettings.enableLinkedin as boolean,
|
|
970
|
-
enableCompany: exaSettings.enableCompany as boolean,
|
|
971
|
-
});
|
|
972
|
-
// Filter out the base web_search (already in built-in tools), add specialized Exa tools
|
|
973
|
-
const specializedTools = exaSearchTools.filter(t => t.name !== "web_search");
|
|
974
|
-
if (specializedTools.length > 0) {
|
|
975
|
-
customTools.push(...specializedTools);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
968
|
+
// Add web search tools
|
|
969
|
+
customTools.push(...getSearchTools());
|
|
978
970
|
|
|
979
971
|
// Discover and load custom tools from .omp/tools/, .claude/tools/, etc.
|
|
980
972
|
const builtInToolNames = builtinTools.map(t => t.name);
|
|
@@ -1336,6 +1328,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1336
1328
|
if (!obfuscator?.hasSecrets()) return converted;
|
|
1337
1329
|
return obfuscateMessages(obfuscator, converted);
|
|
1338
1330
|
};
|
|
1331
|
+
const transformContext = extensionRunner
|
|
1332
|
+
? async (messages: AgentMessage[], _signal?: AbortSignal) => {
|
|
1333
|
+
return await extensionRunner.emitContext(messages);
|
|
1334
|
+
}
|
|
1335
|
+
: undefined;
|
|
1336
|
+
const onPayload = extensionRunner
|
|
1337
|
+
? async (payload: unknown, _model?: Model) => {
|
|
1338
|
+
return await extensionRunner.emitBeforeProviderRequest(payload);
|
|
1339
|
+
}
|
|
1340
|
+
: undefined;
|
|
1339
1341
|
|
|
1340
1342
|
const setToolUIContext = (uiContext: ExtensionUIContext, hasUI: boolean) => {
|
|
1341
1343
|
toolContextStore.setUIContext(uiContext, hasUI);
|
|
@@ -1358,17 +1360,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1358
1360
|
tools: initialTools,
|
|
1359
1361
|
},
|
|
1360
1362
|
convertToLlm: convertToLlmFinal,
|
|
1361
|
-
onPayload
|
|
1362
|
-
? async (payload, _model) => {
|
|
1363
|
-
return extensionRunner.emitBeforeProviderRequest(payload);
|
|
1364
|
-
}
|
|
1365
|
-
: undefined,
|
|
1363
|
+
onPayload,
|
|
1366
1364
|
sessionId: sessionManager.getSessionId(),
|
|
1367
|
-
transformContext
|
|
1368
|
-
? async messages => {
|
|
1369
|
-
return extensionRunner.emitContext(messages);
|
|
1370
|
-
}
|
|
1371
|
-
: undefined,
|
|
1365
|
+
transformContext,
|
|
1372
1366
|
steeringMode: settings.get("steeringMode") ?? "one-at-a-time",
|
|
1373
1367
|
followUpMode: settings.get("followUpMode") ?? "one-at-a-time",
|
|
1374
1368
|
interruptMode: settings.get("interruptMode") ?? "immediate",
|
|
@@ -1443,9 +1437,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1443
1437
|
skillsSettings: settings.getGroup("skills") as Required<SkillsSettings>,
|
|
1444
1438
|
modelRegistry,
|
|
1445
1439
|
toolRegistry,
|
|
1440
|
+
transformContext,
|
|
1441
|
+
onPayload,
|
|
1442
|
+
convertToLlm: convertToLlmFinal,
|
|
1446
1443
|
rebuildSystemPrompt,
|
|
1447
1444
|
ttsrManager,
|
|
1448
|
-
forceCopilotAgentInitiator,
|
|
1449
1445
|
obfuscator,
|
|
1450
1446
|
asyncJobManager,
|
|
1451
1447
|
pendingActionStore,
|