@oh-my-pi/pi-coding-agent 10.3.1 → 10.5.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 +46 -0
- package/docs/config-usage.md +41 -41
- package/package.json +16 -11
- package/src/capability/index.ts +9 -0
- package/src/cli/args.ts +2 -2
- package/src/cli/update-cli.ts +2 -5
- package/src/config/settings-schema.ts +18 -0
- package/src/config.ts +1 -4
- package/src/extensibility/custom-tools/types.ts +6 -1
- package/src/extensibility/custom-tools/wrapper.ts +9 -28
- package/src/extensibility/extensions/types.ts +6 -1
- package/src/extensibility/extensions/wrapper.ts +20 -32
- package/src/extensibility/hooks/tool-wrapper.ts +6 -16
- package/src/extensibility/tool-proxy.ts +25 -0
- package/src/index.ts +1 -0
- package/src/ipy/executor.ts +107 -3
- package/src/ipy/gateway-coordinator.ts +0 -4
- package/src/ipy/kernel.ts +65 -175
- package/src/main.ts +17 -0
- package/src/mcp/render.ts +123 -0
- package/src/mcp/tool-bridge.ts +24 -1
- package/src/modes/components/tool-execution.ts +83 -96
- package/src/modes/controllers/input-controller.ts +38 -0
- package/src/modes/interactive-mode.ts +13 -0
- package/src/patch/index.ts +1 -0
- package/src/prompts/system/system-prompt.md +5 -2
- package/src/prompts/tools/ask.md +6 -9
- package/src/prompts/tools/browser.md +26 -0
- package/src/prompts/tools/task.md +29 -4
- package/src/sdk.ts +21 -1
- package/src/session/session-manager.ts +1 -0
- package/src/task/executor.ts +5 -47
- package/src/tools/ask.ts +60 -71
- package/src/tools/bash.ts +1 -0
- package/src/tools/browser.ts +1138 -0
- package/src/tools/find.ts +11 -2
- package/src/tools/index.ts +4 -0
- package/src/tools/json-tree.ts +231 -0
- package/src/tools/notebook.ts +1 -0
- package/src/tools/puppeteer/00_stealth_tampering.txt +63 -0
- package/src/tools/puppeteer/01_stealth_activity.txt +20 -0
- package/src/tools/puppeteer/02_stealth_hairline.txt +11 -0
- package/src/tools/puppeteer/03_stealth_botd.txt +384 -0
- package/src/tools/puppeteer/04_stealth_iframe.txt +81 -0
- package/src/tools/puppeteer/05_stealth_webgl.txt +75 -0
- package/src/tools/puppeteer/06_stealth_screen.txt +72 -0
- package/src/tools/puppeteer/07_stealth_fonts.txt +97 -0
- package/src/tools/puppeteer/08_stealth_audio.txt +51 -0
- package/src/tools/puppeteer/09_stealth_locale.txt +46 -0
- package/src/tools/puppeteer/10_stealth_plugins.txt +206 -0
- package/src/tools/puppeteer/11_stealth_hardware.txt +8 -0
- package/src/tools/puppeteer/12_stealth_codecs.txt +40 -0
- package/src/tools/puppeteer/13_stealth_worker.txt +74 -0
- package/src/tools/python.ts +1 -0
- package/src/tools/ssh.ts +1 -0
- package/src/tools/todo-write.ts +1 -0
- package/src/tools/write.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [10.5.0] - 2026-02-04
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Changed `ask` tool to require `questions` array parameter; single-question mode with `question`, `options`, `multi`, and `recommended` parameters is no longer supported
|
|
10
|
+
- Removed support for local Python kernel gateway startup; shared gateway is now required
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added browser tool powered by Ulixee Hero with support for navigation, DOM interaction, screenshots, and readable content extraction
|
|
15
|
+
- Added `/browser` command to toggle browser headless vs visible mode in interactive sessions
|
|
16
|
+
- Added `browser.enabled` and `browser.headless` settings to control browser automation behavior
|
|
17
|
+
- Added Python prelude caching to improve startup performance by storing compiled prelude helpers and module metadata
|
|
18
|
+
- Added `OMP_DEBUG_STARTUP` environment variable for conditional startup performance debugging output
|
|
19
|
+
- Added autonomous memory system with storage, memory tools, and context injection
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Updated task tool guidance to enforce small, well-defined task scope with maximum 3-5 files per task to prevent timeouts and improve parallel execution
|
|
24
|
+
- Updated browser viewport to use 1.25x device scale factor for improved rendering on high-DPI displays
|
|
25
|
+
- Modified device pixel ratio detection to respect actual screen capabilities instead of forcing 1x ratio
|
|
26
|
+
- Updated system prompt guidance to state assumptions and proceed without asking for confirmation, reducing unnecessary round-trips
|
|
27
|
+
- Tightened `ask` tool conditions to require multiple approaches with significantly different tradeoffs before prompting user
|
|
28
|
+
- Strengthened `ask` tool guidance to default to action and only ask when genuinely blocked by decisions with materially different outcomes
|
|
29
|
+
- Changed refactor workflow to automatically remove now-unused elements and note removals instead of asking for confirmation
|
|
30
|
+
- Enforced exclusive concurrency mode for all file-modifying tools (edit, write, bash, python, ssh, todo-write) to prevent concurrent execution conflicts
|
|
31
|
+
- Updated `ask` tool guidance to prioritize proactive problem-solving and default to action, asking only when truly blocked by decisions that materially change scope or behavior
|
|
32
|
+
- Changed Python kernel initialization to require shared gateway mode; local gateway startup has been removed
|
|
33
|
+
- Changed shared gateway error handling to retry on server errors (5xx status codes) before failing
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Fixed glob search returning no results when all files are ignored by gitignore by automatically retrying without gitignore filtering
|
|
38
|
+
|
|
39
|
+
## [10.3.2] - 2026-02-03
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- Added `renderCall` and `renderResult` methods to MCP tools for structured TUI display of tool calls and results
|
|
43
|
+
- Added new `mcp/render.ts` module providing JSON tree rendering for MCP tool output with collapsible/expandable views
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Updated `renderResult` signature in custom tools and extensions to accept optional `args` parameter for context-aware rendering
|
|
48
|
+
- Changed environment variable from `ENV_AGENT_DIR` constant to hardcoded `OMP_CODING_AGENT_DIR` string in config and CLI help text
|
|
49
|
+
- Fixed method binding in extension and hook tool wrappers to preserve `this` context for `renderCall` and `renderResult` methods
|
|
50
|
+
|
|
5
51
|
## [10.3.1] - 2026-02-03
|
|
6
52
|
### Fixed
|
|
7
53
|
|
package/docs/config-usage.md
CHANGED
|
@@ -8,7 +8,7 @@ This document shows how each file uses the config module and what subpaths they
|
|
|
8
8
|
┌─────────────────────────────────────────────────────────────────────────────────┐
|
|
9
9
|
│ config.ts exports │
|
|
10
10
|
├─────────────────────────────────────────────────────────────────────────────────┤
|
|
11
|
-
│ Constants: APP_NAME, CONFIG_DIR_NAME, VERSION
|
|
11
|
+
│ Constants: APP_NAME, CONFIG_DIR_NAME, VERSION │
|
|
12
12
|
│ Single paths: getAgentDir, getAuthPath, getModelsPath, getCommandsDir, ... │
|
|
13
13
|
│ Multi-config: getConfigDirs, getConfigDirPaths, findConfigFile, │
|
|
14
14
|
│ readConfigFile, findNearestProjectConfigDir, ... │
|
|
@@ -19,51 +19,51 @@ This document shows how each file uses the config module and what subpaths they
|
|
|
19
19
|
|
|
20
20
|
### 1. Display/Branding Only (no file I/O)
|
|
21
21
|
|
|
22
|
-
| File
|
|
23
|
-
|
|
24
|
-
| `cli/args.ts`
|
|
25
|
-
| `cli/plugin-cli.ts`
|
|
26
|
-
| `cli/update-cli.ts`
|
|
27
|
-
| `core/export-html/index.ts`
|
|
28
|
-
| `modes/interactive/components/welcome.ts` | `APP_NAME`
|
|
29
|
-
| `utils/tools-manager.ts`
|
|
22
|
+
| File | Imports | Purpose |
|
|
23
|
+
| ----------------------------------------- | ----------------------------- | ------------------------ |
|
|
24
|
+
| `cli/args.ts` | `APP_NAME`, `CONFIG_DIR_NAME` | Help text, env var names |
|
|
25
|
+
| `cli/plugin-cli.ts` | `APP_NAME` | Command output |
|
|
26
|
+
| `cli/update-cli.ts` | `APP_NAME`, `VERSION` | Update messages |
|
|
27
|
+
| `core/export-html/index.ts` | `APP_NAME` | HTML export title |
|
|
28
|
+
| `modes/interactive/components/welcome.ts` | `APP_NAME` | Welcome banner |
|
|
29
|
+
| `utils/tools-manager.ts` | `APP_NAME` | Tool download messages |
|
|
30
30
|
|
|
31
31
|
### 2. Single Fixed Paths (user-level only)
|
|
32
32
|
|
|
33
|
-
| File
|
|
34
|
-
|
|
35
|
-
| `core/logger.ts`
|
|
36
|
-
| `core/agent-session.ts`
|
|
37
|
-
| `core/session-manager.ts`
|
|
38
|
-
| `modes/interactive/theme/theme.ts`
|
|
39
|
-
| `modes/interactive/interactive-mode.ts` | `getAuthPath`, `getDebugLogPath`
|
|
40
|
-
| `utils/changelog.ts`
|
|
41
|
-
| `core/system-prompt.ts`
|
|
42
|
-
| `migrations.ts`
|
|
43
|
-
| `core/plugins/installer.ts`
|
|
44
|
-
| `core/plugins/paths.ts`
|
|
33
|
+
| File | Imports | Path | Purpose |
|
|
34
|
+
| --------------------------------------- | ---------------------------------------------------------------- | -------------------------- | ---------------------- |
|
|
35
|
+
| `core/logger.ts` | `CONFIG_DIR_NAME` | `~/.omp/logs/` | Log file directory |
|
|
36
|
+
| `core/agent-session.ts` | `getAuthPath` | `~/.omp/agent/auth.json` | Error messages |
|
|
37
|
+
| `core/session-manager.ts` | `getAgentDir` | `~/.omp/agent/sessions/` | Session storage |
|
|
38
|
+
| `modes/interactive/theme/theme.ts` | `getCustomThemesDir` | `~/.omp/agent/themes/` | Custom themes |
|
|
39
|
+
| `modes/interactive/interactive-mode.ts` | `getAuthPath`, `getDebugLogPath` | auth.json, debug log | Status messages |
|
|
40
|
+
| `utils/changelog.ts` | `getChangelogPath` | Package CHANGELOG.md | Re-exports |
|
|
41
|
+
| `core/system-prompt.ts` | `getAgentDir`, `getDocsPath`, `getExamplesPath`, `getReadmePath` | Package assets + AGENTS.md | System prompt building |
|
|
42
|
+
| `migrations.ts` | `getAgentDir` | `~/.omp/agent/` | Auth/session migration |
|
|
43
|
+
| `core/plugins/installer.ts` | `getAgentDir` | `~/.omp/agent/` | Plugin installation |
|
|
44
|
+
| `core/plugins/paths.ts` | `CONFIG_DIR_NAME` | `~/.omp/plugins/` | Plugin directories |
|
|
45
45
|
|
|
46
46
|
### 3. Multi-Config Discovery (with fallbacks)
|
|
47
47
|
|
|
48
48
|
These use the new helpers to check `.omp`, `.pi`, `.claude` directories:
|
|
49
49
|
|
|
50
|
-
| File
|
|
51
|
-
|
|
52
|
-
| `main.ts`
|
|
53
|
-
| `core/sdk.ts`
|
|
54
|
-
| `core/settings-manager.ts`
|
|
55
|
-
| `core/skills.ts`
|
|
56
|
-
| `core/slash-commands.ts`
|
|
57
|
-
| `core/hooks/loader.ts`
|
|
58
|
-
| `core/custom-tools/loader.ts`
|
|
59
|
-
| `core/custom-commands/loader.ts`
|
|
60
|
-
| `core/plugins/paths.ts`
|
|
61
|
-
| `core/mcp/config.ts`
|
|
62
|
-
| `core/tools/lsp/config.ts`
|
|
63
|
-
| `core/tools/task/commands.ts`
|
|
64
|
-
| `core/tools/task/discovery.ts`
|
|
65
|
-
| `core/tools/task/model-resolver.ts` | `readConfigFile`
|
|
66
|
-
| `core/tools/web-search/auth.ts`
|
|
50
|
+
| File | Helper Used | Subpath(s) | Levels |
|
|
51
|
+
| ----------------------------------- | ------------------------------------------------------ | ------------------------------------ | ------------ |
|
|
52
|
+
| `main.ts` | `findConfigFile` | `SYSTEM.md` | project |
|
|
53
|
+
| `core/sdk.ts` | `getConfigDirPaths` | `auth.json`, `models.json` | user |
|
|
54
|
+
| `core/settings-manager.ts` | `readConfigFile` | `settings.json` | user+project |
|
|
55
|
+
| `core/skills.ts` | `getConfigDirPaths` | `skills/` | user+project |
|
|
56
|
+
| `core/slash-commands.ts` | `getConfigDirPaths` | `commands/` | project |
|
|
57
|
+
| `core/hooks/loader.ts` | `getConfigDirPaths` | `hooks/` | project |
|
|
58
|
+
| `core/custom-tools/loader.ts` | `getConfigDirPaths` | `tools/` | project |
|
|
59
|
+
| `core/custom-commands/loader.ts` | `getConfigDirPaths` | `commands/` | project |
|
|
60
|
+
| `core/plugins/paths.ts` | `getConfigDirPaths` | `plugin-overrides.json` | project |
|
|
61
|
+
| `core/mcp/config.ts` | `getConfigDirPaths` | `mcp.json` | user+project |
|
|
62
|
+
| `core/tools/lsp/config.ts` | `getConfigDirPaths` | `lsp.json`, `.lsp.json` | user+project |
|
|
63
|
+
| `core/tools/task/commands.ts` | `getConfigDirPaths`, `findAllNearestProjectConfigDirs` | `commands/` | user+project |
|
|
64
|
+
| `core/tools/task/discovery.ts` | `getConfigDirs`, `findAllNearestProjectConfigDirs` | `agents/` | user+project |
|
|
65
|
+
| `core/tools/task/model-resolver.ts` | `readConfigFile` | `settings.json` | user |
|
|
66
|
+
| `core/tools/web-search/auth.ts` | `getConfigDirPaths` | `` (root for models.json, auth.json) | user |
|
|
67
67
|
|
|
68
68
|
## Subpath Summary
|
|
69
69
|
|
|
@@ -107,7 +107,7 @@ Special paths (not under agent/):
|
|
|
107
107
|
|
|
108
108
|
These files construct paths manually because they only use the primary config dir:
|
|
109
109
|
|
|
110
|
-
| File
|
|
111
|
-
|
|
112
|
-
| `core/logger.ts`
|
|
110
|
+
| File | Current Approach | Reason |
|
|
111
|
+
| ----------------------- | --------------------------------- | --------------------------------------------------- |
|
|
112
|
+
| `core/logger.ts` | `CONFIG_DIR_NAME` for logs dir | Logs only written to primary (~/.omp/logs/) |
|
|
113
113
|
| `core/plugins/paths.ts` | `CONFIG_DIR_NAME` for plugins dir | Plugins only installed in primary (~/.omp/plugins/) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.0",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -79,31 +79,36 @@
|
|
|
79
79
|
"test": "bun test"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"@
|
|
83
|
-
"@oh-my-pi/
|
|
84
|
-
"@oh-my-pi/pi-
|
|
85
|
-
"@oh-my-pi/pi-
|
|
86
|
-
"@oh-my-pi/pi-
|
|
87
|
-
"@oh-my-pi/pi-
|
|
88
|
-
"@
|
|
82
|
+
"@mozilla/readability": "0.6.0",
|
|
83
|
+
"@oh-my-pi/omp-stats": "10.5.0",
|
|
84
|
+
"@oh-my-pi/pi-agent-core": "10.5.0",
|
|
85
|
+
"@oh-my-pi/pi-ai": "10.5.0",
|
|
86
|
+
"@oh-my-pi/pi-natives": "10.5.0",
|
|
87
|
+
"@oh-my-pi/pi-tui": "10.5.0",
|
|
88
|
+
"@oh-my-pi/pi-utils": "10.5.0",
|
|
89
|
+
"@openai/agents": "^0.4.5",
|
|
89
90
|
"@sinclair/typebox": "^0.34.48",
|
|
90
91
|
"ajv": "^8.17.1",
|
|
91
92
|
"chalk": "^5.6.2",
|
|
92
93
|
"diff": "^8.0.3",
|
|
93
94
|
"file-type": "^21.3.0",
|
|
94
|
-
"glob": "^13.0.
|
|
95
|
+
"glob": "^13.0.1",
|
|
95
96
|
"handlebars": "^4.7.8",
|
|
96
97
|
"ignore": "^7.0.5",
|
|
98
|
+
"jsdom": "28.0.0",
|
|
97
99
|
"marked": "^17.0.1",
|
|
98
100
|
"nanoid": "^5.1.6",
|
|
99
101
|
"node-html-parser": "^7.0.2",
|
|
102
|
+
"puppeteer": "^24.36.1",
|
|
100
103
|
"smol-toml": "^1.6.0",
|
|
101
104
|
"zod": "^4.3.6"
|
|
102
105
|
},
|
|
103
106
|
"devDependencies": {
|
|
104
|
-
"@types/diff": "^
|
|
107
|
+
"@types/diff": "^7.0.2",
|
|
108
|
+
"@types/jsdom": "27.0.0",
|
|
109
|
+
"bun-types": "^1.3.8",
|
|
105
110
|
"@types/ms": "^2.1.0",
|
|
106
|
-
"@types/
|
|
111
|
+
"@types/bun": "^1.3.8",
|
|
107
112
|
"ms": "^2.1.3"
|
|
108
113
|
},
|
|
109
114
|
"keywords": [
|
package/src/capability/index.ts
CHANGED
|
@@ -8,6 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import * as os from "node:os";
|
|
10
10
|
import * as path from "node:path";
|
|
11
|
+
|
|
12
|
+
/** Conditional startup debug prints (stderr) when OMP_DEBUG_STARTUP is set */
|
|
13
|
+
const debugStartup = process.env.OMP_DEBUG_STARTUP
|
|
14
|
+
? (stage: string) => process.stderr.write(`[startup] ${stage}\n`)
|
|
15
|
+
: () => {};
|
|
16
|
+
|
|
11
17
|
import type { Settings } from "../config/settings";
|
|
12
18
|
import { clearCache as clearFsCache, cacheStats as fsCacheStats, invalidate as invalidateFs } from "./fs";
|
|
13
19
|
import type {
|
|
@@ -109,9 +115,12 @@ async function loadImpl<T>(
|
|
|
109
115
|
const results = await Promise.all(
|
|
110
116
|
providers.map(async provider => {
|
|
111
117
|
try {
|
|
118
|
+
debugStartup(`capability:${capability.id}:${provider.id}:start`);
|
|
112
119
|
const result = await provider.load(ctx);
|
|
120
|
+
debugStartup(`capability:${capability.id}:${provider.id}:done`);
|
|
113
121
|
return { provider, result };
|
|
114
122
|
} catch (error) {
|
|
123
|
+
debugStartup(`capability:${capability.id}:${provider.id}:error`);
|
|
115
124
|
return { provider, error };
|
|
116
125
|
}
|
|
117
126
|
}),
|
package/src/cli/args.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
5
5
|
import chalk from "chalk";
|
|
6
|
-
import { APP_NAME, CONFIG_DIR_NAME
|
|
6
|
+
import { APP_NAME, CONFIG_DIR_NAME } from "../config";
|
|
7
7
|
import { BUILTIN_TOOLS } from "../tools";
|
|
8
8
|
|
|
9
9
|
export type Mode = "text" | "json" | "rpc";
|
|
@@ -286,7 +286,7 @@ ${chalk.bold("Environment Variables:")}
|
|
|
286
286
|
PERPLEXITY_API_KEY - Perplexity search API key
|
|
287
287
|
|
|
288
288
|
${chalk.dim("# Configuration")}
|
|
289
|
-
|
|
289
|
+
OMP_CODING_AGENT_DIR - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent)
|
|
290
290
|
|
|
291
291
|
${chalk.bold("Available Tools (all enabled by default):")}
|
|
292
292
|
read - Read file contents
|
package/src/cli/update-cli.ts
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
import { execSync, spawnSync } from "node:child_process";
|
|
8
8
|
import * as fs from "node:fs";
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
-
import { Readable } from "node:stream";
|
|
11
10
|
import { pipeline } from "node:stream/promises";
|
|
12
11
|
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
13
12
|
import chalk from "chalk";
|
|
@@ -200,8 +199,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
|
200
199
|
}
|
|
201
200
|
|
|
202
201
|
const fileStream = fs.createWriteStream(tempPath, { mode: 0o755 });
|
|
203
|
-
|
|
204
|
-
await pipeline(nodeStream, fileStream);
|
|
202
|
+
await pipeline(response.body, fileStream);
|
|
205
203
|
|
|
206
204
|
// Download native addon
|
|
207
205
|
console.log(chalk.dim(`Downloading ${nativeAddonName}...`));
|
|
@@ -212,8 +210,7 @@ async function updateViaBinary(release: ReleaseInfo): Promise<void> {
|
|
|
212
210
|
}
|
|
213
211
|
|
|
214
212
|
const nativeFileStream = fs.createWriteStream(nativeTempPath, { mode: 0o755 });
|
|
215
|
-
|
|
216
|
-
await pipeline(nativeNodeStream, nativeFileStream);
|
|
213
|
+
await pipeline(nativeResponse.body, nativeFileStream);
|
|
217
214
|
|
|
218
215
|
// Replace current binary
|
|
219
216
|
console.log(chalk.dim("Installing update..."));
|
|
@@ -358,6 +358,24 @@ export const SETTINGS_SCHEMA = {
|
|
|
358
358
|
description: "Enable the calculator tool for basic calculations",
|
|
359
359
|
},
|
|
360
360
|
},
|
|
361
|
+
"browser.enabled": {
|
|
362
|
+
type: "boolean",
|
|
363
|
+
default: false,
|
|
364
|
+
ui: {
|
|
365
|
+
tab: "tools",
|
|
366
|
+
label: "Enable Browser",
|
|
367
|
+
description: "Enable the browser tool (Ulixee Hero)",
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
"browser.headless": {
|
|
371
|
+
type: "boolean",
|
|
372
|
+
default: true,
|
|
373
|
+
ui: {
|
|
374
|
+
tab: "tools",
|
|
375
|
+
label: "Browser headless",
|
|
376
|
+
description: "Launch browser in headless mode (disable to show browser UI)",
|
|
377
|
+
},
|
|
378
|
+
},
|
|
361
379
|
|
|
362
380
|
// ─────────────────────────────────────────────────────────────────────────
|
|
363
381
|
// Startup settings
|
package/src/config.ts
CHANGED
|
@@ -22,9 +22,6 @@ const priorityList = [
|
|
|
22
22
|
{ dir: ".gemini" },
|
|
23
23
|
];
|
|
24
24
|
|
|
25
|
-
// e.g., OMP_CODING_AGENT_DIR
|
|
26
|
-
export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;
|
|
27
|
-
|
|
28
25
|
// =============================================================================
|
|
29
26
|
// Package Directory (for optional external docs/examples)
|
|
30
27
|
// =============================================================================
|
|
@@ -56,7 +53,7 @@ export function getChangelogPath(): string {
|
|
|
56
53
|
|
|
57
54
|
/** Get the agent config directory (e.g., ~/.omp/agent/) */
|
|
58
55
|
export function getAgentDir(): string {
|
|
59
|
-
return process.env
|
|
56
|
+
return process.env.OMP_CODING_AGENT_DIR || path.join(os.homedir(), CONFIG_DIR_NAME, "agent");
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
/** Get path to user's custom themes directory */
|
|
@@ -147,7 +147,12 @@ export interface CustomTool<TParams extends TSchema = TSchema, TDetails = any> {
|
|
|
147
147
|
renderCall?: (args: Static<TParams>, theme: Theme) => Component;
|
|
148
148
|
|
|
149
149
|
/** Custom rendering for tool result display - return a Component */
|
|
150
|
-
renderResult?: (
|
|
150
|
+
renderResult?: (
|
|
151
|
+
result: CustomToolResult<TDetails>,
|
|
152
|
+
options: RenderResultOptions,
|
|
153
|
+
theme: Theme,
|
|
154
|
+
args?: Static<TParams>,
|
|
155
|
+
) => Component;
|
|
151
156
|
}
|
|
152
157
|
|
|
153
158
|
/** Factory function that creates a custom tool or array of tools */
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CustomToolAdapter wraps CustomTool instances into AgentTool for use with the agent.
|
|
3
3
|
*/
|
|
4
|
-
import type { AgentTool,
|
|
5
|
-
import type { Component } from "@oh-my-pi/pi-tui";
|
|
4
|
+
import type { AgentTool, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
6
5
|
import type { Static, TSchema } from "@sinclair/typebox";
|
|
7
6
|
import type { Theme } from "../../modes/theme/theme";
|
|
7
|
+
import { applyToolProxy } from "../tool-proxy";
|
|
8
8
|
import type { CustomTool, CustomToolContext, LoadedCustomTool } from "./types";
|
|
9
9
|
|
|
10
10
|
export class CustomToolAdapter<TParams extends TSchema = TSchema, TDetails = any, TTheme extends Theme = Theme>
|
|
11
11
|
implements AgentTool<TParams, TDetails, TTheme>
|
|
12
12
|
{
|
|
13
|
+
declare name: string;
|
|
14
|
+
declare label: string;
|
|
15
|
+
declare description: string;
|
|
16
|
+
declare parameters: TParams;
|
|
17
|
+
|
|
13
18
|
constructor(
|
|
14
19
|
private tool: CustomTool<TParams, TDetails>,
|
|
15
20
|
private getContext: () => CustomToolContext,
|
|
16
|
-
) {
|
|
17
|
-
|
|
18
|
-
get name() {
|
|
19
|
-
return this.tool.name;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get label() {
|
|
23
|
-
return this.tool.label;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
get description() {
|
|
27
|
-
return this.tool.description;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
get parameters() {
|
|
31
|
-
return this.tool.parameters;
|
|
21
|
+
) {
|
|
22
|
+
applyToolProxy(tool, this);
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
execute(
|
|
@@ -41,16 +32,6 @@ export class CustomToolAdapter<TParams extends TSchema = TSchema, TDetails = any
|
|
|
41
32
|
return this.tool.execute(toolCallId, params, onUpdate, context ?? this.getContext(), signal);
|
|
42
33
|
}
|
|
43
34
|
|
|
44
|
-
/** Optional custom rendering for tool call display (returns UI component) */
|
|
45
|
-
renderCall(args: Static<TParams>, theme: TTheme): Component | undefined {
|
|
46
|
-
return this.tool.renderCall?.(args, theme);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Optional custom rendering for tool result display (returns UI component) */
|
|
50
|
-
renderResult(result: AgentToolResult<TDetails>, options: RenderResultOptions, theme: TTheme): Component | undefined {
|
|
51
|
-
return this.tool.renderResult?.(result, options, theme);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
35
|
/**
|
|
55
36
|
* Backward-compatible export of factory function for existing callers.
|
|
56
37
|
* Prefer CustomToolAdapter constructor directly.
|
|
@@ -255,7 +255,12 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
255
255
|
renderCall?: (args: Static<TParams>, theme: Theme) => Component;
|
|
256
256
|
|
|
257
257
|
/** Custom rendering for tool result display */
|
|
258
|
-
renderResult?: (
|
|
258
|
+
renderResult?: (
|
|
259
|
+
result: AgentToolResult<TDetails>,
|
|
260
|
+
options: ToolRenderResultOptions,
|
|
261
|
+
theme: Theme,
|
|
262
|
+
args?: Static<TParams>,
|
|
263
|
+
) => Component;
|
|
259
264
|
}
|
|
260
265
|
|
|
261
266
|
// ============================================================================
|
|
@@ -5,6 +5,7 @@ import type { AgentTool, AgentToolContext, AgentToolUpdateCallback } from "@oh-m
|
|
|
5
5
|
import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
|
|
6
6
|
import type { Static, TSchema } from "@sinclair/typebox";
|
|
7
7
|
import type { Theme } from "../../modes/theme/theme";
|
|
8
|
+
import { applyToolProxy } from "../tool-proxy";
|
|
8
9
|
import type { ExtensionRunner } from "./runner";
|
|
9
10
|
import type { RegisteredTool, ToolCallEventResult, ToolResultEventResult } from "./types";
|
|
10
11
|
|
|
@@ -12,20 +13,16 @@ import type { RegisteredTool, ToolCallEventResult, ToolResultEventResult } from
|
|
|
12
13
|
* Adapts a RegisteredTool into an AgentTool.
|
|
13
14
|
*/
|
|
14
15
|
export class RegisteredToolAdapter implements AgentTool<any, any, any> {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
declare name: string;
|
|
17
|
+
declare description: string;
|
|
18
|
+
declare parameters: any;
|
|
19
|
+
declare label: string;
|
|
19
20
|
|
|
20
21
|
constructor(
|
|
21
22
|
private registeredTool: RegisteredTool,
|
|
22
23
|
private runner: ExtensionRunner,
|
|
23
24
|
) {
|
|
24
|
-
|
|
25
|
-
this.name = definition.name;
|
|
26
|
-
this.label = definition.label || "";
|
|
27
|
-
this.description = definition.description;
|
|
28
|
-
this.parameters = definition.parameters;
|
|
25
|
+
applyToolProxy(registeredTool.definition, this);
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
async execute(
|
|
@@ -42,11 +39,12 @@ export class RegisteredToolAdapter implements AgentTool<any, any, any> {
|
|
|
42
39
|
return this.registeredTool.definition.renderCall?.(args, theme as Theme);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
renderResult?(result: any, options: any, theme: any) {
|
|
42
|
+
renderResult?(result: any, options: any, theme: any, args?: any) {
|
|
46
43
|
return this.registeredTool.definition.renderResult?.(
|
|
47
44
|
result,
|
|
48
45
|
{ expanded: options.expanded, isPartial: options.isPartial, spinnerFrame: options.spinnerFrame },
|
|
49
46
|
theme as Theme,
|
|
47
|
+
args,
|
|
50
48
|
);
|
|
51
49
|
}
|
|
52
50
|
}
|
|
@@ -73,35 +71,25 @@ export function wrapRegisteredTools(registeredTools: RegisteredTool[], runner: E
|
|
|
73
71
|
export class ExtensionToolWrapper<TParameters extends TSchema = TSchema, TDetails = unknown>
|
|
74
72
|
implements AgentTool<TParameters, TDetails>
|
|
75
73
|
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
declare name: string;
|
|
75
|
+
declare description: string;
|
|
76
|
+
declare parameters: TParameters;
|
|
77
|
+
declare label: string;
|
|
80
78
|
|
|
81
79
|
constructor(
|
|
82
80
|
private tool: AgentTool<TParameters, TDetails>,
|
|
83
81
|
private runner: ExtensionRunner,
|
|
84
82
|
) {
|
|
85
|
-
this
|
|
86
|
-
this.renderResult = tool.renderResult;
|
|
87
|
-
this.mergeCallAndResult = (tool as { mergeCallAndResult?: boolean }).mergeCallAndResult;
|
|
88
|
-
this.inline = (tool as { inline?: boolean }).inline;
|
|
83
|
+
applyToolProxy(tool, this);
|
|
89
84
|
}
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
get description(): string {
|
|
100
|
-
return this.tool.description;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
get parameters(): TParameters {
|
|
104
|
-
return this.tool.parameters;
|
|
86
|
+
/**
|
|
87
|
+
* Forward browser mode changes when available.
|
|
88
|
+
*/
|
|
89
|
+
restartForModeChange(): Promise<void> {
|
|
90
|
+
const target = this.tool as { restartForModeChange?: () => Promise<void> };
|
|
91
|
+
if (!target.restartForModeChange) return Promise.resolve();
|
|
92
|
+
return target.restartForModeChange();
|
|
105
93
|
}
|
|
106
94
|
|
|
107
95
|
async execute(
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { AgentTool, AgentToolContext, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
5
5
|
import type { Static, TSchema } from "@sinclair/typebox";
|
|
6
|
+
import { applyToolProxy } from "../tool-proxy";
|
|
6
7
|
import type { HookRunner } from "./runner";
|
|
7
8
|
import type { ToolCallEventResult, ToolResultEventResult } from "./types";
|
|
8
9
|
|
|
@@ -17,27 +18,16 @@ import type { ToolCallEventResult, ToolResultEventResult } from "./types";
|
|
|
17
18
|
export class HookToolWrapper<TParameters extends TSchema = TSchema, TDetails = unknown>
|
|
18
19
|
implements AgentTool<TParameters, TDetails>
|
|
19
20
|
{
|
|
20
|
-
name: string;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
renderCall?: AgentTool<TParameters, TDetails>["renderCall"];
|
|
25
|
-
renderResult?: AgentTool<TParameters, TDetails>["renderResult"];
|
|
26
|
-
mergeCallAndResult?: boolean;
|
|
27
|
-
inline?: boolean;
|
|
21
|
+
declare name: string;
|
|
22
|
+
declare description: string;
|
|
23
|
+
declare parameters: TParameters;
|
|
24
|
+
declare label: string;
|
|
28
25
|
|
|
29
26
|
constructor(
|
|
30
27
|
private tool: AgentTool<TParameters, TDetails>,
|
|
31
28
|
private hookRunner: HookRunner,
|
|
32
29
|
) {
|
|
33
|
-
this
|
|
34
|
-
this.label = tool.label ?? "";
|
|
35
|
-
this.description = tool.description;
|
|
36
|
-
this.parameters = tool.parameters;
|
|
37
|
-
this.renderCall = tool.renderCall;
|
|
38
|
-
this.renderResult = tool.renderResult;
|
|
39
|
-
this.mergeCallAndResult = (tool as { mergeCallAndResult?: boolean }).mergeCallAndResult;
|
|
40
|
-
this.inline = (tool as { inline?: boolean }).inline;
|
|
30
|
+
applyToolProxy(tool, this);
|
|
41
31
|
}
|
|
42
32
|
|
|
43
33
|
async execute(
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines lazy proxy properties on a wrapper so it forwards to the underlying tool.
|
|
3
|
+
*/
|
|
4
|
+
export function applyToolProxy<TTool extends object>(tool: TTool, wrapper: object): void {
|
|
5
|
+
const visited = new Set<PropertyKey>();
|
|
6
|
+
let current: object | null = tool;
|
|
7
|
+
|
|
8
|
+
while (current && current !== Object.prototype) {
|
|
9
|
+
for (const key of Reflect.ownKeys(current)) {
|
|
10
|
+
if (key === "constructor" || visited.has(key) || key in wrapper) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
visited.add(key);
|
|
14
|
+
Object.defineProperty(wrapper, key, {
|
|
15
|
+
get() {
|
|
16
|
+
const value = (tool as Record<PropertyKey, unknown>)[key];
|
|
17
|
+
return typeof value === "function" ? value.bind(tool) : value;
|
|
18
|
+
},
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
current = Object.getPrototypeOf(current);
|
|
24
|
+
}
|
|
25
|
+
}
|