@oh-my-pi/pi-coding-agent 17.1.1 → 17.1.3

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.
Files changed (105) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/cli.js +6317 -4085
  3. package/dist/types/cli/bench-cli.d.ts +1 -0
  4. package/dist/types/config/model-resolver.d.ts +6 -3
  5. package/dist/types/config/settings-schema.d.ts +4 -0
  6. package/dist/types/launch/broker-list-order.test.d.ts +1 -0
  7. package/dist/types/modes/interactive-mode.d.ts +2 -6
  8. package/dist/types/modes/types.d.ts +8 -5
  9. package/dist/types/modes/utils/ui-helpers.d.ts +1 -6
  10. package/dist/types/task/executor.d.ts +3 -1
  11. package/dist/types/task/structured-subagent.d.ts +3 -0
  12. package/dist/types/task/types.d.ts +11 -11
  13. package/dist/types/thinking.d.ts +13 -0
  14. package/dist/types/tools/auto-generated-guard.d.ts +5 -2
  15. package/dist/types/tools/eval-format/index.d.ts +7 -0
  16. package/dist/types/tools/eval-format/javascript.d.ts +2 -0
  17. package/dist/types/tools/eval-format/julia.d.ts +2 -0
  18. package/dist/types/tools/eval-format/python.d.ts +2 -0
  19. package/dist/types/tools/eval-format/ruby.d.ts +2 -0
  20. package/dist/types/tools/memory-render.d.ts +1 -4
  21. package/dist/types/tools/resolve.d.ts +7 -0
  22. package/dist/types/tools/todo.d.ts +4 -1
  23. package/dist/types/web/search/providers/base.d.ts +16 -0
  24. package/dist/types/web/search/providers/brave.d.ts +2 -0
  25. package/dist/types/web/search/providers/firecrawl.d.ts +2 -0
  26. package/dist/types/web/search/providers/gemini.d.ts +3 -0
  27. package/dist/types/web/search/providers/jina.d.ts +2 -0
  28. package/dist/types/web/search/providers/kagi.d.ts +2 -0
  29. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  30. package/dist/types/web/search/providers/parallel.d.ts +2 -0
  31. package/dist/types/web/search/providers/perplexity.d.ts +3 -0
  32. package/dist/types/web/search/providers/searxng.d.ts +10 -0
  33. package/dist/types/web/search/providers/tavily.d.ts +8 -0
  34. package/dist/types/web/search/query.d.ts +190 -0
  35. package/package.json +12 -12
  36. package/src/cli/bench-cli.ts +12 -1
  37. package/src/cli/web-search-cli.ts +7 -0
  38. package/src/config/model-resolver.ts +17 -6
  39. package/src/config/settings-schema.ts +5 -0
  40. package/src/debug/raw-sse-buffer.ts +157 -30
  41. package/src/edit/hashline/filesystem.ts +1 -1
  42. package/src/edit/modes/patch.ts +1 -1
  43. package/src/export/share.ts +4 -3
  44. package/src/launch/broker-list-order.test.ts +89 -0
  45. package/src/launch/broker.ts +49 -8
  46. package/src/modes/controllers/input-controller.ts +8 -8
  47. package/src/modes/interactive-mode.ts +60 -5
  48. package/src/modes/types.ts +9 -4
  49. package/src/modes/utils/ui-helpers.ts +7 -8
  50. package/src/prompts/system/resolve-device-reminder.md +1 -1
  51. package/src/prompts/system/workflow-notice.md +1 -1
  52. package/src/prompts/tools/ast-edit.md +2 -1
  53. package/src/prompts/tools/bash.md +1 -0
  54. package/src/prompts/tools/eval.md +2 -2
  55. package/src/prompts/tools/task.md +5 -2
  56. package/src/prompts/tools/web-search.md +2 -0
  57. package/src/sdk.ts +8 -4
  58. package/src/session/agent-session.ts +14 -0
  59. package/src/session/queued-messages.ts +7 -1
  60. package/src/session/stream-guards.ts +1 -1
  61. package/src/task/executor.ts +17 -9
  62. package/src/task/index.ts +14 -34
  63. package/src/task/structured-subagent.ts +4 -0
  64. package/src/task/types.ts +15 -13
  65. package/src/thinking.ts +27 -0
  66. package/src/tools/ast-edit.ts +4 -1
  67. package/src/tools/auto-generated-guard.ts +18 -5
  68. package/src/tools/bash.ts +13 -0
  69. package/src/tools/browser/render.ts +2 -1
  70. package/src/tools/eval-format/index.ts +24 -0
  71. package/src/tools/eval-format/javascript.ts +952 -0
  72. package/src/tools/eval-format/julia.ts +446 -0
  73. package/src/tools/eval-format/python.ts +544 -0
  74. package/src/tools/eval-format/ruby.ts +380 -0
  75. package/src/tools/eval-render.ts +12 -6
  76. package/src/tools/memory-render.ts +11 -2
  77. package/src/tools/render-utils.ts +8 -3
  78. package/src/tools/resolve.ts +10 -1
  79. package/src/tools/todo.ts +58 -6
  80. package/src/tools/write.ts +1 -1
  81. package/src/web/search/index.ts +28 -5
  82. package/src/web/search/providers/anthropic.ts +62 -4
  83. package/src/web/search/providers/base.ts +16 -0
  84. package/src/web/search/providers/brave.ts +30 -3
  85. package/src/web/search/providers/codex.ts +14 -1
  86. package/src/web/search/providers/duckduckgo.ts +23 -1
  87. package/src/web/search/providers/ecosia.ts +5 -1
  88. package/src/web/search/providers/exa.ts +28 -1
  89. package/src/web/search/providers/firecrawl.ts +37 -3
  90. package/src/web/search/providers/gemini.ts +12 -2
  91. package/src/web/search/providers/google.ts +2 -1
  92. package/src/web/search/providers/jina.ts +31 -8
  93. package/src/web/search/providers/kagi.ts +10 -1
  94. package/src/web/search/providers/kimi.ts +16 -1
  95. package/src/web/search/providers/mojeek.ts +14 -1
  96. package/src/web/search/providers/parallel.ts +48 -2
  97. package/src/web/search/providers/perplexity.ts +94 -6
  98. package/src/web/search/providers/searxng.ts +145 -9
  99. package/src/web/search/providers/startpage.ts +8 -2
  100. package/src/web/search/providers/synthetic.ts +7 -1
  101. package/src/web/search/providers/tavily.ts +52 -3
  102. package/src/web/search/providers/tinyfish.ts +6 -1
  103. package/src/web/search/providers/xai.ts +49 -2
  104. package/src/web/search/providers/zai.ts +19 -1
  105. package/src/web/search/query.ts +850 -0
