@herbertgao/pi-extensions 2026.8.1 → 2026.8.2
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/README.md +5 -2
- package/node_modules/@czottmann/pi-automode/README.md +16 -2
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +35 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +18 -9
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +6 -2
- package/node_modules/@czottmann/pi-automode/examples/automode.local.json +6 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +11 -7
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +100 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +32 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +78 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +16 -4
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +23 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +22 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +18 -2
- package/node_modules/@czottmann/pi-automode/package.json +4 -4
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +23 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +99 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +30 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +16 -0
- package/node_modules/@dietrichgebert/ponytail/AGENTS.md +32 -0
- package/node_modules/@dietrichgebert/ponytail/LICENSE +21 -0
- package/node_modules/@dietrichgebert/ponytail/README.es.md +298 -0
- package/node_modules/@dietrichgebert/ponytail/README.ko.md +315 -0
- package/node_modules/@dietrichgebert/ponytail/README.md +351 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +21 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +62 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +115 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +44 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +21 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +96 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +169 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +98 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +130 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +85 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.ps1 +24 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.sh +18 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +77 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +26 -0
- package/node_modules/@dietrichgebert/ponytail/package.json +47 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +211 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/package.json +8 -0
- package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +60 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +120 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +41 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +44 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +50 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +71 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +57 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -3
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +10 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary.ts +6 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +24 -83
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/markdown-enhance.ts +119 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +73 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-hover.ts +130 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-interaction.ts +65 -542
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-layout.ts +160 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-packets.ts +143 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-scroll.ts +184 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/diff-renderer.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-grouping.ts +9 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +91 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/agent-summary.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +1 -0
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
- package/node_modules/@herbertgao/pi-stash/README.md +9 -9
- package/node_modules/@herbertgao/pi-stash/package.json +1 -1
- package/node_modules/@herbertgao/pi-stash/src/index.ts +2 -1
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +14 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +6 -2
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +85 -11
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +28 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +12 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +2 -0
- package/node_modules/@narumitw/pi-btw/LICENSE +21 -0
- package/node_modules/@narumitw/pi-btw/README.md +210 -0
- package/node_modules/@narumitw/pi-btw/package.json +53 -0
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +632 -0
- package/node_modules/@narumitw/pi-btw/src/btw.ts +996 -0
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +339 -0
- package/node_modules/@narumitw/pi-btw/src/index.ts +1 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +296 -0
- package/node_modules/@narumitw/pi-btw/src/settings.ts +237 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +238 -0
- package/node_modules/@narumitw/pi-btw/src/text.ts +10 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +620 -0
- package/node_modules/@pi-plugins/fast-mode/LICENSE +21 -0
- package/node_modules/@pi-plugins/fast-mode/README.md +92 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts +6 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +2026 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/package.json +73 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +59 -0
- package/node_modules/pi-mcp-adapter/README.md +62 -13
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +377 -0
- package/node_modules/pi-mcp-adapter/commands.ts +9 -7
- package/node_modules/pi-mcp-adapter/config.ts +110 -49
- package/node_modules/pi-mcp-adapter/direct-tools.ts +34 -19
- package/node_modules/pi-mcp-adapter/elicitation-handler.ts +37 -36
- package/node_modules/pi-mcp-adapter/errors.ts +21 -17
- package/node_modules/pi-mcp-adapter/host-html-template.ts +13 -7
- package/node_modules/pi-mcp-adapter/index.ts +37 -14
- package/node_modules/pi-mcp-adapter/init.ts +9 -7
- package/node_modules/pi-mcp-adapter/json-schema-validator.ts +2 -2
- package/node_modules/pi-mcp-adapter/lifecycle.ts +8 -8
- package/node_modules/pi-mcp-adapter/logger.ts +1 -1
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +36 -22
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +120 -2
- package/node_modules/pi-mcp-adapter/mcp-code.ts +13 -11
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +19 -13
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +15 -11
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +34 -15
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +131 -34
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +2 -2
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +7 -4
- package/node_modules/pi-mcp-adapter/mcp-trace.ts +59 -64
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +34 -26
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +6 -4
- package/node_modules/pi-mcp-adapter/oauth-handler.ts +1 -1
- package/node_modules/pi-mcp-adapter/onboarding-state.ts +19 -11
- package/node_modules/pi-mcp-adapter/package.json +13 -8
- package/node_modules/pi-mcp-adapter/panel-keys.ts +20 -4
- package/node_modules/pi-mcp-adapter/prompts.ts +2 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +48 -11
- package/node_modules/pi-mcp-adapter/sampling-handler.ts +22 -15
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -1
- package/node_modules/pi-mcp-adapter/server-manager.ts +165 -113
- package/node_modules/pi-mcp-adapter/session-recovery.ts +11 -12
- package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +3 -3
- package/node_modules/pi-mcp-adapter/state.ts +3 -1
- package/node_modules/pi-mcp-adapter/tool-approval.ts +67 -4
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -5
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +14 -2
- package/node_modules/pi-mcp-adapter/ts-shape.ts +9 -2
- package/node_modules/pi-mcp-adapter/types.ts +109 -22
- package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +40 -0
- package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +28 -19
- package/node_modules/pi-mcp-adapter/ui-server.ts +90 -58
- package/node_modules/pi-mcp-adapter/ui-session.ts +16 -14
- package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +4 -4
- package/node_modules/pi-mcp-adapter/utils.ts +23 -9
- package/package.json +22 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mcp-adapter",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.21.2",
|
|
4
4
|
"description": "MCP (Model Context Protocol) adapter extension for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.ts",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"pi-mcp-adapter": "cli.js"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
28
29
|
"test": "vitest run",
|
|
29
30
|
"test:watch": "vitest",
|
|
30
31
|
"test:coverage": "vitest run --coverage",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
"types.ts",
|
|
81
82
|
"ui-stream-types.ts",
|
|
82
83
|
"ui-tool-visibility.ts",
|
|
84
|
+
"ui-app-bridge-helpers.ts",
|
|
83
85
|
"config.ts",
|
|
84
86
|
"server-manager.ts",
|
|
85
87
|
"unix-socket-transport.ts",
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
"mcp-code.ts",
|
|
94
96
|
"mcp-script-worker.mjs",
|
|
95
97
|
"mcp-probe.ts",
|
|
98
|
+
"agent-plugin-loader.ts",
|
|
96
99
|
"resource-tools.ts",
|
|
97
100
|
"lifecycle.ts",
|
|
98
101
|
"mcp-status.ts",
|
|
@@ -122,8 +125,9 @@
|
|
|
122
125
|
"LICENSE"
|
|
123
126
|
],
|
|
124
127
|
"dependencies": {
|
|
128
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
129
|
+
"@modelcontextprotocol/core": "2.0.0",
|
|
125
130
|
"@modelcontextprotocol/ext-apps": "^1.2.2",
|
|
126
|
-
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
127
131
|
"@napi-rs/keyring": "^1.3.0",
|
|
128
132
|
"ajv": "^8.17.1",
|
|
129
133
|
"ajv-formats": "^3.0.1",
|
|
@@ -135,7 +139,7 @@
|
|
|
135
139
|
"zod": "^3.25.0 || ^4.0.0"
|
|
136
140
|
},
|
|
137
141
|
"peerDependencies": {
|
|
138
|
-
"@earendil-works/pi-ai": "
|
|
142
|
+
"@earendil-works/pi-ai": "^0.84.1",
|
|
139
143
|
"@earendil-works/pi-tui": "*",
|
|
140
144
|
"typebox": "*",
|
|
141
145
|
"zod": "^3.25.0 || ^4.0.0"
|
|
@@ -152,16 +156,17 @@
|
|
|
152
156
|
}
|
|
153
157
|
},
|
|
154
158
|
"devDependencies": {
|
|
155
|
-
"@earendil-works/pi-ai": "0.
|
|
156
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
157
|
-
"@earendil-works/pi-tui": "0.
|
|
159
|
+
"@earendil-works/pi-ai": "0.84.1",
|
|
160
|
+
"@earendil-works/pi-coding-agent": "0.84.1",
|
|
161
|
+
"@earendil-works/pi-tui": "0.84.1",
|
|
158
162
|
"@modelcontextprotocol/conformance": "0.1.16",
|
|
159
163
|
"@types/bun": "^1.0.0",
|
|
160
|
-
"@types/
|
|
164
|
+
"@types/cross-spawn": "6.0.6",
|
|
165
|
+
"@types/node": "20.19.43",
|
|
161
166
|
"@types/open": "^6.2.1",
|
|
162
167
|
"tsx": "^4.21.0",
|
|
163
168
|
"typebox": "1.3.3",
|
|
164
|
-
"typescript": "
|
|
169
|
+
"typescript": "5.9.3",
|
|
165
170
|
"vitest": "^3.0.0"
|
|
166
171
|
}
|
|
167
172
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { matchesKey } from "@earendil-works/pi-tui";
|
|
1
|
+
import { matchesKey, type KeyId } from "@earendil-works/pi-tui";
|
|
2
2
|
|
|
3
|
-
/** The
|
|
3
|
+
/** The panel keybinding ids the adapter panels resolve through pi-tui. */
|
|
4
4
|
export type PanelSelectKeybinding =
|
|
5
5
|
| "tui.select.up"
|
|
6
6
|
| "tui.select.down"
|
|
@@ -9,29 +9,45 @@ export type PanelSelectKeybinding =
|
|
|
9
9
|
/** Structural subset of pi-tui's `KeybindingsManager` (which satisfies it). */
|
|
10
10
|
export interface PanelKeybindings {
|
|
11
11
|
matches(data: string, keybinding: PanelSelectKeybinding): boolean;
|
|
12
|
+
getUserBindings?(): Record<string, KeyId | KeyId[] | undefined>;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
|
-
* Key matchers for
|
|
16
|
-
*
|
|
16
|
+
* Key matchers for panel actions: user bindings when a manager is provided,
|
|
17
|
+
* otherwise the previous hardcoded defaults.
|
|
17
18
|
*/
|
|
18
19
|
export interface PanelKeys {
|
|
19
20
|
selectUp(data: string): boolean;
|
|
20
21
|
selectDown(data: string): boolean;
|
|
21
22
|
selectConfirm(data: string): boolean;
|
|
23
|
+
save(data: string): boolean;
|
|
24
|
+
saveLabel(): string | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function configuredSaveKeys(keybindings?: PanelKeybindings): { keys: KeyId[]; configured: boolean } {
|
|
28
|
+
const explicit = keybindings?.getUserBindings?.()["mcp.panel.save"];
|
|
29
|
+
if (explicit !== undefined) return { keys: Array.isArray(explicit) ? explicit : [explicit], configured: true };
|
|
30
|
+
return { keys: [], configured: false };
|
|
22
31
|
}
|
|
23
32
|
|
|
24
33
|
export function createPanelKeys(keybindings?: PanelKeybindings): PanelKeys {
|
|
34
|
+
const saveBinding = configuredSaveKeys(keybindings);
|
|
25
35
|
if (keybindings) {
|
|
26
36
|
return {
|
|
27
37
|
selectUp: (data) => keybindings.matches(data, "tui.select.up"),
|
|
28
38
|
selectDown: (data) => keybindings.matches(data, "tui.select.down"),
|
|
29
39
|
selectConfirm: (data) => keybindings.matches(data, "tui.select.confirm"),
|
|
40
|
+
save: (data) => saveBinding.keys.length > 0
|
|
41
|
+
? saveBinding.keys.some((key) => matchesKey(data, key))
|
|
42
|
+
: !saveBinding.configured && matchesKey(data, "ctrl+s"),
|
|
43
|
+
saveLabel: () => saveBinding.keys[0] ?? (saveBinding.configured ? null : "ctrl+s"),
|
|
30
44
|
};
|
|
31
45
|
}
|
|
32
46
|
return {
|
|
33
47
|
selectUp: (data) => matchesKey(data, "up"),
|
|
34
48
|
selectDown: (data) => matchesKey(data, "down"),
|
|
35
49
|
selectConfirm: (data) => matchesKey(data, "return"),
|
|
50
|
+
save: (data) => matchesKey(data, "ctrl+s"),
|
|
51
|
+
saveLabel: () => "ctrl+s",
|
|
36
52
|
};
|
|
37
53
|
}
|
|
@@ -2,7 +2,7 @@ import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-c
|
|
|
2
2
|
import type {
|
|
3
3
|
GetPromptResult,
|
|
4
4
|
PromptMessage,
|
|
5
|
-
} from "@modelcontextprotocol/
|
|
5
|
+
} from "@modelcontextprotocol/client";
|
|
6
6
|
import type { McpExtensionState } from "./state.ts";
|
|
7
7
|
import { isServerDisabled, type McpConfig, type PromptMetadata } from "./types.ts";
|
|
8
8
|
import { formatPromptCommandName } from "./types.ts";
|
|
@@ -117,7 +117,7 @@ function findUnquotedEquals(token: string): number {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function stripQuotes(value: string): string {
|
|
120
|
-
if (value.length >= 2 && (value.startsWith('"') || value.startsWith("'")) && value.endsWith(value
|
|
120
|
+
if (value.length >= 2 && (value.startsWith('"') || value.startsWith("'")) && value.endsWith(value.charAt(0))) {
|
|
121
121
|
return value.slice(1, -1);
|
|
122
122
|
}
|
|
123
123
|
return value;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentToolResult, ToolInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { UrlElicitationRequiredError } from "@modelcontextprotocol/
|
|
2
|
+
import { UrlElicitationRequiredError, type Client } from "@modelcontextprotocol/client";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import type { McpExtensionState } from "./state.ts";
|
|
5
5
|
import type { ToolMetadata, McpContent } from "./types.ts";
|
|
@@ -20,6 +20,7 @@ import { paginate, rankSuggestions, rankToolMatches } from "./search-ranking.ts"
|
|
|
20
20
|
import { ensureToolCallApproved, isToolCallApprovalRequired } from "./tool-approval.ts";
|
|
21
21
|
|
|
22
22
|
type ProxyToolResult = AgentToolResult<Record<string, unknown>>;
|
|
23
|
+
type ClientCallToolResult = Awaited<ReturnType<Client["callTool"]>>;
|
|
23
24
|
|
|
24
25
|
const require = createRequire(import.meta.url);
|
|
25
26
|
const MAX_REGEX_SEARCH_QUERY_LENGTH = 256;
|
|
@@ -524,10 +525,28 @@ export function executeSearch(
|
|
|
524
525
|
|
|
525
526
|
const page = paginate(matches, offset, limit);
|
|
526
527
|
if (page.total === 0) {
|
|
528
|
+
const connectingServers = server
|
|
529
|
+
? state.config.mcpServers[server] && state.manager.isConnecting(server) ? [server] : []
|
|
530
|
+
: Object.keys(state.config.mcpServers)
|
|
531
|
+
.filter(name => !isServerDisabled(state.config.mcpServers[name]) && state.manager.isConnecting(name))
|
|
532
|
+
.sort((a, b) => a.localeCompare(b));
|
|
527
533
|
const msg = server ? `No tools matching "${query}" in "${server}"` : `No tools matching "${query}"`;
|
|
534
|
+
const connectingMessage = connectingServers.length === 1
|
|
535
|
+
? ` Server "${connectingServers[0]}" is still connecting; retry in a moment.`
|
|
536
|
+
: connectingServers.length > 1
|
|
537
|
+
? ` Servers ${connectingServers.map(name => `"${name}"`).join(", ")} are still connecting; retry in a moment.`
|
|
538
|
+
: "";
|
|
528
539
|
return {
|
|
529
|
-
content: [{ type: "text" as const, text: msg }],
|
|
530
|
-
details: {
|
|
540
|
+
content: [{ type: "text" as const, text: `${msg}${connectingMessage}` }],
|
|
541
|
+
details: {
|
|
542
|
+
mode: "search",
|
|
543
|
+
matches: [],
|
|
544
|
+
count: 0,
|
|
545
|
+
hasMore: false,
|
|
546
|
+
nextOffset: null,
|
|
547
|
+
query,
|
|
548
|
+
...(connectingServers.length > 0 ? { connectingServers } : {}),
|
|
549
|
+
},
|
|
531
550
|
};
|
|
532
551
|
}
|
|
533
552
|
|
|
@@ -748,6 +767,7 @@ export async function executeCall(
|
|
|
748
767
|
serverOverride?: string,
|
|
749
768
|
getPiTools?: () => ToolInfo[],
|
|
750
769
|
signal?: AbortSignal,
|
|
770
|
+
origin?: "proxy" | "script",
|
|
751
771
|
): Promise<ProxyToolResult> {
|
|
752
772
|
const ownedSignal = combineAbortSignals(state.owner?.signal, signal);
|
|
753
773
|
throwIfAborted(ownedSignal);
|
|
@@ -1033,7 +1053,14 @@ export async function executeCall(
|
|
|
1033
1053
|
return disabledCallResult(serverName, toolMeta);
|
|
1034
1054
|
}
|
|
1035
1055
|
|
|
1036
|
-
const approval = await ensureToolCallApproved(
|
|
1056
|
+
const approval = await ensureToolCallApproved(
|
|
1057
|
+
state,
|
|
1058
|
+
serverName,
|
|
1059
|
+
toolMeta,
|
|
1060
|
+
args,
|
|
1061
|
+
ownedSignal,
|
|
1062
|
+
origin ?? (toolMeta.resourceUri ? "resource" : "proxy"),
|
|
1063
|
+
);
|
|
1037
1064
|
if (approval.ok === false) {
|
|
1038
1065
|
const denied = approval.reason === "denied";
|
|
1039
1066
|
const message = denied
|
|
@@ -1086,7 +1113,12 @@ export async function executeCall(
|
|
|
1086
1113
|
|
|
1087
1114
|
if (toolMeta.resourceUri) {
|
|
1088
1115
|
const result = await withSessionRecovery(
|
|
1089
|
-
{
|
|
1116
|
+
{
|
|
1117
|
+
manager: state.manager,
|
|
1118
|
+
config: state.config,
|
|
1119
|
+
...(ownedSignal ? { signal: ownedSignal } : {}),
|
|
1120
|
+
onNeedsAuth: recoverAuthConnection,
|
|
1121
|
+
},
|
|
1090
1122
|
serverName,
|
|
1091
1123
|
(conn) => conn.client.readResource({ uri: toolMeta.resourceUri! }, requestOptions),
|
|
1092
1124
|
);
|
|
@@ -1107,24 +1139,29 @@ export async function executeCall(
|
|
|
1107
1139
|
toolName: toolMeta.originalName,
|
|
1108
1140
|
toolArgs: args ?? {},
|
|
1109
1141
|
uiResourceUri: toolMeta.uiResourceUri,
|
|
1110
|
-
streamMode: toolMeta.uiStreamMode,
|
|
1111
|
-
signal,
|
|
1142
|
+
...(toolMeta.uiStreamMode !== undefined ? { streamMode: toolMeta.uiStreamMode } : {}),
|
|
1143
|
+
...(signal ? { signal } : {}),
|
|
1112
1144
|
onNeedsAuth: recoverAuthConnection,
|
|
1113
1145
|
})
|
|
1114
1146
|
: null;
|
|
1115
1147
|
|
|
1116
|
-
const result = await withSessionRecovery(
|
|
1117
|
-
{
|
|
1148
|
+
const result = await withSessionRecovery<ClientCallToolResult>(
|
|
1149
|
+
{
|
|
1150
|
+
manager: state.manager,
|
|
1151
|
+
config: state.config,
|
|
1152
|
+
...(ownedSignal ? { signal: ownedSignal } : {}),
|
|
1153
|
+
onNeedsAuth: recoverAuthConnection,
|
|
1154
|
+
},
|
|
1118
1155
|
serverName,
|
|
1119
1156
|
(conn) => abortable(conn.client.callTool({
|
|
1120
1157
|
name: toolMeta.originalName,
|
|
1121
1158
|
arguments: args ?? {},
|
|
1122
1159
|
_meta: uiSession?.requestMeta,
|
|
1123
|
-
},
|
|
1160
|
+
}, requestOptions), ownedSignal),
|
|
1124
1161
|
);
|
|
1125
1162
|
|
|
1126
1163
|
if (toolMeta.uiResourceUri) {
|
|
1127
|
-
uiSession?.sendToolResult(result as unknown as import("@modelcontextprotocol/
|
|
1164
|
+
uiSession?.sendToolResult(result as unknown as import("@modelcontextprotocol/client").CallToolResult);
|
|
1128
1165
|
|
|
1129
1166
|
if (result.isError) {
|
|
1130
1167
|
const mcpContent = (result.content ?? []) as McpContent[];
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import { complete
|
|
1
|
+
import { complete } from "@earendil-works/pi-ai/compat";
|
|
2
|
+
import type { Api, AssistantMessage, Message, Model, ProviderHeaders, TextContent } from "@earendil-works/pi-ai";
|
|
2
3
|
import { truncateAtWord } from "./utils.ts";
|
|
3
4
|
import { throwIfAborted } from "./abort.ts";
|
|
4
5
|
import type { ExtensionUIContext, ModelRegistry } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import type { Client } from "@modelcontextprotocol/
|
|
6
|
+
import type { Client } from "@modelcontextprotocol/client";
|
|
6
7
|
import {
|
|
7
|
-
CreateMessageRequestSchema,
|
|
8
8
|
type CreateMessageRequest,
|
|
9
9
|
type CreateMessageResult,
|
|
10
10
|
type ModelPreferences,
|
|
11
11
|
type SamplingMessage,
|
|
12
12
|
type SamplingMessageContentBlock,
|
|
13
|
-
} from "@modelcontextprotocol/
|
|
13
|
+
} from "@modelcontextprotocol/client";
|
|
14
|
+
|
|
15
|
+
export type SamplingUIContext = Pick<ExtensionUIContext, "confirm">;
|
|
16
|
+
export type SamplingModelRegistry = Pick<ModelRegistry, "getAvailable" | "getApiKeyAndHeaders">;
|
|
14
17
|
|
|
15
18
|
export interface SamplingHandlerOptions {
|
|
16
19
|
serverName: string;
|
|
17
20
|
autoApprove: boolean;
|
|
18
|
-
ui?:
|
|
19
|
-
modelRegistry:
|
|
21
|
+
ui?: SamplingUIContext;
|
|
22
|
+
modelRegistry: SamplingModelRegistry;
|
|
20
23
|
getCurrentModel: () => Model<Api> | undefined;
|
|
21
24
|
getSignal: () => AbortSignal | undefined;
|
|
22
25
|
}
|
|
@@ -24,7 +27,7 @@ export interface SamplingHandlerOptions {
|
|
|
24
27
|
export type ServerSamplingConfig = Omit<SamplingHandlerOptions, "serverName">;
|
|
25
28
|
|
|
26
29
|
export function registerSamplingHandler(client: Client, options: SamplingHandlerOptions): void {
|
|
27
|
-
client.setRequestHandler(
|
|
30
|
+
client.setRequestHandler("sampling/createMessage", request => {
|
|
28
31
|
return handleSamplingRequest(options, request);
|
|
29
32
|
});
|
|
30
33
|
}
|
|
@@ -66,16 +69,16 @@ export async function handleSamplingRequest(
|
|
|
66
69
|
const result = await complete(
|
|
67
70
|
model,
|
|
68
71
|
{
|
|
69
|
-
systemPrompt: params.systemPrompt,
|
|
72
|
+
...(params.systemPrompt !== undefined ? { systemPrompt: params.systemPrompt } : {}),
|
|
70
73
|
messages,
|
|
71
74
|
},
|
|
72
75
|
{
|
|
73
|
-
apiKey,
|
|
74
|
-
headers,
|
|
76
|
+
...(apiKey !== undefined ? { apiKey } : {}),
|
|
77
|
+
...(headers !== undefined ? { headers } : {}),
|
|
75
78
|
maxTokens: params.maxTokens,
|
|
76
|
-
temperature: params.temperature,
|
|
77
|
-
metadata: params.metadata as Record<string, unknown>
|
|
78
|
-
signal,
|
|
79
|
+
...(params.temperature !== undefined ? { temperature: params.temperature } : {}),
|
|
80
|
+
...(params.metadata !== undefined ? { metadata: params.metadata as Record<string, unknown> } : {}),
|
|
81
|
+
...(signal ? { signal } : {}),
|
|
79
82
|
},
|
|
80
83
|
);
|
|
81
84
|
|
|
@@ -127,7 +130,7 @@ async function resolveSamplingModel(
|
|
|
127
130
|
): Promise<{
|
|
128
131
|
model: Model<Api>;
|
|
129
132
|
apiKey?: string;
|
|
130
|
-
headers?:
|
|
133
|
+
headers?: ProviderHeaders;
|
|
131
134
|
}> {
|
|
132
135
|
const candidates: Model<Api>[] = [];
|
|
133
136
|
const availableModels = options.modelRegistry.getAvailable();
|
|
@@ -160,7 +163,11 @@ async function resolveSamplingModel(
|
|
|
160
163
|
errors.push(`${model.provider}/${model.id}: ${auth.error}`);
|
|
161
164
|
continue;
|
|
162
165
|
}
|
|
163
|
-
return {
|
|
166
|
+
return {
|
|
167
|
+
model,
|
|
168
|
+
...(auth.apiKey !== undefined ? { apiKey: auth.apiKey } : {}),
|
|
169
|
+
...(auth.headers !== undefined ? { headers: auth.headers } : {}),
|
|
170
|
+
};
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
if (errors.length > 0) {
|
|
@@ -82,7 +82,8 @@ export function scoreToolMatch(tool: ToolMetadata, server: string, query: string
|
|
|
82
82
|
if (!phraseMatched && (queryTokens.length <= 2 ? coverage !== 1 : coverage < 0.6)) return null;
|
|
83
83
|
|
|
84
84
|
score += coverage === 1 ? 25 : Math.round(coverage * 10);
|
|
85
|
-
|
|
85
|
+
const firstQueryToken = queryTokens[0];
|
|
86
|
+
if (firstQueryToken !== undefined && tokenize(fields.name).includes(firstQueryToken)) score += 8;
|
|
86
87
|
if (wholeFieldExact) score += 20;
|
|
87
88
|
return score;
|
|
88
89
|
}
|