@oh-my-pi/pi-coding-agent 15.10.5 → 15.10.7
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 +29 -0
- package/dist/types/exa/index.d.ts +1 -19
- package/dist/types/exa/mcp-client.d.ts +10 -3
- package/dist/types/exa/types.d.ts +0 -83
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +8 -0
- package/dist/types/modes/interactive-mode.d.ts +8 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/task/render.d.ts +1 -0
- package/dist/types/tools/index.d.ts +0 -2
- package/dist/types/utils/git.d.ts +6 -0
- package/package.json +9 -9
- package/src/cli/auth-gateway-cli.ts +3 -2
- package/src/commit/agentic/tools/split-commit.ts +8 -1
- package/src/config/model-provider-priority.ts +1 -0
- package/src/exa/index.ts +1 -26
- package/src/exa/mcp-client.ts +10 -10
- package/src/exa/types.ts +0 -97
- package/src/internal-urls/docs-index.generated.ts +1 -1
- package/src/mcp/manager.ts +17 -16
- package/src/modes/components/agent-dashboard.ts +6 -4
- package/src/modes/controllers/event-controller.ts +8 -0
- package/src/modes/controllers/input-controller.ts +24 -1
- package/src/modes/controllers/mcp-command-controller.ts +24 -5
- package/src/modes/interactive-mode.ts +33 -1
- package/src/modes/types.ts +1 -0
- package/src/prompts/tools/read.md +0 -1
- package/src/session/agent-session.ts +77 -41
- package/src/slash-commands/builtin-registry.ts +8 -0
- package/src/task/index.ts +9 -1
- package/src/task/render.ts +22 -12
- package/src/tools/index.ts +0 -4
- package/src/utils/git.ts +41 -0
- package/dist/types/exa/factory.d.ts +0 -13
- package/dist/types/exa/render.d.ts +0 -19
- package/dist/types/exa/researcher.d.ts +0 -9
- package/dist/types/exa/search.d.ts +0 -9
- package/dist/types/exa/websets.d.ts +0 -9
- package/src/exa/factory.ts +0 -60
- package/src/exa/render.ts +0 -244
- package/src/exa/researcher.ts +0 -36
- package/src/exa/search.ts +0 -47
- package/src/exa/websets.ts +0 -248
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [15.10.7] - 2026-06-08
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed MCP OAuth fallback rendering to show a short terminal hyperlink and keep the raw authorization URL on one unwrapped copy line ([#2121](https://github.com/can1357/oh-my-pi/issues/2121)).
|
|
10
|
+
- Fixed `omp` startup blocking 25–30 s on a single unresponsive MCP server when no cached tools were available for it. `MCPManager.connectServers` used to fall through to an unbounded `Promise.allSettled` over every still-pending server without a cached tool list, so one server stuck waiting on the per-request MCP timeout (`OMP_MCP_TIMEOUT_MS`, default 30 000 ms) gated the entire UI ready signal. Pending-without-cache servers are now left in flight: their tools surface via the existing background `#onToolsChanged` → `refreshMCPTools` path the moment the connect completes, and failures continue to log through the background catch handler ([#2100](https://github.com/can1357/oh-my-pi/issues/2100)).
|
|
11
|
+
|
|
12
|
+
## [15.10.6] - 2026-06-08
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Added a `/plan-review` command that manually (re-)opens the plan-review overlay while plan mode is active. Since there is no fixed plan filename, it reviews the newest `local://<slug>-plan.md` the agent wrote — useful for pulling the review back up after dismissing it, or reviewing a plan the agent wrote without calling `resolve`.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Reverted the `task` tool's result-header glyph from the `⇶` signature icon back to the quiet `status.done` bullet (`•`): white while a subagent is running, accent once it finishes. The reviewer verdict line and per-agent result lines use the same bullet.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Fixed `/login` API-key prompts (OpenCode Zen, Perplexity OTP, GitHub Enterprise URL, manual OAuth redirect URL, …) silently dropping pasted content on kitty/Linux/Wayland — and any other terminal supporting OSC 5522 enhanced paste. `InputController` enables kitty's enhanced clipboard protocol on TUI start and consumes the resulting OSC 5522 packets in an `addInputListener` that runs before focus dispatch, so the paste never reached the modal `Input`'s bracketed-paste handler; the routing then stuffed the text into the main `CustomEditor` unconditionally, even when `selector-controller` had detached the editor and focused a temporary OAuth input. The pasted API key accumulated in the hidden editor and only resurfaced in the main prompt when the user dismissed the modal with Enter or Esc. The enhanced-paste callback now consults `ui.getFocused()` and routes the text to the focused component when it exposes a `pasteText` hook, falling back to the editor only when no modal target is in focus; image pastes refuse with a status message instead of stuffing a binary blob into the hidden editor. ([#2127](https://github.com/can1357/oh-my-pi/issues/2127))
|
|
25
|
+
- Fixed an auto-compaction dead loop when `compaction.strategy` was `shake` and the configured threshold was low enough that a single shake pass could not bring the context below it (e.g. a 50K-token threshold on a session well above it). Each pass auto-continued, the next agent turn re-triggered the threshold check, and the second shake had nothing new to drop, so the session spun forever. The shake recovery path now estimates post-shake context and, when it is still above the threshold (or shake reclaimed nothing on overflow recovery), surfaces a one-shot warning and falls back to the summarization-driven `context-full` compaction so progress actually resumes ([#2119](https://github.com/can1357/oh-my-pi/issues/2119)).
|
|
26
|
+
- Fixed `/skill:` prompts so magic keywords and turn-budget directives in skill args inject the same hidden notices as normal user prompts, matching the editor highlight behavior ([#2128](https://github.com/can1357/oh-my-pi/issues/2128)).
|
|
27
|
+
- Fixed MCP OAuth fallback rendering to show a short terminal hyperlink and keep the raw authorization URL on one unwrapped copy line ([#2121](https://github.com/can1357/oh-my-pi/issues/2121)).
|
|
28
|
+
- Fixed the `task` tool rendering a success bullet and a `success` frame state for detail-less error results (e.g. an argument-validation failure that never executes): the header now shows the error glyph with an error border and `error` state, and surfaces the dispatched agent name.
|
|
29
|
+
- Fixed Agent Control Center new-agent creation so Windows Ctrl+Enter sequences submitted as a single LF generate the agent instead of inserting a newline ([#2118](https://github.com/can1357/oh-my-pi/issues/2118)).
|
|
30
|
+
- Fixed plan-mode subagents preserving read-only specialty tools such as `report_finding` while still stripping mutating tools ([#1998](https://github.com/can1357/oh-my-pi/issues/1998)).
|
|
31
|
+
- Removed unreachable standalone Exa tool-suite exports and stale tool-count barrel exposure while keeping the live Exa `web_search` provider helpers ([#2093](https://github.com/can1357/oh-my-pi/issues/2093)).
|
|
32
|
+
- Fixed `omp commit` split plans accepting hunk selectors that resolve to no parsed hunks, which crashed the apply step after the index reset and left the working tree fully unstaged ([#2098](https://github.com/can1357/oh-my-pi/issues/2098)).
|
|
33
|
+
|
|
5
34
|
## [15.10.5] - 2026-06-08
|
|
6
35
|
|
|
7
36
|
### Added
|
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exa MCP Tools
|
|
3
|
-
*
|
|
4
|
-
* 22 tools for Exa's MCP servers:
|
|
5
|
-
* - 4 search tools (search, deep, code, crawl)
|
|
6
|
-
* - 1 LinkedIn search tool
|
|
7
|
-
* - 1 company research tool
|
|
8
|
-
* - 2 researcher tools (start, poll)
|
|
9
|
-
* - 14 websets tools (CRUD, items, search, enrichment, monitor)
|
|
10
|
-
*/
|
|
11
|
-
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
12
|
-
import type { ExaRenderDetails } from "./types";
|
|
13
|
-
/** All Exa tools (22 total) - static export for backward compatibility */
|
|
14
|
-
export declare const exaTools: CustomTool<any, ExaRenderDetails>[];
|
|
15
1
|
export * from "./mcp-client";
|
|
16
|
-
export {
|
|
17
|
-
export { researcherTools } from "./researcher";
|
|
18
|
-
export { searchTools } from "./search";
|
|
19
|
-
export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult, MCPToolWrapperConfig } from "./types";
|
|
20
|
-
export { websetsTools } from "./websets";
|
|
2
|
+
export type { ExaSearchResponse, MCPCallResponse, MCPTool, MCPToolsResponse, MCPToolWrapperConfig } from "./types";
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { TSchema } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import type { CustomTool, CustomToolResult } from "../extensibility/custom-tools/types";
|
|
3
3
|
import { type CallMcpOptions } from "../mcp/json-rpc";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ExaSearchResponse, MCPTool, MCPToolWrapperConfig } from "./types";
|
|
5
|
+
type MCPWrappedToolDetails = {
|
|
6
|
+
response?: ExaSearchResponse;
|
|
7
|
+
error?: string;
|
|
8
|
+
toolName?: string;
|
|
9
|
+
raw?: unknown;
|
|
10
|
+
};
|
|
5
11
|
/** Find EXA_API_KEY from Bun.env or .env files */
|
|
6
12
|
export declare function findApiKey(): string | null;
|
|
7
13
|
/** Fetch available tools from Exa MCP */
|
|
@@ -29,14 +35,14 @@ export declare function fetchMCPToolSchema(apiKey: string, mcpToolName: string,
|
|
|
29
35
|
* This allows tools to be generated from MCP server schemas without hardcoding,
|
|
30
36
|
* reducing drift when MCP servers add new parameters.
|
|
31
37
|
*/
|
|
32
|
-
export declare class MCPWrappedTool implements CustomTool<TSchema,
|
|
38
|
+
export declare class MCPWrappedTool implements CustomTool<TSchema, MCPWrappedToolDetails> {
|
|
33
39
|
private readonly config;
|
|
34
40
|
readonly parameters: TSchema;
|
|
35
41
|
readonly description: string;
|
|
36
42
|
readonly name: string;
|
|
37
43
|
readonly label: string;
|
|
38
44
|
constructor(config: MCPToolWrapperConfig, parameters: TSchema, description: string);
|
|
39
|
-
execute(_toolCallId: string, params: unknown, _onUpdate?: unknown, _ctx?: unknown, _signal?: AbortSignal): Promise<CustomToolResult<
|
|
45
|
+
execute(_toolCallId: string, params: unknown, _onUpdate?: unknown, _ctx?: unknown, _signal?: AbortSignal): Promise<CustomToolResult<MCPWrappedToolDetails>>;
|
|
40
46
|
}
|
|
41
47
|
/**
|
|
42
48
|
* Create a CustomTool by fetching schema from MCP server.
|
|
@@ -44,3 +50,4 @@ export declare class MCPWrappedTool implements CustomTool<TSchema, ExaRenderDeta
|
|
|
44
50
|
* Falls back to provided fallback schema if MCP fetch fails.
|
|
45
51
|
*/
|
|
46
52
|
export declare function createMCPToolFromServer(apiKey: string, config: MCPToolWrapperConfig, fallbackSchema: TSchema, fallbackDescription: string): Promise<MCPWrappedTool>;
|
|
53
|
+
export {};
|
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* Types for the Exa MCP client and tool implementations.
|
|
5
5
|
*/
|
|
6
6
|
import type { TSchema } from "@oh-my-pi/pi-ai";
|
|
7
|
-
/** MCP endpoint URLs */
|
|
8
|
-
export declare const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
|
|
9
|
-
export declare const WEBSETS_MCP_URL = "https://websetsmcp.exa.ai/mcp";
|
|
10
7
|
/** MCP tool definition from server */
|
|
11
8
|
export interface MCPTool {
|
|
12
9
|
name: string;
|
|
@@ -73,83 +70,3 @@ export interface ExaSearchResponse {
|
|
|
73
70
|
searchTime?: number;
|
|
74
71
|
requestId?: string;
|
|
75
72
|
}
|
|
76
|
-
/** Researcher task status */
|
|
77
|
-
export interface ResearcherStatus {
|
|
78
|
-
id: string;
|
|
79
|
-
status: "pending" | "running" | "completed" | "failed";
|
|
80
|
-
result?: string;
|
|
81
|
-
error?: string;
|
|
82
|
-
}
|
|
83
|
-
/** Webset definition */
|
|
84
|
-
export interface Webset {
|
|
85
|
-
id: string;
|
|
86
|
-
name: string;
|
|
87
|
-
description?: string;
|
|
88
|
-
createdAt?: string;
|
|
89
|
-
updatedAt?: string;
|
|
90
|
-
}
|
|
91
|
-
/** Webset item */
|
|
92
|
-
export interface WebsetItem {
|
|
93
|
-
id: string;
|
|
94
|
-
websetId: string;
|
|
95
|
-
url: string;
|
|
96
|
-
title?: string;
|
|
97
|
-
content?: string;
|
|
98
|
-
metadata?: Record<string, unknown>;
|
|
99
|
-
}
|
|
100
|
-
/** Webset search */
|
|
101
|
-
export interface WebsetSearch {
|
|
102
|
-
id: string;
|
|
103
|
-
websetId: string;
|
|
104
|
-
query: string;
|
|
105
|
-
status: "pending" | "running" | "completed" | "cancelled";
|
|
106
|
-
resultCount?: number;
|
|
107
|
-
}
|
|
108
|
-
/** Webset enrichment */
|
|
109
|
-
export interface WebsetEnrichment {
|
|
110
|
-
id: string;
|
|
111
|
-
websetId: string;
|
|
112
|
-
name: string;
|
|
113
|
-
prompt: string;
|
|
114
|
-
status: "pending" | "running" | "completed" | "cancelled";
|
|
115
|
-
}
|
|
116
|
-
/** Tool name mappings: MCP name -> our tool name */
|
|
117
|
-
export declare const EXA_TOOL_MAPPINGS: {
|
|
118
|
-
readonly web_search_exa: "exa_search";
|
|
119
|
-
readonly get_code_context_exa: "exa_search_code";
|
|
120
|
-
readonly crawling_exa: "exa_crawl";
|
|
121
|
-
readonly linkedin_search_exa: "exa_linkedin";
|
|
122
|
-
readonly company_research_exa: "exa_company";
|
|
123
|
-
readonly deep_researcher_start: "exa_researcher_start";
|
|
124
|
-
readonly deep_researcher_check: "exa_researcher_poll";
|
|
125
|
-
};
|
|
126
|
-
export declare const WEBSETS_TOOL_MAPPINGS: {
|
|
127
|
-
readonly create_webset: "webset_create";
|
|
128
|
-
readonly list_websets: "webset_list";
|
|
129
|
-
readonly get_webset: "webset_get";
|
|
130
|
-
readonly update_webset: "webset_update";
|
|
131
|
-
readonly delete_webset: "webset_delete";
|
|
132
|
-
readonly list_webset_items: "webset_items_list";
|
|
133
|
-
readonly get_item: "webset_item_get";
|
|
134
|
-
readonly create_search: "webset_search_create";
|
|
135
|
-
readonly get_search: "webset_search_get";
|
|
136
|
-
readonly cancel_search: "webset_search_cancel";
|
|
137
|
-
readonly create_enrichment: "webset_enrichment_create";
|
|
138
|
-
readonly get_enrichment: "webset_enrichment_get";
|
|
139
|
-
readonly update_enrichment: "webset_enrichment_update";
|
|
140
|
-
readonly delete_enrichment: "webset_enrichment_delete";
|
|
141
|
-
readonly cancel_enrichment: "webset_enrichment_cancel";
|
|
142
|
-
readonly create_monitor: "webset_monitor_create";
|
|
143
|
-
};
|
|
144
|
-
export type ExaMcpToolName = keyof typeof EXA_TOOL_MAPPINGS;
|
|
145
|
-
export type WebsetsMcpToolName = keyof typeof WEBSETS_TOOL_MAPPINGS;
|
|
146
|
-
export type ExaToolName = (typeof EXA_TOOL_MAPPINGS)[ExaMcpToolName];
|
|
147
|
-
export type WebsetsToolName = (typeof WEBSETS_TOOL_MAPPINGS)[WebsetsMcpToolName];
|
|
148
|
-
/** Render details for TUI */
|
|
149
|
-
export interface ExaRenderDetails {
|
|
150
|
-
response?: ExaSearchResponse;
|
|
151
|
-
error?: string;
|
|
152
|
-
toolName?: string;
|
|
153
|
-
/** Raw result for non-search responses */
|
|
154
|
-
raw?: unknown;
|
|
155
|
-
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { type Component } from "@oh-my-pi/pi-tui";
|
|
1
2
|
import type { InteractiveModeContext } from "../types";
|
|
3
|
+
/** Renders the MCP OAuth fallback URL without hard-wrapping the copy target. */
|
|
4
|
+
export declare class MCPAuthorizationLinkPrompt implements Component {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(url: string);
|
|
7
|
+
invalidate(): void;
|
|
8
|
+
render(_width: number): string[];
|
|
9
|
+
}
|
|
2
10
|
export declare class MCPCommandController {
|
|
3
11
|
#private;
|
|
4
12
|
private ctx;
|
|
@@ -161,6 +161,14 @@ export declare class InteractiveMode implements InteractiveModeContext {
|
|
|
161
161
|
}): Promise<string | undefined>;
|
|
162
162
|
handlePlanModeCommand(initialPrompt?: string): Promise<void>;
|
|
163
163
|
handleGoalModeCommand(rest?: string): Promise<void>;
|
|
164
|
+
/** Manually (re-)open the plan-review overlay — bound to `/plan-review`. Lets
|
|
165
|
+
* the operator pull the review back up after dismissing it, or review a plan
|
|
166
|
+
* the agent wrote without calling `resolve`. There is no fixed plan filename:
|
|
167
|
+
* `getPlanReferencePath()` is empty until a plan is actually approved (and does
|
|
168
|
+
* not survive a restart), so this drives off the newest `local://<slug>-plan.md`
|
|
169
|
+
* the agent wrote — the files persist in the session artifacts dir, so the scan
|
|
170
|
+
* works before any review and across restarts. */
|
|
171
|
+
openPlanReview(): Promise<void>;
|
|
164
172
|
handlePlanApproval(details: PlanApprovalDetails): Promise<void>;
|
|
165
173
|
stop(): void;
|
|
166
174
|
shutdown(): Promise<void>;
|
|
@@ -290,6 +290,7 @@ export interface InteractiveModeContext {
|
|
|
290
290
|
disableLoopMode(): void;
|
|
291
291
|
pauseLoop(): void;
|
|
292
292
|
handlePlanApproval(details: PlanApprovalDetails): Promise<void>;
|
|
293
|
+
openPlanReview(): Promise<void>;
|
|
293
294
|
initHooksAndCustomTools(): Promise<void>;
|
|
294
295
|
emitCustomToolSessionEvent(reason: "start" | "switch" | "branch" | "tree" | "shutdown", previousSessionFile?: string): Promise<void>;
|
|
295
296
|
setHookWidget(key: string, content: ExtensionWidgetContent, options?: ExtensionWidgetOptions): void;
|
|
@@ -19,6 +19,7 @@ export declare function renderResult(result: {
|
|
|
19
19
|
text?: string;
|
|
20
20
|
}>;
|
|
21
21
|
details?: TaskToolDetails;
|
|
22
|
+
isError?: boolean;
|
|
22
23
|
}, options: RenderResultOptions, theme: Theme, args?: TaskParams): Component;
|
|
23
24
|
export declare const taskToolRenderer: {
|
|
24
25
|
renderCall: typeof renderCall;
|
|
@@ -23,8 +23,6 @@ import type { WorkspaceTree } from "../workspace-tree";
|
|
|
23
23
|
import { type CheckpointState } from "./checkpoint";
|
|
24
24
|
import { type TodoPhase } from "./todo";
|
|
25
25
|
export * from "../edit";
|
|
26
|
-
export * from "../exa";
|
|
27
|
-
export type * from "../exa/types";
|
|
28
26
|
export * from "../goals";
|
|
29
27
|
export * from "../lsp";
|
|
30
28
|
export * from "../session/streaming-output";
|
|
@@ -34,6 +34,10 @@ export interface StageHunksOptions {
|
|
|
34
34
|
readonly rawDiff?: string;
|
|
35
35
|
readonly signal?: AbortSignal;
|
|
36
36
|
}
|
|
37
|
+
export interface HunkSelectionValidationError {
|
|
38
|
+
readonly path: string;
|
|
39
|
+
readonly message: string;
|
|
40
|
+
}
|
|
37
41
|
export interface DiffOptions {
|
|
38
42
|
readonly allowFailure?: boolean;
|
|
39
43
|
readonly base?: string;
|
|
@@ -128,6 +132,8 @@ interface CommandOptions {
|
|
|
128
132
|
* module never auto-acquire — callers wrap the critical section themselves.
|
|
129
133
|
*/
|
|
130
134
|
export declare function withRepoLock<T>(cwd: string, fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
135
|
+
export declare function createHunkSelectionValidator(rawDiff: string): (selections: readonly HunkSelection[]) => HunkSelectionValidationError[];
|
|
136
|
+
export declare function validateHunkSelections(rawDiff: string, selections: readonly HunkSelection[]): HunkSelectionValidationError[];
|
|
131
137
|
declare function parseStatusPorcelain(text: string): GitStatusSummary;
|
|
132
138
|
/** Run `git diff` with the given options. Returns raw diff text. */
|
|
133
139
|
export declare const diff: ((cwd: string, options?: DiffOptions) => Promise<string>) & {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "15.10.
|
|
4
|
+
"version": "15.10.7",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -47,14 +47,14 @@
|
|
|
47
47
|
"@agentclientprotocol/sdk": "0.22.1",
|
|
48
48
|
"@babel/parser": "^7.29.7",
|
|
49
49
|
"@mozilla/readability": "^0.6.0",
|
|
50
|
-
"@oh-my-pi/hashline": "15.10.
|
|
51
|
-
"@oh-my-pi/omp-stats": "15.10.
|
|
52
|
-
"@oh-my-pi/pi-agent-core": "15.10.
|
|
53
|
-
"@oh-my-pi/pi-ai": "15.10.
|
|
54
|
-
"@oh-my-pi/pi-mnemopi": "15.10.
|
|
55
|
-
"@oh-my-pi/pi-natives": "15.10.
|
|
56
|
-
"@oh-my-pi/pi-tui": "15.10.
|
|
57
|
-
"@oh-my-pi/pi-utils": "15.10.
|
|
50
|
+
"@oh-my-pi/hashline": "15.10.7",
|
|
51
|
+
"@oh-my-pi/omp-stats": "15.10.7",
|
|
52
|
+
"@oh-my-pi/pi-agent-core": "15.10.7",
|
|
53
|
+
"@oh-my-pi/pi-ai": "15.10.7",
|
|
54
|
+
"@oh-my-pi/pi-mnemopi": "15.10.7",
|
|
55
|
+
"@oh-my-pi/pi-natives": "15.10.7",
|
|
56
|
+
"@oh-my-pi/pi-tui": "15.10.7",
|
|
57
|
+
"@oh-my-pi/pi-utils": "15.10.7",
|
|
58
58
|
"@opentelemetry/api": "^1.9.1",
|
|
59
59
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|
|
60
60
|
"@opentelemetry/exporter-trace-otlp-proto": "^0.218.0",
|
|
@@ -175,8 +175,9 @@ async function runServe(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
|
175
175
|
for (const provider of getBundledProviders()) {
|
|
176
176
|
if (!providersWithCreds.has(provider)) continue;
|
|
177
177
|
for (const model of getBundledModels(provider as GeneratedProvider)) {
|
|
178
|
-
//
|
|
179
|
-
|
|
178
|
+
// Always set the qualified key (no collision possible)
|
|
179
|
+
modelById.set(`${model.provider}/${model.id}`, model);
|
|
180
|
+
// Bare id as fallback for legacy clients (first-write-wins)
|
|
180
181
|
if (!modelById.has(model.id)) modelById.set(model.id, model);
|
|
181
182
|
}
|
|
182
183
|
}
|
|
@@ -68,6 +68,7 @@ export function createSplitCommitTool(
|
|
|
68
68
|
const errors: string[] = [];
|
|
69
69
|
const warnings: string[] = [];
|
|
70
70
|
const diffText = await git.diff(cwd, { cached: true });
|
|
71
|
+
const validateHunksForDiff = git.createHunkSelectionValidator(diffText);
|
|
71
72
|
|
|
72
73
|
const commits: SplitCommitGroup[] = params.commits.map((commit, index) => {
|
|
73
74
|
const scope = commit.scope?.trim() || null;
|
|
@@ -102,7 +103,7 @@ export function createSplitCommitTool(
|
|
|
102
103
|
}
|
|
103
104
|
warnings.push(...summaryValidation.warnings.map(warning => `Commit ${index + 1}: ${warning}`));
|
|
104
105
|
warnings.push(...typeValidation.warnings.map(warning => `Commit ${index + 1}: ${warning}`));
|
|
105
|
-
const hunkValidation = validateHunkSelectors(index, changes, files);
|
|
106
|
+
const hunkValidation = validateHunkSelectors(index, changes, files, validateHunksForDiff);
|
|
106
107
|
warnings.push(...hunkValidation.warnings);
|
|
107
108
|
errors.push(...hunkValidation.errors);
|
|
108
109
|
errors.push(...validateDependencies(index, dependencies, params.commits.length));
|
|
@@ -186,6 +187,7 @@ function validateHunkSelectors(
|
|
|
186
187
|
commitIndex: number,
|
|
187
188
|
changes: SplitCommitGroup["changes"],
|
|
188
189
|
files: string[],
|
|
190
|
+
validateHunksForDiff: (changes: SplitCommitGroup["changes"]) => git.HunkSelectionValidationError[],
|
|
189
191
|
): { errors: string[]; warnings: string[] } {
|
|
190
192
|
const errors: string[] = [];
|
|
191
193
|
const warnings: string[] = [];
|
|
@@ -215,6 +217,11 @@ function validateHunkSelectors(
|
|
|
215
217
|
}
|
|
216
218
|
}
|
|
217
219
|
}
|
|
220
|
+
if (errors.length === 0) {
|
|
221
|
+
for (const error of validateHunksForDiff(changes)) {
|
|
222
|
+
errors.push(`${prefix}: ${error.message}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
218
225
|
return { errors, warnings };
|
|
219
226
|
}
|
|
220
227
|
|
package/src/exa/index.ts
CHANGED
|
@@ -1,27 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Exa MCP Tools
|
|
3
|
-
*
|
|
4
|
-
* 22 tools for Exa's MCP servers:
|
|
5
|
-
* - 4 search tools (search, deep, code, crawl)
|
|
6
|
-
* - 1 LinkedIn search tool
|
|
7
|
-
* - 1 company research tool
|
|
8
|
-
* - 2 researcher tools (start, poll)
|
|
9
|
-
* - 14 websets tools (CRUD, items, search, enrichment, monitor)
|
|
10
|
-
*/
|
|
11
|
-
import type { CustomTool } from "../extensibility/custom-tools/types";
|
|
12
|
-
import { researcherTools } from "./researcher";
|
|
13
|
-
import { searchTools } from "./search";
|
|
14
|
-
import type { ExaRenderDetails } from "./types";
|
|
15
|
-
import { websetsTools } from "./websets";
|
|
16
|
-
|
|
17
|
-
/** All Exa tools (22 total) - static export for backward compatibility */
|
|
18
|
-
export const exaTools: CustomTool<any, ExaRenderDetails>[] = [...searchTools, ...researcherTools, ...websetsTools];
|
|
19
|
-
|
|
20
1
|
export * from "./mcp-client";
|
|
21
|
-
export {
|
|
22
|
-
export { researcherTools } from "./researcher";
|
|
23
|
-
// Re-export individual modules for selective importing
|
|
24
|
-
export { searchTools } from "./search";
|
|
25
|
-
// Re-export types and utilities
|
|
26
|
-
export type { ExaRenderDetails, ExaSearchResponse, ExaSearchResult, MCPToolWrapperConfig } from "./types";
|
|
27
|
-
export { websetsTools } from "./websets";
|
|
2
|
+
export type { ExaSearchResponse, MCPCallResponse, MCPTool, MCPToolsResponse, MCPToolWrapperConfig } from "./types";
|
package/src/exa/mcp-client.ts
CHANGED
|
@@ -2,14 +2,14 @@ import type { TSchema } from "@oh-my-pi/pi-ai";
|
|
|
2
2
|
import { $env, logger } from "@oh-my-pi/pi-utils";
|
|
3
3
|
import type { CustomTool, CustomToolResult } from "../extensibility/custom-tools/types";
|
|
4
4
|
import { type CallMcpOptions, callMCP } from "../mcp/json-rpc";
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
5
|
+
import type { ExaSearchResponse, MCPCallResponse, MCPTool, MCPToolsResponse, MCPToolWrapperConfig } from "./types";
|
|
6
|
+
|
|
7
|
+
type MCPWrappedToolDetails = {
|
|
8
|
+
response?: ExaSearchResponse;
|
|
9
|
+
error?: string;
|
|
10
|
+
toolName?: string;
|
|
11
|
+
raw?: unknown;
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
/** Find EXA_API_KEY from Bun.env or .env files */
|
|
15
15
|
export function findApiKey(): string | null {
|
|
@@ -296,7 +296,7 @@ export async function fetchMCPToolSchema(
|
|
|
296
296
|
* This allows tools to be generated from MCP server schemas without hardcoding,
|
|
297
297
|
* reducing drift when MCP servers add new parameters.
|
|
298
298
|
*/
|
|
299
|
-
export class MCPWrappedTool implements CustomTool<TSchema,
|
|
299
|
+
export class MCPWrappedTool implements CustomTool<TSchema, MCPWrappedToolDetails> {
|
|
300
300
|
readonly name: string;
|
|
301
301
|
readonly label: string;
|
|
302
302
|
|
|
@@ -315,7 +315,7 @@ export class MCPWrappedTool implements CustomTool<TSchema, ExaRenderDetails> {
|
|
|
315
315
|
_onUpdate?: unknown,
|
|
316
316
|
_ctx?: unknown,
|
|
317
317
|
_signal?: AbortSignal,
|
|
318
|
-
): Promise<CustomToolResult<
|
|
318
|
+
): Promise<CustomToolResult<MCPWrappedToolDetails>> {
|
|
319
319
|
try {
|
|
320
320
|
const apiKey = findApiKey();
|
|
321
321
|
// Websets tools require an API key; basic Exa MCP tools work without one
|
package/src/exa/types.ts
CHANGED
|
@@ -5,10 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { TSchema } from "@oh-my-pi/pi-ai";
|
|
7
7
|
|
|
8
|
-
/** MCP endpoint URLs */
|
|
9
|
-
export const EXA_MCP_URL = "https://mcp.exa.ai/mcp";
|
|
10
|
-
export const WEBSETS_MCP_URL = "https://websetsmcp.exa.ai/mcp";
|
|
11
|
-
|
|
12
8
|
/** MCP tool definition from server */
|
|
13
9
|
export interface MCPTool {
|
|
14
10
|
name: string;
|
|
@@ -71,96 +67,3 @@ export interface ExaSearchResponse {
|
|
|
71
67
|
searchTime?: number;
|
|
72
68
|
requestId?: string;
|
|
73
69
|
}
|
|
74
|
-
|
|
75
|
-
/** Researcher task status */
|
|
76
|
-
export interface ResearcherStatus {
|
|
77
|
-
id: string;
|
|
78
|
-
status: "pending" | "running" | "completed" | "failed";
|
|
79
|
-
result?: string;
|
|
80
|
-
error?: string;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** Webset definition */
|
|
84
|
-
export interface Webset {
|
|
85
|
-
id: string;
|
|
86
|
-
name: string;
|
|
87
|
-
description?: string;
|
|
88
|
-
createdAt?: string;
|
|
89
|
-
updatedAt?: string;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/** Webset item */
|
|
93
|
-
export interface WebsetItem {
|
|
94
|
-
id: string;
|
|
95
|
-
websetId: string;
|
|
96
|
-
url: string;
|
|
97
|
-
title?: string;
|
|
98
|
-
content?: string;
|
|
99
|
-
metadata?: Record<string, unknown>;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Webset search */
|
|
103
|
-
export interface WebsetSearch {
|
|
104
|
-
id: string;
|
|
105
|
-
websetId: string;
|
|
106
|
-
query: string;
|
|
107
|
-
status: "pending" | "running" | "completed" | "cancelled";
|
|
108
|
-
resultCount?: number;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/** Webset enrichment */
|
|
112
|
-
export interface WebsetEnrichment {
|
|
113
|
-
id: string;
|
|
114
|
-
websetId: string;
|
|
115
|
-
name: string;
|
|
116
|
-
prompt: string;
|
|
117
|
-
status: "pending" | "running" | "completed" | "cancelled";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** Tool name mappings: MCP name -> our tool name */
|
|
121
|
-
export const EXA_TOOL_MAPPINGS = {
|
|
122
|
-
// Search tools
|
|
123
|
-
web_search_exa: "exa_search",
|
|
124
|
-
get_code_context_exa: "exa_search_code",
|
|
125
|
-
crawling_exa: "exa_crawl",
|
|
126
|
-
// LinkedIn
|
|
127
|
-
linkedin_search_exa: "exa_linkedin",
|
|
128
|
-
// Company
|
|
129
|
-
company_research_exa: "exa_company",
|
|
130
|
-
// Researcher
|
|
131
|
-
deep_researcher_start: "exa_researcher_start",
|
|
132
|
-
deep_researcher_check: "exa_researcher_poll",
|
|
133
|
-
} as const;
|
|
134
|
-
|
|
135
|
-
export const WEBSETS_TOOL_MAPPINGS = {
|
|
136
|
-
create_webset: "webset_create",
|
|
137
|
-
list_websets: "webset_list",
|
|
138
|
-
get_webset: "webset_get",
|
|
139
|
-
update_webset: "webset_update",
|
|
140
|
-
delete_webset: "webset_delete",
|
|
141
|
-
list_webset_items: "webset_items_list",
|
|
142
|
-
get_item: "webset_item_get",
|
|
143
|
-
create_search: "webset_search_create",
|
|
144
|
-
get_search: "webset_search_get",
|
|
145
|
-
cancel_search: "webset_search_cancel",
|
|
146
|
-
create_enrichment: "webset_enrichment_create",
|
|
147
|
-
get_enrichment: "webset_enrichment_get",
|
|
148
|
-
update_enrichment: "webset_enrichment_update",
|
|
149
|
-
delete_enrichment: "webset_enrichment_delete",
|
|
150
|
-
cancel_enrichment: "webset_enrichment_cancel",
|
|
151
|
-
create_monitor: "webset_monitor_create",
|
|
152
|
-
} as const;
|
|
153
|
-
|
|
154
|
-
export type ExaMcpToolName = keyof typeof EXA_TOOL_MAPPINGS;
|
|
155
|
-
export type WebsetsMcpToolName = keyof typeof WEBSETS_TOOL_MAPPINGS;
|
|
156
|
-
export type ExaToolName = (typeof EXA_TOOL_MAPPINGS)[ExaMcpToolName];
|
|
157
|
-
export type WebsetsToolName = (typeof WEBSETS_TOOL_MAPPINGS)[WebsetsMcpToolName];
|
|
158
|
-
|
|
159
|
-
/** Render details for TUI */
|
|
160
|
-
export interface ExaRenderDetails {
|
|
161
|
-
response?: ExaSearchResponse;
|
|
162
|
-
error?: string;
|
|
163
|
-
toolName?: string;
|
|
164
|
-
/** Raw result for non-search responses */
|
|
165
|
-
raw?: unknown;
|
|
166
|
-
}
|