@@ -21,6 +21,7 @@ export interface BenchCommandArgs {
21
21
  }
22
22
  export interface BenchModelRegistry {
23
23
  getAll(): Model<Api>[];
24
+ getAvailable(): Model<Api>[];
24
25
  getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined>;
25
26
  resolver(model: ApiKeyResolverModel, sessionId?: string): ApiKeyResolver;
26
27
  hasConfiguredAuth?(model: Model<Api>): boolean;
@@ -78,7 +78,7 @@ export interface ModelMatchPreferences {
78
78
  deprioritizeProviders?: string[];
79
79
  }
80
80
  export type ModelLookupRegistry = Pick<ModelRegistry, "getAvailable">;
81
- type CliModelRegistry = Pick<ModelRegistry, "getAll">;
81
+ type CliModelRegistry = Pick<ModelRegistry, "getAll" | "getAvailable">;
82
82
  type InitialModelRegistry = Pick<ModelRegistry, "getAvailable" | "find">;
83
83
  type RestorableModelRegistry = Pick<ModelRegistry, "getAvailable" | "find" | "getApiKey">;
84
84
  export declare function getModelMatchPreferences(settings?: Partial<Pick<Settings, "get" | "getStorage">>): ModelMatchPreferences;
@@ -279,13 +279,16 @@ export interface ResolveCliModelResult {
279
279
  /**
280
280
  * Resolve a single model from CLI flags.
281
281
  *
282
- * Exact model names take precedence over configured role names.
282
+ * Explicit `provider/id` references and authenticated bare ids take precedence
283
+ * over configured role names, which in turn take precedence over an
284
+ * unauthenticated catalog-only id (so a bundled `cursor/default` never shadows a
285
+ * configured `modelRoles.default`).
283
286
  */
284
287
  export declare function resolveCliModel(options: {
285
288
  cliProvider?: string;
286
289
  cliModel?: string;
287
290
  modelRegistry: CliModelRegistry;
288
- /** Authenticated models to prefer for unqualified selectors; omit to preserve catalog-order behavior. */
291
+ /** Authenticated models to prefer for unqualified selectors; defaults to the registry's authenticated set. */
289
292
  availableModels?: Model<Api>[];
290
293
  settings?: Settings;
291
294
  preferences?: ModelMatchPreferences;
@@ -5811,6 +5811,10 @@ export declare const SETTINGS_SCHEMA: {
5811
5811
  readonly type: "string";
5812
5812
  readonly default: undefined;
5813
5813
  };
5814
+ readonly "searxng.engines": {
5815
+ readonly type: "string";
5816
+ readonly default: undefined;
5817
+ };
5814
5818
  readonly "searxng.language": {
5815
5819
  readonly type: "string";
5816
5820
  readonly default: undefined;
@@ -0,0 +1 @@
1
+ export {};
@@ -36,7 +36,7 @@ import { type LoopLimitRuntime } from "./loop-limit.js";
36
36
  import { OAuthManualInputManager } from "./oauth-manual-input.js";
37
37
  import { type ObservableSession } from "./session-observer-registry.js";
38
38
  import type { Theme } from "./theme/theme.js";
39
- import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types.js";
39
+ import type { CompactionQueuedMessage, InteractiveModeContext, InteractiveModeInitOptions, InteractiveSelectorDialogOptions, RenderSessionContextOptions, SubmittedUserInput, TodoItem, TodoPhase } from "./types.js";
40
40
  /**
41
41
  * Editor max-height cap for a terminal of `terminalRows` rows.
42
42
  *
@@ -309,11 +309,7 @@ export declare class InteractiveMode implements InteractiveModeContext {
309
309
  imageLinks?: readonly (string | undefined)[];
310
310
  reuseSettledComponent?: boolean;
311
311
  }): Component[];
312
- renderSessionContext(sessionContext: SessionContext, options?: {
313
- updateFooter?: boolean;
314
- populateHistory?: boolean;
315
- reuseSettledComponents?: boolean;
316
- }): void;
312
+ renderSessionContext(sessionContext: SessionContext, options?: RenderSessionContextOptions): void;
317
313
  renderInitialMessages(options?: {
318
314
  preserveExistingChat?: boolean;
319
315
  clearTerminalHistory?: boolean;
@@ -77,6 +77,13 @@ export interface InteractiveModeInitOptions {
77
77
  clearInitialTerminalHistory?: boolean;
78
78
  }
79
79
  export type InteractiveSelectorDialogOptions = ExtensionUIDialogOptions & Pick<HookSelectorOptions, "disabledIndices">;
80
+ export interface RenderSessionContextOptions {
81
+ updateFooter?: boolean;
82
+ populateHistory?: boolean;
83
+ reuseSettledComponents?: boolean;
84
+ /** Tool calls whose existing live component remains the sole render owner across a rebuild. */
85
+ preservedLiveToolCallIds?: ReadonlySet<string>;
86
+ }
80
87
  export interface InteractiveModeContext {
81
88
  ui: TUI;
82
89
  chatContainer: TranscriptContainer;
@@ -284,11 +291,7 @@ export interface InteractiveModeContext {
284
291
  imageLinks?: readonly (string | undefined)[];
285
292
  reuseSettledComponent?: boolean;
286
293
  }): Component[];
287
- renderSessionContext(sessionContext: SessionContext, options?: {
288
- updateFooter?: boolean;
289
- populateHistory?: boolean;
290
- reuseSettledComponents?: boolean;
291
- }): void;
294
+ renderSessionContext(sessionContext: SessionContext, options?: RenderSessionContextOptions): void;
292
295
  renderInitialMessages(options?: {
293
296
  preserveExistingChat?: boolean;
294
297
  clearTerminalHistory?: boolean;
@@ -1,7 +1,7 @@
1
1
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
2
  import type { AssistantMessage, ImageContent, Message } from "@oh-my-pi/pi-ai";
3
3
  import { type Component } from "@oh-my-pi/pi-tui";
4
- import type { InteractiveModeContext } from "../../modes/types.js";
4
+ import type { InteractiveModeContext, RenderSessionContextOptions } from "../../modes/types.js";
5
5
  import type { SessionContext } from "../../session/session-context.js";
6
6
  interface RenderInitialMessagesOptions {
7
7
  preserveExistingChat?: boolean;
@@ -12,11 +12,6 @@ type AddMessageOptions = {
12
12
  imageLinks?: readonly (string | undefined)[];
13
13
  reuseSettledComponent?: boolean;
14
14
  };
15
- type RenderSessionContextOptions = {
16
- updateFooter?: boolean;
17
- populateHistory?: boolean;
18
- reuseSettledComponents?: boolean;
19
- };
20
15
  export declare class UiHelpers {
21
16
  #private;
22
17
  private ctx;
@@ -21,7 +21,7 @@ import { type AgentReviver } from "../registry/agent-lifecycle.js";
21
21
  import type { AgentSession } from "../session/agent-session.js";
22
22
  import type { ArtifactManager } from "../session/artifacts.js";
23
23
  import type { AuthStorage } from "../session/auth-storage.js";
24
- import type { ConfiguredThinkingLevel } from "../thinking.js";
24
+ import { type ConfiguredThinkingLevel, type TaskEffort } from "../thinking.js";
25
25
  import type { ContextFileEntry } from "../tools/index.js";
26
26
  import type { EventBus } from "../utils/event-bus.js";
27
27
  import type { WorkspaceTree } from "../workspace-tree.js";
@@ -81,6 +81,8 @@ export interface ExecutorOptions {
81
81
  */
82
82
  parentActiveModelPattern?: string;
83
83
  thinkingLevel?: ConfiguredThinkingLevel;
84
+ /** Caller-requested coarse effort (`lo`/`med`/`hi`); maps onto the resolved model's supported thinking range and wins over {@link thinkingLevel}. */
85
+ effort?: TaskEffort;
84
86
  /** Schema used to validate the final structured completion. */
85
87
  outputSchema?: unknown;
86
88
  /** Enforcement policy for {@link outputSchema}; defaults to legacy permissive behavior. */
@@ -1,3 +1,4 @@
1
+ import type { TaskEffort } from "../thinking.js";
1
2
  import type { ToolSession } from "../tools/index.js";
2
3
  import { type DiscoveryResult } from "./discovery.js";
3
4
  import { type AgentDefinition, type AgentProgress, type SingleResult, type StructuredSubagentOutput } from "./types.js";
@@ -40,6 +41,8 @@ export interface StructuredSubagentRequest {
40
41
  /** Presence, rather than truthiness, makes this the highest-priority schema. */
41
42
  outputSchema?: unknown;
42
43
  schemaMode?: StructuredSubagentSchemaMode;
44
+ /** Per-spawn thinking effort mapped onto the resolved model's supported range; overrides the agent's default selector. */
45
+ effort?: TaskEffort;
43
46
  identity?: StructuredSubagentIdentity;
44
47
  index?: number;
45
48
  parentToolCallId?: string;
@@ -1,7 +1,7 @@
1
1
  import type { Usage } from "@oh-my-pi/pi-ai";
2
2
  import { type BaseType } from "arktype";
3
3
  import type { AgentSessionEvent } from "../session/agent-session.js";
4
- import type { ConfiguredThinkingLevel } from "../thinking.js";
4
+ import type { ConfiguredThinkingLevel, TaskEffort } from "../thinking.js";
5
5
  import type { NestedRepoPatch } from "./worktree.js";
6
6
  /** Source of an agent definition */
7
7
  export type AgentSource = "bundled" | "user" | "project";
@@ -83,7 +83,7 @@ export declare const taskItemSchema: import("arktype/internal/variants/object.ts
83
83
  name?: string | undefined;
84
84
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
85
85
  task: string;
86
- model?: string | string[] | undefined;
86
+ effort?: "hi" | "lo" | "med" | undefined;
87
87
  outputSchema?: string | boolean | object | null | undefined;
88
88
  schemaMode?: "permissive" | "strict" | undefined;
89
89
  }, {}>;
@@ -95,8 +95,8 @@ export interface TaskItem {
95
95
  agent?: string;
96
96
  /** The work; required by the schema. */
97
97
  task?: string;
98
- /** Explicit model selector or fallback chain for this spawn, including optional reasoning suffixes. */
99
- model?: string | string[];
98
+ /** Per-spawn thinking effort: lowest/middle/highest level the resolved model supports. Overrides the agent's default selector (e.g. `auto`). */
99
+ effort?: TaskEffort;
100
100
  /** Caller-provided output schema; its presence overrides the selected agent's schema. */
101
101
  outputSchema?: unknown;
102
102
  /** Validation behavior for a caller-provided or inherited output schema. */
@@ -108,7 +108,7 @@ export declare const taskSchema: import("arktype/internal/variants/object.ts").O
108
108
  name?: string | undefined;
109
109
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
110
110
  task: string;
111
- model?: string | string[] | undefined;
111
+ effort?: "hi" | "lo" | "med" | undefined;
112
112
  outputSchema?: string | boolean | object | null | undefined;
113
113
  schemaMode?: "permissive" | "strict" | undefined;
114
114
  isolated?: boolean | undefined;
@@ -117,7 +117,7 @@ declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/obje
117
117
  name?: string | undefined;
118
118
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
119
119
  task: string;
120
- model?: string | string[] | undefined;
120
+ effort?: "hi" | "lo" | "med" | undefined;
121
121
  outputSchema?: string | boolean | object | null | undefined;
122
122
  schemaMode?: "permissive" | "strict" | undefined;
123
123
  isolated?: boolean | undefined;
@@ -125,7 +125,7 @@ declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/obje
125
125
  name?: string | undefined;
126
126
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
127
127
  task: string;
128
- model?: string | string[] | undefined;
128
+ effort?: "hi" | "lo" | "med" | undefined;
129
129
  outputSchema?: string | boolean | object | null | undefined;
130
130
  schemaMode?: "permissive" | "strict" | undefined;
131
131
  }, {}>, import("arktype/internal/variants/object.ts").ObjectType<{
@@ -134,7 +134,7 @@ declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/obje
134
134
  name?: string | undefined;
135
135
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
136
136
  task: string;
137
- model?: string | string[] | undefined;
137
+ effort?: "hi" | "lo" | "med" | undefined;
138
138
  outputSchema?: string | boolean | object | null | undefined;
139
139
  schemaMode?: "permissive" | "strict" | undefined;
140
140
  isolated?: boolean | undefined;
@@ -145,7 +145,7 @@ declare const ALL_TASK_SCHEMAS: readonly [import("arktype/internal/variants/obje
145
145
  name?: string | undefined;
146
146
  agent: import("arktype/internal/attributes.ts").Default<string, "task">;
147
147
  task: string;
148
- model?: string | string[] | undefined;
148
+ effort?: "hi" | "lo" | "med" | undefined;
149
149
  outputSchema?: string | boolean | object | null | undefined;
150
150
  schemaMode?: "permissive" | "strict" | undefined;
151
151
  }[];
@@ -176,8 +176,8 @@ export interface TaskParams {
176
176
  agent?: string;
177
177
  /** The work (flat form). */
178
178
  task?: string;
179
- /** Explicit model selector or fallback chain for the spawn, including optional reasoning suffixes. */
180
- model?: string | string[];
179
+ /** Per-spawn thinking effort (flat form): lowest/middle/highest level the resolved model supports. */
180
+ effort?: TaskEffort;
181
181
  /** Caller-provided output schema; its presence overrides the selected agent's schema. */
182
182
  outputSchema?: unknown;
183
183
  /** Validation behavior for a caller-provided or inherited output schema. */
@@ -88,6 +88,19 @@ export declare function parseCliThinkingLevel(value: string | null | undefined):
88
88
  * downstream.
89
89
  */
90
90
  export declare function clampAutoThinkingEffort(model: Model | undefined, effort: Effort): Effort | undefined;
91
+ /** Coarse per-spawn effort selectors accepted by the task tool. */
92
+ export declare const TASK_EFFORTS: readonly ["lo", "med", "hi"];
93
+ /** Coarse task-spawn effort: the lowest, middle, or highest thinking level the target model supports. */
94
+ export type TaskEffort = (typeof TASK_EFFORTS)[number];
95
+ /**
96
+ * Maps a coarse task effort onto the model's supported thinking range:
97
+ * `lo` = lowest supported level, `hi` = highest (whatever the model tops out
98
+ * at — high, xhigh, or max), `med` = the middle (lower of the two middles for
99
+ * an even-sized range). Without a model, maps over the full canonical range.
100
+ * Returns `undefined` when the model has no controllable effort surface, so
101
+ * callers fall back to their default selector (e.g. `auto`).
102
+ */
103
+ export declare function resolveTaskEffortLevel(model: Model | undefined, effort: TaskEffort): Effort | undefined;
91
104
  /**
92
105
  * The provisional concrete level shown while `auto` is configured but before a
93
106
  * turn has been classified. Prefers the model's `defaultLevel`, otherwise High,
@@ -1,11 +1,13 @@
1
+ import { type Settings } from "../config/settings.js";
1
2
  /**
2
3
  * Check if a file is auto-generated by examining its content.
3
4
  * Throws ToolError if the file appears to be auto-generated.
4
5
  *
5
6
  * @param absolutePath - Absolute path to the file
6
7
  * @param displayPath - Path to show in error messages (relative or as provided)
8
+ * @param activeSettings - Session settings; falls back to global settings or the schema default
7
9
  */
8
- export declare function assertEditableFile(absolutePath: string, displayPath?: string): Promise<void>;
10
+ export declare function assertEditableFile(absolutePath: string, displayPath?: string, activeSettings?: Settings): Promise<void>;
9
11
  /**
10
12
  * Check if file content is auto-generated.
11
13
  * Uses only the first CHECK_BYTE_COUNT characters of the content.
@@ -13,5 +15,6 @@ export declare function assertEditableFile(absolutePath: string, displayPath?: s
13
15
  *
14
16
  * @param content - File content to check (can be full content or prefix)
15
17
  * @param displayPath - Path to show in error messages
18
+ * @param activeSettings - Session settings; falls back to global settings or the schema default
16
19
  */
17
- export declare function assertEditableFileContent(content: string, displayPath: string): void;
20
+ export declare function assertEditableFileContent(content: string, displayPath: string, activeSettings?: Settings): void;
@@ -0,0 +1,7 @@
1
+ import type { EvalLanguage } from "../../eval/types.js";
2
+ export * from "./javascript.js";
3
+ export * from "./julia.js";
4
+ export * from "./python.js";
5
+ export * from "./ruby.js";
6
+ /** Formats an arbitrary eval-code prefix for display without changing the executed source. */
7
+ export declare function formatEvalCodeForDisplay(source: string, language: EvalLanguage): string;
@@ -0,0 +1,2 @@
1
+ /** Formats JavaScript/TypeScript-like eval source for safe, stable display without requiring valid syntax. */
2
+ export declare function formatJavaScriptForDisplay(source: string): string;
@@ -0,0 +1,2 @@
1
+ /** Formats an arbitrary Julia source prefix for stable, readable display. */
2
+ export declare function formatJuliaForDisplay(source: string): string;
@@ -0,0 +1,2 @@
1
+ /** Formats an arbitrary Python source prefix for stable, readable display. */
2
+ export declare function formatPythonForDisplay(source: string): string;
@@ -0,0 +1,2 @@
1
+ /** Formats an arbitrary Ruby source prefix for display without requiring valid syntax. */
2
+ export declare function formatRubyForDisplay(source: string): string;
@@ -13,10 +13,7 @@ import type { Component } from "@oh-my-pi/pi-tui";
13
13
  import type { RenderResultOptions } from "../extensibility/custom-tools/types.js";
14
14
  import type { Theme } from "../modes/theme/theme.js";
15
15
  interface RetainRenderArgs {
16
- items?: Array<{
17
- content?: string;
18
- context?: string;
19
- }>;
16
+ items?: unknown;
20
17
  }
21
18
  interface QueryRenderArgs {
22
19
  query?: string;
@@ -27,6 +27,13 @@ export declare const PROPOSE_DEVICE_NAME = "propose";
27
27
  export declare const RESOLVE_DEVICE_PATH = "xd://resolve";
28
28
  export declare const REJECT_DEVICE_PATH = "xd://reject";
29
29
  export declare const PROPOSE_DEVICE_PATH = "xd://propose";
30
+ /**
31
+ * Model-visible banner prepended to a staged preview's tool result text. The
32
+ * TUI badge (`⟨proposed⟩`) never reaches the model, and preview diffs are
33
+ * byte-identical to applied-edit output — without this line the model reads
34
+ * the result as an already-applied change.
35
+ */
36
+ export declare const PREVIEW_PENDING_NOTICE = "Staged as a proposal \u2014 files NOT modified yet. To apply: write a one-sentence reason to xd://resolve. To discard: write to xd://reject.";
30
37
  export type ResolutionDeviceName = typeof RESOLVE_DEVICE_NAME | typeof REJECT_DEVICE_NAME | typeof PROPOSE_DEVICE_NAME;
31
38
  /** Whether an xd:// device name is one of the plain-text resolution devices. */
32
39
  export declare function isResolutionDeviceName(name: string): name is ResolutionDeviceName;
@@ -44,6 +44,8 @@ declare const todoSchema: import("arktype/internal/variants/object.ts").ObjectTy
44
44
  }, {}>;
45
45
  type TodoParams = TodoSchema;
46
46
  type TodoSchema = typeof todoSchema.infer;
47
+ /** A single todo op entry (the params object itself). */
48
+ type TodoOpEntryValue = TodoParams;
47
49
  /** Return the active todo task, preferring an in-progress item over the first pending item. */
48
50
  export declare function nextActionableTask(phases: readonly TodoPhase[]): TodoItem | undefined;
49
51
  export declare const USER_TODO_EDIT_CUSTOM_TYPE = "user_todo_edit";
@@ -92,7 +94,7 @@ export declare function selectCollapsedTodos<T extends {
92
94
  status: TodoStatus;
93
95
  }>(tasks: T[], isMatched: (task: T) => boolean, cap: number): CollapsedTodoSelection<T>;
94
96
  /** Apply an array of `todo`-style ops to existing phases. Used by /todo slash command. */
95
- export declare function applyOpsToPhases(currentPhases: TodoPhase[], ops: TodoParams[]): {
97
+ export declare function applyOpsToPhases(currentPhases: TodoPhase[], ops: TodoOpEntryValue[]): {
96
98
  phases: TodoPhase[];
97
99
  errors: string[];
98
100
  };
@@ -124,6 +126,7 @@ export declare class TodoTool implements AgentTool<typeof todoSchema, TodoToolDe
124
126
  }, {}>;
125
127
  readonly concurrency = "exclusive";
126
128
  readonly strict = true;
129
+ readonly lenientArgValidation = true;
127
130
  readonly examples: readonly ToolExample<typeof todoSchema.infer>[];
128
131
  readonly loadMode = "discoverable";
129
132
  constructor(session: ToolSession);
@@ -1,5 +1,6 @@
1
1
  import type { AuthStorage, FetchImpl } from "@oh-my-pi/pi-ai";
2
2
  import type { ModelRegistry } from "../../../config/model-registry.js";
3
+ import type { StructuredQuery } from "../query.js";
3
4
  import type { SearchProviderId, SearchResponse } from "../types.js";
4
5
  /**
5
6
  * Shared web search parameters passed to providers.
@@ -13,6 +14,21 @@ import type { SearchProviderId, SearchResponse } from "../types.js";
13
14
  */
14
15
  export interface SearchParams {
15
16
  query: string;
17
+ /**
18
+ * Structured view of `query`, parsed once by the search pipeline:
19
+ * Google-style directives (`site:`, `before:`/`after:`, `inurl:`,
20
+ * `intitle:`, `filetype:`, quoted phrases, `OR` groups, `-exclusions`)
21
+ * extracted into fields.
22
+ *
23
+ * Providers SHOULD map constraints onto native API parameters
24
+ * (domain/date filters) or engine query syntax (`formatQuery`) where the
25
+ * upstream supports them, and lean lenient otherwise: the pipeline
26
+ * post-filters every response with `applyQueryConstraints`, which
27
+ * relaxes any constraint that would eliminate all results — so a
28
+ * best-effort search always beats an empty one. When absent (direct
29
+ * provider calls), parse with `parseSearchQuery(params.query)`.
30
+ */
31
+ parsedQuery?: StructuredQuery;
16
32
  limit?: number;
17
33
  /**
18
34
  * Temporal filter narrowing results to the specified time window.
@@ -6,12 +6,14 @@
6
6
  */
7
7
  import { type AuthStorage, type FetchImpl } from "@oh-my-pi/pi-ai";
8
8
  import type { SearchResponse } from "../../../web/search/types.js";
9
+ import type { StructuredQuery } from "../query.js";
9
10
  import type { SearchParams } from "./base.js";
10
11
  import { SearchProvider } from "./base.js";
11
12
  export interface BraveSearchParams {
12
13
  query: string;
13
14
  num_results?: number;
14
15
  recency?: "day" | "week" | "month" | "year";
16
+ parsedQuery?: StructuredQuery;
15
17
  signal?: AbortSignal;
16
18
  fetch?: FetchImpl;
17
19
  }
@@ -12,6 +12,8 @@ export interface FirecrawlSearchParams {
12
12
  query: string;
13
13
  num_results?: number;
14
14
  recency?: SearchParams["recency"];
15
+ /** Explicit `tbs` (custom date range); takes precedence over `recency`. */
16
+ tbs?: string;
15
17
  signal?: AbortSignal;
16
18
  fetch?: FetchImpl;
17
19
  }
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { type AuthStorage, type FetchImpl, type OAuthAccess } from "@oh-my-pi/pi-ai";
12
12
  import type { SearchResponse } from "../../../web/search/types.js";
13
+ import { type StructuredQuery } from "../query.js";
13
14
  import type { SearchParams } from "./base.js";
14
15
  import { SearchProvider } from "./base.js";
15
16
  declare const GEMINI_PROVIDERS: readonly ["google-gemini-cli", "google-antigravity"];
@@ -21,6 +22,8 @@ interface GeminiToolParams {
21
22
  }
22
23
  export interface GeminiSearchParams extends GeminiToolParams {
23
24
  query: string;
25
+ /** Pre-parsed structured query; falls back to parsing `query` when omitted. */
26
+ parsedQuery?: StructuredQuery;
24
27
  system_prompt?: string;
25
28
  num_results?: number;
26
29
  /** Maximum output tokens. */
@@ -14,6 +14,8 @@ type SearchParamsWithFetch = SearchParams & {
14
14
  export interface JinaSearchParams {
15
15
  query: string;
16
16
  num_results?: number;
17
+ /** Single bare host for Jina's `X-Site` in-site search header. */
18
+ site?: string;
17
19
  signal?: AbortSignal;
18
20
  fetch?: FetchImpl;
19
21
  }
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import type { AuthStorage, FetchImpl } from "@oh-my-pi/pi-ai";
7
7
  import type { SearchResponse } from "../../../web/search/types.js";
8
+ import type { StructuredQuery } from "../query.js";
8
9
  import type { SearchParams } from "./base.js";
9
10
  import { SearchProvider } from "./base.js";
10
11
  type SearchParamsWithFetch = SearchParams & {
@@ -15,6 +16,7 @@ export declare function searchKagi(params: {
15
16
  query: string;
16
17
  num_results?: number;
17
18
  recency?: SearchParams["recency"];
19
+ parsedQuery?: StructuredQuery;
18
20
  signal?: AbortSignal;
19
21
  authStorage: AuthStorage;
20
22
  sessionId?: string;
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import { type AuthStorage, type FetchImpl } from "@oh-my-pi/pi-ai";
11
11
  import type { SearchResponse } from "../../../web/search/types.js";
12
+ import { type StructuredQuery } from "../query.js";
12
13
  import type { SearchParams } from "./base.js";
13
14
  import { SearchProvider } from "./base.js";
14
15
  type SearchParamsWithFetch = SearchParams & {
@@ -16,6 +17,7 @@ type SearchParamsWithFetch = SearchParams & {
16
17
  };
17
18
  export interface KimiSearchParams {
18
19
  query: string;
20
+ parsedQuery?: StructuredQuery;
19
21
  num_results?: number;
20
22
  include_content?: boolean;
21
23
  signal?: AbortSignal;
@@ -1,5 +1,6 @@
1
1
  import { type AuthStorage, type FetchImpl } from "@oh-my-pi/pi-ai";
2
2
  import type { SearchResponse } from "../../../web/search/types.js";
3
+ import { type StructuredQuery } from "../query.js";
3
4
  import type { SearchParams } from "./base.js";
4
5
  import { SearchProvider } from "./base.js";
5
6
  export declare function searchParallel(params: {
@@ -7,6 +8,7 @@ export declare function searchParallel(params: {
7
8
  num_results?: number;
8
9
  signal?: AbortSignal;
9
10
  fetch?: FetchImpl;
11
+ parsedQuery?: StructuredQuery;
10
12
  }, authStorage: AuthStorage, sessionId?: string): Promise<SearchResponse>;
11
13
  export declare class ParallelProvider extends SearchProvider {
12
14
  readonly id = "parallel";
@@ -9,12 +9,15 @@
9
9
  */
10
10
  import { type AuthStorage, type FetchImpl } from "@oh-my-pi/pi-ai";
11
11
  import type { SearchResponse } from "../../../web/search/types.js";
12
+ import { type StructuredQuery } from "../query.js";
12
13
  import type { SearchParams } from "./base.js";
13
14
  import { SearchProvider } from "./base.js";
14
15
  export interface PerplexitySearchParams {
15
16
  signal?: AbortSignal;
16
17
  query: string;
17
18
  system_prompt?: string;
19
+ /** Pre-parsed view of `query` from the search pipeline; parsed locally when absent. */
20
+ parsedQuery?: StructuredQuery;
18
21
  search_recency_filter?: "hour" | "day" | "week" | "month" | "year";
19
22
  num_results?: number;
20
23
  /** Maximum output tokens. Defaults to 8192. */
@@ -14,6 +14,9 @@
14
14
  * searxng.basicUsername - Optional RFC 7617 Basic auth username
15
15
  * searxng.basicPassword - Optional RFC 7617 Basic auth password
16
16
  * searxng.categories - Optional comma-separated categories filter
17
+ * searxng.engines - Optional comma-separated engine names or shortcuts
18
+ * (e.g. "duckduckgo, br, sp"); shortcuts resolve via
19
+ * the instance's /config endpoint
17
20
  * searxng.language - Optional language code (e.g. en, zh-CN)
18
21
  *
19
22
  * Environment variable fallbacks:
@@ -22,15 +25,22 @@
22
25
  * SEARXNG_BASIC_USERNAME - Optional RFC 7617 Basic auth username
23
26
  * SEARXNG_BASIC_PASSWORD - Optional RFC 7617 Basic auth password
24
27
  *
28
+ * Bang syntax in queries is passed through: `!ddg foo` selects an engine or
29
+ * category server-side and the bang token is stripped from the upstream query.
30
+ * External bangs (`!!g`) are removed client-side because SearXNG answers them
31
+ * with an HTTP redirect even for JSON requests.
32
+ *
25
33
  * Reference: https://docs.searxng.org/dev/search_api.html
26
34
  */
27
35
  import type { AuthStorage, FetchImpl } from "@oh-my-pi/pi-ai";
28
36
  import type { SearchResponse } from "../../../web/search/types.js";
37
+ import type { StructuredQuery } from "../query.js";
29
38
  import type { SearchParams } from "./base.js";
30
39
  import { SearchProvider } from "./base.js";
31
40
  /** Execute SearXNG web search. */
32
41
  export declare function searchSearXNG(params: {
33
42
  query: string;
43
+ parsedQuery?: StructuredQuery;
34
44
  num_results?: number;
35
45
  recency?: "day" | "week" | "month" | "year";
36
46
  signal?: AbortSignal;
@@ -12,6 +12,14 @@ export interface TavilySearchParams {
12
12
  query: string;
13
13
  num_results?: number;
14
14
  recency?: "day" | "week" | "month" | "year";
15
+ /** `site:` hosts mapped to Tavily's `include_domains`. */
16
+ include_domains?: string[];
17
+ /** `-site:` hosts mapped to Tavily's `exclude_domains`. */
18
+ exclude_domains?: string[];
19
+ /** `after:` inclusive lower bound, ISO `YYYY-MM-DD`, mapped to `start_date`. */
20
+ start_date?: string;
21
+ /** `before:` upper bound, ISO `YYYY-MM-DD`, mapped to `end_date`. */
22
+ end_date?: string;
15
23
  signal?: AbortSignal;
16
24
  fetch?: FetchImpl;
17
25
  }