@oh-my-pi/pi-coding-agent 10.5.0 → 10.6.1
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 +48 -0
- package/package.json +7 -7
- package/src/commit/model-selection.ts +18 -39
- package/src/config/model-registry.ts +19 -0
- package/src/config/model-resolver.ts +92 -1
- package/src/config/settings-schema.ts +22 -2
- package/src/config/settings.ts +23 -2
- package/src/cursor.ts +1 -1
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/loader.ts +1 -1
- package/src/extensibility/extensions/runner.ts +1 -1
- package/src/extensibility/extensions/types.ts +4 -4
- package/src/extensibility/hooks/runner.ts +2 -2
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/main.ts +1 -2
- package/src/modes/components/model-selector.ts +43 -94
- package/src/modes/controllers/input-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +4 -2
- package/src/modes/interactive-mode.ts +1 -1
- package/src/modes/rpc/rpc-types.ts +4 -4
- package/src/prompts/tools/grep.md +4 -8
- package/src/sdk.ts +2 -2
- package/src/session/agent-session.ts +26 -27
- package/src/session/compaction/branch-summarization.ts +1 -1
- package/src/session/compaction/compaction.ts +4 -4
- package/src/task/executor.ts +1 -35
- package/src/task/index.ts +1 -10
- package/src/tools/grep.ts +111 -107
- package/src/web/search/index.ts +15 -4
- package/src/web/search/providers/jina.ts +76 -0
- package/src/web/search/render.ts +3 -1
- package/src/web/search/types.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [10.6.1] - 2026-02-04
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added `commit` model role for dedicated commit message generation
|
|
10
|
+
- Exported `resolveModelOverride` function from model resolver for external use
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Updated model role resolution to accept optional `roleOrder` parameter for custom role priority
|
|
15
|
+
- Made `tag` and `color` properties optional in `ModelRoleInfo` interface
|
|
16
|
+
- Updated model selector to safely handle roles without tag or color definitions
|
|
17
|
+
- Refactored role label display to use centralized `MODEL_ROLES` registry instead of hardcoded strings
|
|
18
|
+
- Refactored model role system to use centralized `MODEL_ROLES` registry with consistent tag, name, and color definitions
|
|
19
|
+
- Simplified model role resolution to use `MODEL_ROLE_IDS` array instead of hardcoded role checks
|
|
20
|
+
- Updated model selector to dynamically generate menu actions from `MODEL_ROLES` registry
|
|
21
|
+
|
|
22
|
+
### Removed
|
|
23
|
+
|
|
24
|
+
- Removed support for `omp/` model role prefix; use `pi/` prefix instead
|
|
25
|
+
|
|
26
|
+
## [10.6.0] - 2026-02-04
|
|
27
|
+
### Breaking Changes
|
|
28
|
+
|
|
29
|
+
- Removed `output_mode` parameter from grep tool—results now always use content mode with formatted match output
|
|
30
|
+
- Renamed grep context parameters from `context_pre`/`context_post` to `pre`/`post`
|
|
31
|
+
- Removed `n` (show line numbers) parameter—line numbers are now always displayed in grep results
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- Added Jina as a web search provider option alongside Exa, Perplexity, and Anthropic
|
|
36
|
+
- Added support for Jina Reader API integration with automatic provider detection when JINA_API_KEY is configured
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- Reformatted grep output to display matches grouped by file with numbered match headers and aligned context lines
|
|
41
|
+
- Updated grep output to use `>>` prefix for match lines and aligned spacing for context lines for improved readability
|
|
42
|
+
- Changed multiline matching to automatically enable when pattern contains literal newlines (`
|
|
43
|
+
`)
|
|
44
|
+
- Split grep context parameter into separate `context_pre` and `context_post` options for independent control of lines before and after matches
|
|
45
|
+
- Updated grep tool to use configurable default context settings from `grep.contextBefore` and `grep.contextAfter` configuration
|
|
46
|
+
- Added configurable grep context defaults and reduced the default to 1 line before, 3 lines after
|
|
47
|
+
- Enabled the browser tool by default
|
|
48
|
+
|
|
49
|
+
### Removed
|
|
50
|
+
|
|
51
|
+
- Removed `filesWithMatches` and `count` output modes from grep tool
|
|
52
|
+
|
|
5
53
|
## [10.5.0] - 2026-02-04
|
|
6
54
|
|
|
7
55
|
### Breaking Changes
|
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.6.1",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"ompConfig": {
|
|
@@ -80,12 +80,12 @@
|
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@mozilla/readability": "0.6.0",
|
|
83
|
-
"@oh-my-pi/omp-stats": "10.
|
|
84
|
-
"@oh-my-pi/pi-agent-core": "10.
|
|
85
|
-
"@oh-my-pi/pi-ai": "10.
|
|
86
|
-
"@oh-my-pi/pi-natives": "10.
|
|
87
|
-
"@oh-my-pi/pi-tui": "10.
|
|
88
|
-
"@oh-my-pi/pi-utils": "10.
|
|
83
|
+
"@oh-my-pi/omp-stats": "10.6.1",
|
|
84
|
+
"@oh-my-pi/pi-agent-core": "10.6.1",
|
|
85
|
+
"@oh-my-pi/pi-ai": "10.6.1",
|
|
86
|
+
"@oh-my-pi/pi-natives": "10.6.1",
|
|
87
|
+
"@oh-my-pi/pi-tui": "10.6.1",
|
|
88
|
+
"@oh-my-pi/pi-utils": "10.6.1",
|
|
89
89
|
"@openai/agents": "^0.4.5",
|
|
90
90
|
"@sinclair/typebox": "^0.34.48",
|
|
91
91
|
"ajv": "^8.17.1",
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import {
|
|
2
|
+
import { MODEL_ROLE_IDS } from "../config/model-registry";
|
|
3
|
+
import {
|
|
4
|
+
expandRoleAlias,
|
|
5
|
+
parseModelPattern,
|
|
6
|
+
resolveModelFromSettings,
|
|
7
|
+
resolveModelFromString,
|
|
8
|
+
SMOL_MODEL_PRIORITY,
|
|
9
|
+
} from "../config/model-resolver";
|
|
3
10
|
import type { Settings } from "../config/settings";
|
|
4
11
|
|
|
5
12
|
export async function resolvePrimaryModel(
|
|
@@ -12,9 +19,15 @@ export async function resolvePrimaryModel(
|
|
|
12
19
|
): Promise<{ model: Model<Api>; apiKey: string }> {
|
|
13
20
|
const available = modelRegistry.getAvailable();
|
|
14
21
|
const matchPreferences = { usageOrder: settings.getStorage()?.getModelUsageOrder() };
|
|
22
|
+
const roleOrder = ["commit", "smol", ...MODEL_ROLE_IDS] as const;
|
|
15
23
|
const model = override
|
|
16
24
|
? resolveModelFromString(expandRoleAlias(override, settings), available, matchPreferences)
|
|
17
|
-
: resolveModelFromSettings(
|
|
25
|
+
: resolveModelFromSettings({
|
|
26
|
+
settings,
|
|
27
|
+
availableModels: available,
|
|
28
|
+
matchPreferences,
|
|
29
|
+
roleOrder,
|
|
30
|
+
});
|
|
18
31
|
if (!model) {
|
|
19
32
|
throw new Error("No model available for commit generation");
|
|
20
33
|
}
|
|
@@ -37,7 +50,9 @@ export async function resolveSmolModel(
|
|
|
37
50
|
const available = modelRegistry.getAvailable();
|
|
38
51
|
const matchPreferences = { usageOrder: settings.getStorage()?.getModelUsageOrder() };
|
|
39
52
|
const role = settings.getModelRole("smol");
|
|
40
|
-
const roleModel = role
|
|
53
|
+
const roleModel = role
|
|
54
|
+
? resolveModelFromString(expandRoleAlias(role, settings), available, matchPreferences)
|
|
55
|
+
: undefined;
|
|
41
56
|
if (roleModel) {
|
|
42
57
|
const apiKey = await modelRegistry.getApiKey(roleModel);
|
|
43
58
|
if (apiKey) return { model: roleModel, apiKey };
|
|
@@ -52,39 +67,3 @@ export async function resolveSmolModel(
|
|
|
52
67
|
|
|
53
68
|
return { model: fallbackModel, apiKey: fallbackApiKey };
|
|
54
69
|
}
|
|
55
|
-
|
|
56
|
-
function resolveModelFromSettings(
|
|
57
|
-
settings: Settings,
|
|
58
|
-
available: Model<Api>[],
|
|
59
|
-
matchPreferences: { usageOrder?: string[] },
|
|
60
|
-
): Model<Api> | undefined {
|
|
61
|
-
const roles = ["commit", "smol", "default"];
|
|
62
|
-
for (const role of roles) {
|
|
63
|
-
const configured = settings.getModelRole(role);
|
|
64
|
-
if (!configured) continue;
|
|
65
|
-
const resolved = resolveModelFromString(expandRoleAlias(configured, settings), available, matchPreferences);
|
|
66
|
-
if (resolved) return resolved;
|
|
67
|
-
}
|
|
68
|
-
return available[0];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function resolveModelFromString(
|
|
72
|
-
value: string,
|
|
73
|
-
available: Model<Api>[],
|
|
74
|
-
matchPreferences: { usageOrder?: string[] },
|
|
75
|
-
): Model<Api> | undefined {
|
|
76
|
-
const parsed = parseModelString(value);
|
|
77
|
-
if (parsed) {
|
|
78
|
-
return available.find(model => model.provider === parsed.provider && model.id === parsed.id);
|
|
79
|
-
}
|
|
80
|
-
return parseModelPattern(value, available, matchPreferences).model;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function expandRoleAlias(value: string, settings: Settings): string {
|
|
84
|
-
const lower = value.toLowerCase();
|
|
85
|
-
if (lower.startsWith("pi/") || lower.startsWith("omp/")) {
|
|
86
|
-
const role = lower.startsWith("pi/") ? value.slice(3) : value.slice(4);
|
|
87
|
-
return settings.getModelRole(role) ?? value;
|
|
88
|
-
}
|
|
89
|
-
return value;
|
|
90
|
-
}
|
|
@@ -15,8 +15,27 @@ import { isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
|
15
15
|
import { type Static, Type } from "@sinclair/typebox";
|
|
16
16
|
import AjvModule from "ajv";
|
|
17
17
|
import { YAML } from "bun";
|
|
18
|
+
import type { ThemeColor } from "../modes/theme/theme";
|
|
18
19
|
import type { AuthStorage } from "../session/auth-storage";
|
|
19
20
|
|
|
21
|
+
export type ModelRole = "default" | "smol" | "slow" | "plan" | "commit";
|
|
22
|
+
|
|
23
|
+
export interface ModelRoleInfo {
|
|
24
|
+
tag?: string;
|
|
25
|
+
name: string;
|
|
26
|
+
color?: ThemeColor;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const MODEL_ROLES: Record<ModelRole, ModelRoleInfo> = {
|
|
30
|
+
default: { tag: "DEFAULT", name: "Default", color: "success" },
|
|
31
|
+
smol: { tag: "SMOL", name: "Fast", color: "warning" },
|
|
32
|
+
slow: { tag: "SLOW", name: "Thinking", color: "accent" },
|
|
33
|
+
plan: { tag: "PLAN", name: "Architect", color: "muted" },
|
|
34
|
+
commit: { name: "Commit" },
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const MODEL_ROLE_IDS: ModelRole[] = ["default", "smol", "slow", "plan", "commit"];
|
|
38
|
+
|
|
20
39
|
const Ajv = (AjvModule as any).default || AjvModule;
|
|
21
40
|
|
|
22
41
|
const OpenRouterRoutingSchema = Type.Object({
|
|
@@ -6,7 +6,8 @@ import { type Api, type KnownProvider, type Model, modelsAreEqual } from "@oh-my
|
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import { isValidThinkingLevel } from "../cli/args";
|
|
8
8
|
import { fuzzyMatch } from "../utils/fuzzy";
|
|
9
|
-
import type
|
|
9
|
+
import { MODEL_ROLE_IDS, type ModelRegistry, type ModelRole } from "./model-registry";
|
|
10
|
+
import type { Settings } from "./settings";
|
|
10
11
|
|
|
11
12
|
/** Default model IDs for each known provider */
|
|
12
13
|
export const defaultModelPerProvider: Record<KnownProvider, string> = {
|
|
@@ -310,6 +311,96 @@ export function parseModelPattern(
|
|
|
310
311
|
return parseModelPatternWithContext(pattern, availableModels, context);
|
|
311
312
|
}
|
|
312
313
|
|
|
314
|
+
const PREFIX_MODEL_ROLE = "pi/";
|
|
315
|
+
const DEFAULT_MODEL_ROLE = "default";
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Check if a model override value is effectively the default role.
|
|
319
|
+
*/
|
|
320
|
+
export function isDefaultModelAlias(value: string | string[] | undefined): boolean {
|
|
321
|
+
if (!value) return true;
|
|
322
|
+
if (Array.isArray(value)) return value.every(entry => isDefaultModelAlias(entry));
|
|
323
|
+
if (value.startsWith(PREFIX_MODEL_ROLE)) {
|
|
324
|
+
value = value.slice(PREFIX_MODEL_ROLE.length);
|
|
325
|
+
}
|
|
326
|
+
return value === DEFAULT_MODEL_ROLE;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Expand a role alias like "pi/smol" to the configured model string.
|
|
331
|
+
*/
|
|
332
|
+
export function expandRoleAlias(value: string, settings?: Settings): string {
|
|
333
|
+
const normalized = value.trim();
|
|
334
|
+
if (normalized === "default") return settings?.getModelRole("default") ?? value;
|
|
335
|
+
if (!normalized.startsWith(PREFIX_MODEL_ROLE)) return value;
|
|
336
|
+
const role = normalized.slice(PREFIX_MODEL_ROLE.length) as ModelRole;
|
|
337
|
+
if (!MODEL_ROLE_IDS.includes(role)) return value;
|
|
338
|
+
return settings?.getModelRole(role) ?? value;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Resolve a model identifier or pattern to a Model instance.
|
|
343
|
+
*/
|
|
344
|
+
export function resolveModelFromString(
|
|
345
|
+
value: string,
|
|
346
|
+
available: Model<Api>[],
|
|
347
|
+
matchPreferences?: ModelMatchPreferences,
|
|
348
|
+
): Model<Api> | undefined {
|
|
349
|
+
const parsed = parseModelString(value);
|
|
350
|
+
if (parsed) {
|
|
351
|
+
return available.find(model => model.provider === parsed.provider && model.id === parsed.id);
|
|
352
|
+
}
|
|
353
|
+
return parseModelPattern(value, available, matchPreferences).model;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Resolve a model from configured roles, honoring order and overrides.
|
|
358
|
+
*/
|
|
359
|
+
export function resolveModelFromSettings(options: {
|
|
360
|
+
settings: Settings;
|
|
361
|
+
availableModels: Model<Api>[];
|
|
362
|
+
matchPreferences?: ModelMatchPreferences;
|
|
363
|
+
roleOrder?: readonly ModelRole[];
|
|
364
|
+
}): Model<Api> | undefined {
|
|
365
|
+
const { settings, availableModels, matchPreferences, roleOrder } = options;
|
|
366
|
+
const roles = roleOrder ?? MODEL_ROLE_IDS;
|
|
367
|
+
for (const role of roles) {
|
|
368
|
+
const configured = settings.getModelRole(role);
|
|
369
|
+
if (!configured) continue;
|
|
370
|
+
const resolved = resolveModelFromString(expandRoleAlias(configured, settings), availableModels, matchPreferences);
|
|
371
|
+
if (resolved) return resolved;
|
|
372
|
+
}
|
|
373
|
+
return availableModels[0];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Resolve a list of override patterns to the first matching model.
|
|
378
|
+
*/
|
|
379
|
+
export function resolveModelOverride(
|
|
380
|
+
modelPatterns: string[],
|
|
381
|
+
modelRegistry: ModelRegistry,
|
|
382
|
+
settings?: Settings,
|
|
383
|
+
): { model?: Model<Api>; thinkingLevel?: ThinkingLevel } {
|
|
384
|
+
if (modelPatterns.length === 0) return {};
|
|
385
|
+
const matchPreferences = { usageOrder: settings?.getStorage()?.getModelUsageOrder() };
|
|
386
|
+
for (const pattern of modelPatterns) {
|
|
387
|
+
const normalized = pattern.trim();
|
|
388
|
+
if (!normalized || isDefaultModelAlias(normalized)) {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const effectivePattern = expandRoleAlias(pattern, settings);
|
|
392
|
+
const { model, thinkingLevel } = parseModelPattern(
|
|
393
|
+
effectivePattern,
|
|
394
|
+
modelRegistry.getAvailable(),
|
|
395
|
+
matchPreferences,
|
|
396
|
+
);
|
|
397
|
+
if (model) {
|
|
398
|
+
return { model, thinkingLevel: thinkingLevel !== "off" ? thinkingLevel : undefined };
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return {};
|
|
402
|
+
}
|
|
403
|
+
|
|
313
404
|
/**
|
|
314
405
|
* Resolve model patterns to actual Model objects with optional thinking levels
|
|
315
406
|
* Format: "pattern:level" where :level is optional
|
|
@@ -329,6 +329,26 @@ export const SETTINGS_SCHEMA = {
|
|
|
329
329
|
default: true,
|
|
330
330
|
ui: { tab: "tools", label: "Enable Grep", description: "Enable the grep tool for content searching" },
|
|
331
331
|
},
|
|
332
|
+
"grep.contextBefore": {
|
|
333
|
+
type: "number",
|
|
334
|
+
default: 1,
|
|
335
|
+
ui: {
|
|
336
|
+
tab: "tools",
|
|
337
|
+
label: "Grep context before",
|
|
338
|
+
description: "Lines of context before each grep match",
|
|
339
|
+
submenu: true,
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
"grep.contextAfter": {
|
|
343
|
+
type: "number",
|
|
344
|
+
default: 3,
|
|
345
|
+
ui: {
|
|
346
|
+
tab: "tools",
|
|
347
|
+
label: "Grep context after",
|
|
348
|
+
description: "Lines of context after each grep match",
|
|
349
|
+
submenu: true,
|
|
350
|
+
},
|
|
351
|
+
},
|
|
332
352
|
"notebook.enabled": {
|
|
333
353
|
type: "boolean",
|
|
334
354
|
default: true,
|
|
@@ -360,7 +380,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
360
380
|
},
|
|
361
381
|
"browser.enabled": {
|
|
362
382
|
type: "boolean",
|
|
363
|
-
default:
|
|
383
|
+
default: true,
|
|
364
384
|
ui: {
|
|
365
385
|
tab: "tools",
|
|
366
386
|
label: "Enable Browser",
|
|
@@ -485,7 +505,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
485
505
|
// ─────────────────────────────────────────────────────────────────────────
|
|
486
506
|
"providers.webSearch": {
|
|
487
507
|
type: "enum",
|
|
488
|
-
values: ["auto", "exa", "perplexity", "anthropic"] as const,
|
|
508
|
+
values: ["auto", "exa", "jina", "perplexity", "anthropic"] as const,
|
|
489
509
|
default: "auto",
|
|
490
510
|
ui: { tab: "services", label: "Web search provider", description: "Provider for web search tool", submenu: true },
|
|
491
511
|
},
|
package/src/config/settings.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import * as fs from "node:fs";
|
|
15
15
|
import * as path from "node:path";
|
|
16
|
+
import type { ModelRole } from "@oh-my-pi/pi-coding-agent/config/model-registry";
|
|
16
17
|
import { isEnoent, logger, procmgr } from "@oh-my-pi/pi-utils";
|
|
17
18
|
import { YAML } from "bun";
|
|
18
19
|
import { type Settings as SettingsCapabilityItem, settingsCapability } from "../capability/settings";
|
|
@@ -387,7 +388,7 @@ export class Settings {
|
|
|
387
388
|
/**
|
|
388
389
|
* Set a model role (helper for modelRoles record).
|
|
389
390
|
*/
|
|
390
|
-
setModelRole(role: string, modelId: string): void {
|
|
391
|
+
setModelRole(role: ModelRole | string, modelId: string): void {
|
|
391
392
|
const current = this.get("modelRoles");
|
|
392
393
|
this.set("modelRoles", { ...current, [role]: modelId });
|
|
393
394
|
}
|
|
@@ -395,11 +396,31 @@ export class Settings {
|
|
|
395
396
|
/**
|
|
396
397
|
* Get a model role (helper for modelRoles record).
|
|
397
398
|
*/
|
|
398
|
-
getModelRole(role: string): string | undefined {
|
|
399
|
+
getModelRole(role: ModelRole | string): string | undefined {
|
|
399
400
|
const roles = this.get("modelRoles");
|
|
400
401
|
return roles[role];
|
|
401
402
|
}
|
|
402
403
|
|
|
404
|
+
/**
|
|
405
|
+
* Get all model roles (helper for modelRoles record).
|
|
406
|
+
*/
|
|
407
|
+
getModelRoles(): ReadOnlyDict<string> {
|
|
408
|
+
return this.get("modelRoles");
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/*
|
|
412
|
+
* Override model roles (helper for modelRoles record).
|
|
413
|
+
*/
|
|
414
|
+
overrideModelRoles(roles: ReadOnlyDict<string>): void {
|
|
415
|
+
const prev = this.get("modelRoles");
|
|
416
|
+
for (const [role, modelId] of Object.entries(roles)) {
|
|
417
|
+
if (modelId) {
|
|
418
|
+
prev[role] = modelId;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
this.set("modelRoles", prev);
|
|
422
|
+
}
|
|
423
|
+
|
|
403
424
|
/**
|
|
404
425
|
* Set disabled providers (for compatibility with discovery system).
|
|
405
426
|
*/
|
package/src/cursor.ts
CHANGED
|
@@ -167,7 +167,7 @@ export class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
167
167
|
pattern: args.pattern,
|
|
168
168
|
path: args.path || undefined,
|
|
169
169
|
glob: args.glob || undefined,
|
|
170
|
-
|
|
170
|
+
mode: args.outputMode || undefined,
|
|
171
171
|
context: args.context ?? args.contextBefore ?? args.contextAfter ?? undefined,
|
|
172
172
|
ignore_case: args.caseInsensitive || undefined,
|
|
173
173
|
type: args.type || undefined,
|
|
@@ -51,7 +51,7 @@ export interface CustomToolContext {
|
|
|
51
51
|
/** Model registry - use for API key resolution and model retrieval */
|
|
52
52
|
modelRegistry: ModelRegistry;
|
|
53
53
|
/** Current model (may be undefined if no model is selected yet) */
|
|
54
|
-
model: Model
|
|
54
|
+
model: Model | undefined;
|
|
55
55
|
/** Whether the agent is idle (not streaming) */
|
|
56
56
|
isIdle(): boolean;
|
|
57
57
|
/** Whether there are queued messages waiting to be processed */
|
|
@@ -206,7 +206,7 @@ class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
|
206
206
|
return this.runtime.setActiveTools(toolNames);
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
setModel(model: Model
|
|
209
|
+
setModel(model: Model): Promise<boolean> {
|
|
210
210
|
return this.runtime.setModel(model);
|
|
211
211
|
}
|
|
212
212
|
|
|
@@ -112,7 +112,7 @@ export class ExtensionRunner {
|
|
|
112
112
|
private sessionManager: SessionManager;
|
|
113
113
|
private modelRegistry: ModelRegistry;
|
|
114
114
|
private errorListeners: Set<ExtensionErrorListener> = new Set();
|
|
115
|
-
private getModel: () => Model
|
|
115
|
+
private getModel: () => Model | undefined = () => undefined;
|
|
116
116
|
private isIdleFn: () => boolean = () => true;
|
|
117
117
|
private waitForIdleFn: () => Promise<void> = async () => {};
|
|
118
118
|
private abortFn: () => void = () => {};
|
|
@@ -162,7 +162,7 @@ export interface ExtensionContext {
|
|
|
162
162
|
/** Model registry for API key resolution */
|
|
163
163
|
modelRegistry: ModelRegistry;
|
|
164
164
|
/** Current model (may be undefined) */
|
|
165
|
-
model: Model
|
|
165
|
+
model: Model | undefined;
|
|
166
166
|
/** Whether the agent is idle (not streaming) */
|
|
167
167
|
isIdle(): boolean;
|
|
168
168
|
/** Abort the current agent operation */
|
|
@@ -776,7 +776,7 @@ export interface ExtensionAPI {
|
|
|
776
776
|
setActiveTools(toolNames: string[]): Promise<void>;
|
|
777
777
|
|
|
778
778
|
/** Set the current model. Returns false if no API key available. */
|
|
779
|
-
setModel(model: Model
|
|
779
|
+
setModel(model: Model): Promise<boolean>;
|
|
780
780
|
|
|
781
781
|
/** Get current thinking level. */
|
|
782
782
|
getThinkingLevel(): ThinkingLevel;
|
|
@@ -835,7 +835,7 @@ export type GetAllToolsHandler = () => string[];
|
|
|
835
835
|
|
|
836
836
|
export type SetActiveToolsHandler = (toolNames: string[]) => Promise<void>;
|
|
837
837
|
|
|
838
|
-
export type SetModelHandler = (model: Model
|
|
838
|
+
export type SetModelHandler = (model: Model) => Promise<boolean>;
|
|
839
839
|
|
|
840
840
|
export type GetThinkingLevelHandler = () => ThinkingLevel;
|
|
841
841
|
|
|
@@ -862,7 +862,7 @@ export interface ExtensionActions {
|
|
|
862
862
|
|
|
863
863
|
/** Actions for ExtensionContext (ctx.* in event handlers). */
|
|
864
864
|
export interface ExtensionContextActions {
|
|
865
|
-
getModel: () => Model
|
|
865
|
+
getModel: () => Model | undefined;
|
|
866
866
|
isIdle: () => boolean;
|
|
867
867
|
abort: () => void;
|
|
868
868
|
hasPendingMessages: () => boolean;
|
|
@@ -69,7 +69,7 @@ export class HookRunner {
|
|
|
69
69
|
private sessionManager: SessionManager;
|
|
70
70
|
private modelRegistry: ModelRegistry;
|
|
71
71
|
private errorListeners: Set<HookErrorListener> = new Set();
|
|
72
|
-
private getModel: () => Model
|
|
72
|
+
private getModel: () => Model | undefined = () => undefined;
|
|
73
73
|
private isIdleFn: () => boolean = () => true;
|
|
74
74
|
private waitForIdleFn: () => Promise<void> = async () => {};
|
|
75
75
|
private abortFn: () => void = () => {};
|
|
@@ -93,7 +93,7 @@ export class HookRunner {
|
|
|
93
93
|
*/
|
|
94
94
|
initialize(options: {
|
|
95
95
|
/** Function to get the current model */
|
|
96
|
-
getModel: () => Model
|
|
96
|
+
getModel: () => Model | undefined;
|
|
97
97
|
/** Handler for hooks to send messages */
|
|
98
98
|
sendMessageHandler: SendMessageHandler;
|
|
99
99
|
/** Handler for hooks to append entries */
|
|
@@ -147,7 +147,7 @@ export interface HookContext {
|
|
|
147
147
|
/** Model registry - use for API key resolution and model retrieval */
|
|
148
148
|
modelRegistry: ModelRegistry;
|
|
149
149
|
/** Current model (may be undefined if no model is selected yet) */
|
|
150
|
-
model: Model
|
|
150
|
+
model: Model | undefined;
|
|
151
151
|
/** Whether the agent is idle (not streaming) */
|
|
152
152
|
isIdle(): boolean;
|
|
153
153
|
/** Abort the current agent operation (fire-and-forget, does not wait) */
|
package/src/main.ts
CHANGED
|
@@ -391,8 +391,7 @@ async function buildSessionOptions(
|
|
|
391
391
|
process.exit(1);
|
|
392
392
|
}
|
|
393
393
|
options.model = model;
|
|
394
|
-
|
|
395
|
-
settings.override("modelRoles", { ...currentRoles, default: `${model.provider}/${model.id}` });
|
|
394
|
+
settings.overrideModelRoles({ default: `${model.provider}/${model.id}` });
|
|
396
395
|
} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {
|
|
397
396
|
const remembered = settings.getModelRole("default");
|
|
398
397
|
if (remembered) {
|