@oh-my-pi/pi-coding-agent 16.0.4 → 16.0.6
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 +94 -0
- package/dist/cli.js +2027 -1396
- package/dist/types/advisor/advise-tool.d.ts +31 -19
- package/dist/types/autoresearch/tools/init-experiment.d.ts +13 -17
- package/dist/types/autoresearch/tools/log-experiment.d.ts +17 -19
- package/dist/types/autoresearch/tools/run-experiment.d.ts +3 -4
- package/dist/types/autoresearch/tools/update-notes.d.ts +4 -5
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/bench-cli.d.ts +6 -0
- package/dist/types/cli/ttsr-cli.d.ts +39 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/commands/ttsr.d.ts +57 -0
- package/dist/types/commit/agentic/tools/analyze-file.d.ts +4 -5
- package/dist/types/commit/agentic/tools/git-file-diff.d.ts +4 -5
- package/dist/types/commit/agentic/tools/git-hunk.d.ts +5 -6
- package/dist/types/commit/agentic/tools/git-overview.d.ts +4 -5
- package/dist/types/commit/agentic/tools/propose-changelog.d.ts +23 -24
- package/dist/types/commit/agentic/tools/propose-commit.d.ts +11 -32
- package/dist/types/commit/agentic/tools/recent-commits.d.ts +3 -4
- package/dist/types/commit/agentic/tools/schemas.d.ts +6 -27
- package/dist/types/commit/agentic/tools/split-commit.d.ts +28 -49
- package/dist/types/commit/changelog/generate.d.ts +12 -13
- package/dist/types/commit/shared-llm.d.ts +10 -37
- package/dist/types/config/config-file.d.ts +4 -4
- package/dist/types/config/keybindings.d.ts +5 -0
- package/dist/types/config/models-config-schema.d.ts +625 -990
- package/dist/types/config/models-config.d.ts +229 -217
- package/dist/types/config/settings-schema.d.ts +144 -25
- package/dist/types/edit/hashline/params.d.ts +7 -11
- package/dist/types/edit/index.d.ts +2 -1
- package/dist/types/edit/modes/apply-patch.d.ts +4 -5
- package/dist/types/edit/modes/patch.d.ts +15 -24
- package/dist/types/edit/modes/replace.d.ts +16 -17
- package/dist/types/eval/js/index.d.ts +1 -0
- package/dist/types/extensibility/custom-commands/types.d.ts +6 -3
- package/dist/types/extensibility/custom-tools/types.d.ts +8 -5
- package/dist/types/extensibility/extensions/runner.d.ts +5 -2
- package/dist/types/extensibility/extensions/types.d.ts +14 -10
- package/dist/types/extensibility/hooks/types.d.ts +7 -4
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +13 -5
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +17 -0
- package/dist/types/extensibility/shared-events.d.ts +22 -1
- package/dist/types/extensibility/typebox.d.ts +80 -58
- package/dist/types/goals/tools/goal-tool.d.ts +11 -24
- package/dist/types/index.d.ts +2 -0
- package/dist/types/lsp/index.d.ts +11 -26
- package/dist/types/lsp/types.d.ts +12 -28
- package/dist/types/main.d.ts +1 -0
- package/dist/types/mcp/client.d.ts +8 -0
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -1
- package/dist/types/modes/components/status-line/component.d.ts +1 -1
- package/dist/types/modes/components/status-line/context-thresholds.d.ts +0 -1
- package/dist/types/modes/controllers/btw-controller.d.ts +2 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/types/modes/setup-wizard/index.d.ts +1 -0
- package/dist/types/modes/setup-wizard/startup-splash.d.ts +7 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +3 -0
- package/dist/types/modes/utils/context-usage.d.ts +12 -0
- package/dist/types/sdk.d.ts +8 -1
- package/dist/types/session/agent-session.d.ts +24 -0
- package/dist/types/session/session-persistence.d.ts +4 -0
- package/dist/types/startup-splash.d.ts +12 -0
- package/dist/types/task/types.d.ts +47 -48
- package/dist/types/tools/ask.d.ts +26 -27
- package/dist/types/tools/ast-edit.d.ts +17 -17
- package/dist/types/tools/ast-grep.d.ts +12 -13
- package/dist/types/tools/bash.d.ts +20 -17
- package/dist/types/tools/browser.d.ts +46 -71
- package/dist/types/tools/checkpoint.d.ts +14 -15
- package/dist/types/tools/debug.d.ts +82 -145
- package/dist/types/tools/eval.d.ts +30 -40
- package/dist/types/tools/find.d.ts +17 -18
- package/dist/types/tools/gh.d.ts +49 -78
- package/dist/types/tools/image-gen.d.ts +20 -36
- package/dist/types/tools/inspect-image.d.ts +10 -11
- package/dist/types/tools/irc.d.ts +22 -33
- package/dist/types/tools/job.d.ts +11 -12
- package/dist/types/tools/learn.d.ts +21 -28
- package/dist/types/tools/manage-skill.d.ts +13 -22
- package/dist/types/tools/memory-edit.d.ts +15 -24
- package/dist/types/tools/memory-recall.d.ts +7 -8
- package/dist/types/tools/memory-reflect.d.ts +9 -10
- package/dist/types/tools/memory-retain.d.ts +13 -14
- package/dist/types/tools/read.d.ts +8 -8
- package/dist/types/tools/resolve.d.ts +11 -18
- package/dist/types/tools/review.d.ts +9 -15
- package/dist/types/tools/search-tool-bm25.d.ts +9 -10
- package/dist/types/tools/search.d.ts +16 -17
- package/dist/types/tools/ssh.d.ts +14 -15
- package/dist/types/tools/todo.d.ts +27 -43
- package/dist/types/tools/tts.d.ts +8 -9
- package/dist/types/tools/write.d.ts +9 -10
- package/dist/types/tui/code-cell.d.ts +2 -0
- package/dist/types/tui/index.d.ts +1 -0
- package/dist/types/tui/width-aware-text.d.ts +23 -0
- package/dist/types/utils/image-vision-fallback.d.ts +28 -0
- package/dist/types/utils/markit.d.ts +10 -1
- package/dist/types/web/search/index.d.ts +17 -28
- package/dist/types/web/search/providers/base.d.ts +1 -0
- package/dist/types/web/search/providers/gemini.d.ts +1 -0
- package/dist/types/web/search/providers/perplexity.d.ts +0 -2
- package/dist/types/web/search/types.d.ts +32 -26
- package/package.json +14 -13
- package/scripts/omp +1 -1
- package/src/advisor/__tests__/advisor.test.ts +103 -1
- package/src/advisor/advise-tool.ts +47 -11
- package/src/autoresearch/tools/init-experiment.ts +13 -16
- package/src/autoresearch/tools/log-experiment.ts +15 -18
- package/src/autoresearch/tools/run-experiment.ts +3 -3
- package/src/autoresearch/tools/update-notes.ts +4 -4
- package/src/cli/args.ts +1 -0
- package/src/cli/bench-cli.ts +30 -7
- package/src/cli/flag-tables.ts +8 -0
- package/src/cli/ttsr-cli.ts +995 -0
- package/src/cli-commands.ts +1 -0
- package/src/cli.ts +7 -1
- package/src/collab/host.ts +2 -2
- package/src/commands/launch.ts +3 -0
- package/src/commands/ttsr.ts +125 -0
- package/src/commit/agentic/tools/analyze-file.ts +4 -4
- package/src/commit/agentic/tools/git-file-diff.ts +4 -4
- package/src/commit/agentic/tools/git-hunk.ts +7 -5
- package/src/commit/agentic/tools/git-overview.ts +4 -4
- package/src/commit/agentic/tools/propose-changelog.ts +18 -15
- package/src/commit/agentic/tools/propose-commit.ts +6 -6
- package/src/commit/agentic/tools/recent-commits.ts +3 -3
- package/src/commit/agentic/tools/schemas.ts +8 -20
- package/src/commit/agentic/tools/split-commit.ts +19 -23
- package/src/commit/analysis/summary.ts +7 -5
- package/src/commit/changelog/generate.ts +15 -11
- package/src/commit/shared-llm.ts +17 -24
- package/src/config/config-file.ts +13 -15
- package/src/config/keybindings.ts +6 -0
- package/src/config/models-config-schema.ts +206 -179
- package/src/config/settings-schema.ts +118 -2
- package/src/discovery/builtin-rules/index.ts +2 -0
- package/src/discovery/builtin-rules/ts-import-type.md +2 -2
- package/src/discovery/builtin-rules/ts-no-any.md +11 -2
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +55 -0
- package/src/edit/hashline/params.ts +12 -11
- package/src/edit/index.ts +5 -4
- package/src/edit/modes/apply-patch.ts +4 -4
- package/src/edit/modes/patch.ts +15 -18
- package/src/edit/modes/replace.ts +13 -17
- package/src/edit/renderer.ts +0 -1
- package/src/eval/agent-bridge.ts +11 -13
- package/src/eval/completion-bridge.ts +25 -17
- package/src/eval/js/context-manager.ts +17 -2
- package/src/eval/js/index.ts +1 -1
- package/src/eval/py/executor.ts +2 -2
- package/src/eval/py/runner.py +44 -0
- package/src/extensibility/custom-commands/loader.ts +5 -3
- package/src/extensibility/custom-commands/types.ts +6 -3
- package/src/extensibility/custom-tools/loader.ts +4 -2
- package/src/extensibility/custom-tools/types.ts +8 -5
- package/src/extensibility/extensions/loader.ts +4 -2
- package/src/extensibility/extensions/runner.ts +20 -2
- package/src/extensibility/extensions/types.ts +22 -8
- package/src/extensibility/hooks/loader.ts +5 -2
- package/src/extensibility/hooks/types.ts +7 -4
- package/src/extensibility/legacy-pi-ai-shim.ts +42 -5
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +113 -0
- package/src/extensibility/plugins/legacy-pi-compat.ts +13 -13
- package/src/extensibility/shared-events.ts +24 -0
- package/src/extensibility/tool-proxy.ts +4 -1
- package/src/extensibility/typebox.ts +778 -251
- package/src/goals/guided-setup.ts +12 -3
- package/src/goals/tools/goal-tool.ts +6 -6
- package/src/index.ts +2 -0
- package/src/internal-urls/docs-index.generated.ts +15 -13
- package/src/lsp/types.ts +13 -27
- package/src/main.ts +29 -21
- package/src/mcp/client.ts +38 -13
- package/src/mcp/render.ts +102 -89
- package/src/modes/components/agent-hub.ts +11 -4
- package/src/modes/components/branch-summary-message.ts +1 -0
- package/src/modes/components/btw-panel.ts +5 -1
- package/src/modes/components/collab-prompt-message.ts +9 -7
- package/src/modes/components/compaction-summary-message.ts +1 -0
- package/src/modes/components/custom-editor.ts +18 -0
- package/src/modes/components/custom-message.ts +1 -0
- package/src/modes/components/footer.ts +6 -5
- package/src/modes/components/hook-message.ts +1 -0
- package/src/modes/components/read-tool-group.ts +9 -3
- package/src/modes/components/skill-message.ts +1 -0
- package/src/modes/components/status-line/component.ts +139 -15
- package/src/modes/components/status-line/context-thresholds.ts +0 -1
- package/src/modes/components/todo-reminder.ts +1 -0
- package/src/modes/components/tool-execution.ts +17 -10
- package/src/modes/components/ttsr-notification.ts +1 -0
- package/src/modes/components/user-message.ts +6 -6
- package/src/modes/controllers/btw-controller.ts +69 -1
- package/src/modes/controllers/event-controller.ts +2 -7
- package/src/modes/controllers/input-controller.ts +29 -0
- package/src/modes/controllers/selector-controller.ts +10 -3
- package/src/modes/interactive-mode.ts +42 -10
- package/src/modes/rpc/rpc-types.ts +1 -1
- package/src/modes/setup-wizard/index.ts +1 -0
- package/src/modes/setup-wizard/scenes/sign-in.ts +77 -5
- package/src/modes/setup-wizard/startup-splash.ts +107 -0
- package/src/modes/theme/theme.ts +133 -143
- package/src/modes/types.ts +3 -0
- package/src/modes/utils/context-usage.ts +37 -20
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/tools/image-attachment-describe-system.md +8 -0
- package/src/prompts/tools/image-attachment-describe.md +10 -0
- package/src/sdk.ts +35 -22
- package/src/session/agent-session.ts +715 -255
- package/src/session/session-history-format.ts +11 -2
- package/src/session/session-loader.ts +19 -32
- package/src/session/session-persistence.ts +27 -11
- package/src/session/snapcompact-inline.ts +1 -1
- package/src/slash-commands/builtin-registry.ts +4 -11
- package/src/ssh/connection-manager.ts +3 -2
- package/src/startup-splash.ts +19 -0
- package/src/task/executor.ts +12 -7
- package/src/task/types.ts +44 -41
- package/src/tool-discovery/tool-index.ts +17 -4
- package/src/tools/ask.ts +14 -14
- package/src/tools/ast-edit.ts +17 -14
- package/src/tools/ast-grep.ts +10 -9
- package/src/tools/bash.ts +15 -10
- package/src/tools/browser/launch.ts +13 -0
- package/src/tools/browser.ts +26 -32
- package/src/tools/checkpoint.ts +7 -7
- package/src/tools/debug.ts +72 -69
- package/src/tools/eval.ts +18 -19
- package/src/tools/find.ts +20 -13
- package/src/tools/gh.ts +29 -49
- package/src/tools/image-gen.ts +94 -57
- package/src/tools/inspect-image.ts +8 -9
- package/src/tools/irc.ts +12 -12
- package/src/tools/job.ts +6 -6
- package/src/tools/learn.ts +11 -14
- package/src/tools/manage-skill.ts +19 -23
- package/src/tools/memory-edit.ts +8 -8
- package/src/tools/memory-recall.ts +4 -4
- package/src/tools/memory-reflect.ts +5 -5
- package/src/tools/memory-retain.ts +9 -11
- package/src/tools/puppeteer/02_stealth_hairline.txt +1 -1
- package/src/tools/puppeteer/04_stealth_iframe.txt +4 -4
- package/src/tools/puppeteer/05_stealth_webgl.txt +1 -1
- package/src/tools/puppeteer/10_stealth_plugins.txt +6 -4
- package/src/tools/puppeteer/12_stealth_codecs.txt +2 -2
- package/src/tools/puppeteer/13_stealth_worker.txt +1 -1
- package/src/tools/read.ts +197 -19
- package/src/tools/report-tool-issue.ts +6 -6
- package/src/tools/resolve.ts +6 -6
- package/src/tools/review.ts +10 -12
- package/src/tools/search-tool-bm25.ts +5 -5
- package/src/tools/search.ts +20 -29
- package/src/tools/ssh.ts +8 -8
- package/src/tools/todo.ts +16 -19
- package/src/tools/tts.ts +16 -15
- package/src/tools/write.ts +5 -5
- package/src/tui/code-cell.ts +44 -3
- package/src/tui/index.ts +1 -0
- package/src/tui/width-aware-text.ts +58 -0
- package/src/utils/image-vision-fallback.ts +197 -0
- package/src/utils/markit.ts +17 -2
- package/src/web/search/index.ts +21 -9
- package/src/web/search/providers/base.ts +1 -0
- package/src/web/search/providers/gemini.ts +56 -18
- package/src/web/search/providers/perplexity.ts +373 -126
- package/src/web/search/types.ts +28 -48
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { getAgentDir, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
4
|
+
import type { Type } from "arktype";
|
|
4
5
|
import { JSONC, YAML } from "bun";
|
|
5
|
-
import type { ZodType } from "zod/v4";
|
|
6
6
|
|
|
7
7
|
/** Minimal subset of the AJV ConfigSchemaError shape this module actually relies on. */
|
|
8
8
|
interface ConfigSchemaError {
|
|
@@ -55,7 +55,7 @@ function migrateJsonToYml(jsonPath: string, ymlPath: string) {
|
|
|
55
55
|
|
|
56
56
|
export interface IConfigFile<T> {
|
|
57
57
|
readonly id: string;
|
|
58
|
-
readonly schema:
|
|
58
|
+
readonly schema: Type;
|
|
59
59
|
path?(): string;
|
|
60
60
|
load(): T | null;
|
|
61
61
|
invalidate?(): void;
|
|
@@ -129,7 +129,7 @@ export class ConfigFile<T> implements IConfigFile<T> {
|
|
|
129
129
|
|
|
130
130
|
constructor(
|
|
131
131
|
readonly id: string,
|
|
132
|
-
readonly schema:
|
|
132
|
+
readonly schema: Type,
|
|
133
133
|
configPath: string = path.join(getAgentDir(), `${id}.yml`),
|
|
134
134
|
) {
|
|
135
135
|
this.#basePath = configPath;
|
|
@@ -193,10 +193,10 @@ export class ConfigFile<T> implements IConfigFile<T> {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
createDefault(): T {
|
|
196
|
-
const parsed = this.schema
|
|
197
|
-
if (parsed
|
|
198
|
-
const fallback = this.schema
|
|
199
|
-
if (fallback
|
|
196
|
+
const parsed = this.schema({});
|
|
197
|
+
if (!(parsed instanceof Error)) return parsed as T;
|
|
198
|
+
const fallback = this.schema(undefined);
|
|
199
|
+
if (!(fallback instanceof Error)) return fallback as T;
|
|
200
200
|
throw new ConfigError(this.id, undefined, {
|
|
201
201
|
err: new Error("Schema produced no default value"),
|
|
202
202
|
stage: "createDefault",
|
|
@@ -219,19 +219,17 @@ export class ConfigFile<T> implements IConfigFile<T> {
|
|
|
219
219
|
throw new Error(`Invalid config file path: ${this.#basePath}`);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
const checked = this.schema
|
|
223
|
-
if (
|
|
222
|
+
const checked = this.schema(parsed);
|
|
223
|
+
if (checked instanceof Error) {
|
|
224
224
|
const schemaErrors: ConfigSchemaError[] = [];
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (schemaErrors.length >= 50) break;
|
|
229
|
-
}
|
|
225
|
+
// arktype errors are Error instances with a message property
|
|
226
|
+
// Extract the error message as a single schema error
|
|
227
|
+
schemaErrors.push({ instancePath: "root", message: checked.message });
|
|
230
228
|
const error = new ConfigError(this.id, schemaErrors);
|
|
231
229
|
logger.warn("Failed to parse config file", { path: this.path(), error });
|
|
232
230
|
return this.#storeCache({ error, status: "error" });
|
|
233
231
|
}
|
|
234
|
-
const value = checked
|
|
232
|
+
const value = checked as T;
|
|
235
233
|
try {
|
|
236
234
|
this.#auxValidate?.(value);
|
|
237
235
|
} catch (error) {
|
|
@@ -31,6 +31,7 @@ interface AppKeybindings {
|
|
|
31
31
|
"app.tools.expand": true;
|
|
32
32
|
"app.editor.external": true;
|
|
33
33
|
"app.message.followUp": true;
|
|
34
|
+
"app.retry": true;
|
|
34
35
|
"app.message.dequeue": true;
|
|
35
36
|
"app.clipboard.pasteImage": true;
|
|
36
37
|
"app.clipboard.pasteTextRaw": true;
|
|
@@ -131,6 +132,10 @@ export const KEYBINDINGS = {
|
|
|
131
132
|
defaultKeys: ["ctrl+q", "ctrl+enter"],
|
|
132
133
|
description: "Send follow-up message",
|
|
133
134
|
},
|
|
135
|
+
"app.retry": {
|
|
136
|
+
defaultKeys: "alt+r",
|
|
137
|
+
description: "Retry last failed assistant turn",
|
|
138
|
+
},
|
|
134
139
|
"app.message.dequeue": {
|
|
135
140
|
defaultKeys: "alt+up",
|
|
136
141
|
description: "Dequeue message",
|
|
@@ -238,6 +243,7 @@ const KEYBINDING_NAME_MIGRATIONS = {
|
|
|
238
243
|
toggleThinking: "app.thinking.toggle",
|
|
239
244
|
externalEditor: "app.editor.external",
|
|
240
245
|
followUp: "app.message.followUp",
|
|
246
|
+
retry: "app.retry",
|
|
241
247
|
dequeue: "app.message.dequeue",
|
|
242
248
|
pasteImage: "app.clipboard.pasteImage",
|
|
243
249
|
pasteTextRaw: "app.clipboard.pasteTextRaw",
|
|
@@ -1,73 +1,72 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type } from "arktype";
|
|
2
2
|
|
|
3
|
-
const OpenRouterRoutingSchema =
|
|
4
|
-
only:
|
|
5
|
-
order:
|
|
3
|
+
const OpenRouterRoutingSchema = type({
|
|
4
|
+
"only?": "string[]",
|
|
5
|
+
"order?": "string[]",
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
const VercelGatewayRoutingSchema =
|
|
9
|
-
only:
|
|
10
|
-
order:
|
|
8
|
+
const VercelGatewayRoutingSchema = type({
|
|
9
|
+
"only?": "string[]",
|
|
10
|
+
"order?": "string[]",
|
|
11
11
|
});
|
|
12
12
|
|
|
13
|
-
const ReasoningEffortMapSchema =
|
|
14
|
-
minimal:
|
|
15
|
-
low:
|
|
16
|
-
medium:
|
|
17
|
-
high:
|
|
18
|
-
xhigh:
|
|
13
|
+
const ReasoningEffortMapSchema = type({
|
|
14
|
+
"minimal?": "string",
|
|
15
|
+
"low?": "string",
|
|
16
|
+
"medium?": "string",
|
|
17
|
+
"high?": "string",
|
|
18
|
+
"xhigh?": "string",
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
const
|
|
22
|
-
supportsStore:
|
|
23
|
-
supportsDeveloperRole:
|
|
24
|
-
supportsMultipleSystemMessages:
|
|
25
|
-
supportsReasoningEffort:
|
|
26
|
-
reasoningEffortMap: ReasoningEffortMapSchema
|
|
27
|
-
maxTokensField:
|
|
28
|
-
supportsUsageInStreaming:
|
|
29
|
-
requiresToolResultName:
|
|
30
|
-
requiresMistralToolIds:
|
|
31
|
-
requiresAssistantAfterToolResult:
|
|
32
|
-
requiresThinkingAsText:
|
|
33
|
-
reasoningContentField:
|
|
34
|
-
requiresReasoningContentForToolCalls:
|
|
35
|
-
allowsSyntheticReasoningContentForToolCalls:
|
|
36
|
-
requiresAssistantContentForToolCalls:
|
|
37
|
-
supportsToolChoice:
|
|
38
|
-
supportsForcedToolChoice:
|
|
39
|
-
disableReasoningOnForcedToolChoice:
|
|
40
|
-
disableReasoningOnToolChoice:
|
|
41
|
-
thinkingFormat:
|
|
42
|
-
openRouterRouting: OpenRouterRoutingSchema
|
|
43
|
-
vercelGatewayRouting: VercelGatewayRoutingSchema
|
|
44
|
-
extraBody:
|
|
45
|
-
cacheControlFormat:
|
|
46
|
-
supportsStrictMode:
|
|
47
|
-
toolStrictMode:
|
|
48
|
-
streamIdleTimeoutMs:
|
|
49
|
-
supportsLongPromptCacheRetention:
|
|
50
|
-
supportsReasoningParams:
|
|
51
|
-
alwaysSendMaxTokens:
|
|
52
|
-
strictResponsesPairing:
|
|
21
|
+
const OpenAICompatFields = {
|
|
22
|
+
"supportsStore?": "boolean",
|
|
23
|
+
"supportsDeveloperRole?": "boolean",
|
|
24
|
+
"supportsMultipleSystemMessages?": "boolean",
|
|
25
|
+
"supportsReasoningEffort?": "boolean",
|
|
26
|
+
"reasoningEffortMap?": ReasoningEffortMapSchema,
|
|
27
|
+
"maxTokensField?": '"max_completion_tokens" | "max_tokens"',
|
|
28
|
+
"supportsUsageInStreaming?": "boolean",
|
|
29
|
+
"requiresToolResultName?": "boolean",
|
|
30
|
+
"requiresMistralToolIds?": "boolean",
|
|
31
|
+
"requiresAssistantAfterToolResult?": "boolean",
|
|
32
|
+
"requiresThinkingAsText?": "boolean",
|
|
33
|
+
"reasoningContentField?": '"reasoning_content" | "reasoning" | "reasoning_text"',
|
|
34
|
+
"requiresReasoningContentForToolCalls?": "boolean",
|
|
35
|
+
"allowsSyntheticReasoningContentForToolCalls?": "boolean",
|
|
36
|
+
"requiresAssistantContentForToolCalls?": "boolean",
|
|
37
|
+
"supportsToolChoice?": "boolean",
|
|
38
|
+
"supportsForcedToolChoice?": "boolean",
|
|
39
|
+
"disableReasoningOnForcedToolChoice?": "boolean",
|
|
40
|
+
"disableReasoningOnToolChoice?": "boolean",
|
|
41
|
+
"thinkingFormat?": '"openai" | "openrouter" | "zai" | "qwen" | "qwen-chat-template"',
|
|
42
|
+
"openRouterRouting?": OpenRouterRoutingSchema,
|
|
43
|
+
"vercelGatewayRouting?": VercelGatewayRoutingSchema,
|
|
44
|
+
"extraBody?": { "[string]": "unknown" },
|
|
45
|
+
"cacheControlFormat?": '"anthropic"',
|
|
46
|
+
"supportsStrictMode?": "boolean",
|
|
47
|
+
"toolStrictMode?": '"all_strict" | "none"',
|
|
48
|
+
"streamIdleTimeoutMs?": "number >= 0",
|
|
49
|
+
"supportsLongPromptCacheRetention?": "boolean",
|
|
50
|
+
"supportsReasoningParams?": "boolean",
|
|
51
|
+
"alwaysSendMaxTokens?": "boolean",
|
|
52
|
+
"strictResponsesPairing?": "boolean",
|
|
53
53
|
// anthropic-messages compat flags (same `compat` slot, per-api interpretation)
|
|
54
|
-
requiresToolResultId:
|
|
55
|
-
replayUnsignedThinking:
|
|
56
|
-
}
|
|
54
|
+
"requiresToolResultId?": "boolean",
|
|
55
|
+
"replayUnsignedThinking?": "boolean",
|
|
56
|
+
} as const;
|
|
57
|
+
|
|
58
|
+
const OpenAICompatFieldsSchema = type(OpenAICompatFields);
|
|
57
59
|
|
|
58
|
-
export const OpenAICompatSchema =
|
|
59
|
-
|
|
60
|
+
export const OpenAICompatSchema = type({
|
|
61
|
+
...OpenAICompatFields,
|
|
62
|
+
"whenThinking?": OpenAICompatFieldsSchema,
|
|
60
63
|
});
|
|
61
64
|
|
|
62
|
-
const EffortSchema =
|
|
65
|
+
const EffortSchema = type('"minimal" | "low" | "medium" | "high" | "xhigh"');
|
|
63
66
|
|
|
64
|
-
const ThinkingControlModeSchema =
|
|
65
|
-
"effort",
|
|
66
|
-
|
|
67
|
-
"google-level",
|
|
68
|
-
"anthropic-adaptive",
|
|
69
|
-
"anthropic-budget-effort",
|
|
70
|
-
]);
|
|
67
|
+
const ThinkingControlModeSchema = type(
|
|
68
|
+
'"effort" | "budget" | "google-level" | "anthropic-adaptive" | "anthropic-budget-effort"',
|
|
69
|
+
);
|
|
71
70
|
|
|
72
71
|
const EFFORT_ORDER = ["minimal", "low", "medium", "high", "xhigh"] as const;
|
|
73
72
|
|
|
@@ -77,137 +76,141 @@ const EFFORT_ORDER = ["minimal", "low", "medium", "high", "xhigh"] as const;
|
|
|
77
76
|
* `ThinkingConfig` (ordered `efforts`, never empty). Precedence mirrors the
|
|
78
77
|
* old runtime: explicit `levels` beat the min..max range; `efforts` beats both.
|
|
79
78
|
*/
|
|
80
|
-
const ModelThinkingSchema =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
value =>
|
|
79
|
+
const ModelThinkingSchema = type({
|
|
80
|
+
mode: ThinkingControlModeSchema,
|
|
81
|
+
"efforts?": EffortSchema.array(),
|
|
82
|
+
"defaultLevel?": EffortSchema,
|
|
83
|
+
"effortMap?": ReasoningEffortMapSchema,
|
|
84
|
+
"supportsDisplay?": "boolean",
|
|
85
|
+
// Legacy range vocabulary (pre-efforts configs).
|
|
86
|
+
"minLevel?": EffortSchema,
|
|
87
|
+
"maxLevel?": EffortSchema,
|
|
88
|
+
"levels?": EffortSchema.array(),
|
|
89
|
+
})
|
|
90
|
+
.narrow(
|
|
91
|
+
(value, ctx) =>
|
|
94
92
|
value.efforts !== undefined ||
|
|
95
93
|
value.levels !== undefined ||
|
|
96
|
-
(value.minLevel !== undefined && value.maxLevel !== undefined)
|
|
97
|
-
|
|
98
|
-
message: "thinking requires `efforts` (or legacy `levels`/`minLevel`+`maxLevel`)",
|
|
99
|
-
},
|
|
94
|
+
(value.minLevel !== undefined && value.maxLevel !== undefined) ||
|
|
95
|
+
ctx.mustBe("thinking with `efforts` (or legacy `levels`/`minLevel`+`maxLevel`)"),
|
|
100
96
|
)
|
|
101
|
-
.
|
|
102
|
-
let resolved = efforts ?? levels;
|
|
97
|
+
.pipe((value: any) => {
|
|
98
|
+
let resolved = value.efforts ?? value.levels;
|
|
103
99
|
if (!resolved) {
|
|
104
|
-
const minIndex = EFFORT_ORDER.indexOf(minLevel!);
|
|
105
|
-
const maxIndex = EFFORT_ORDER.indexOf(maxLevel!);
|
|
100
|
+
const minIndex = EFFORT_ORDER.indexOf(value.minLevel!);
|
|
101
|
+
const maxIndex = EFFORT_ORDER.indexOf(value.maxLevel!);
|
|
106
102
|
resolved = EFFORT_ORDER.slice(minIndex, Math.max(minIndex, maxIndex) + 1);
|
|
107
103
|
}
|
|
108
104
|
return {
|
|
109
|
-
mode,
|
|
105
|
+
mode: value.mode,
|
|
110
106
|
efforts: resolved,
|
|
111
|
-
...(defaultLevel !== undefined && { defaultLevel }),
|
|
112
|
-
...(effortMap !== undefined && { effortMap }),
|
|
113
|
-
...(supportsDisplay !== undefined && { supportsDisplay }),
|
|
107
|
+
...(value.defaultLevel !== undefined && { defaultLevel: value.defaultLevel }),
|
|
108
|
+
...(value.effortMap !== undefined && { effortMap: value.effortMap }),
|
|
109
|
+
...(value.supportsDisplay !== undefined && { supportsDisplay: value.supportsDisplay }),
|
|
114
110
|
};
|
|
115
111
|
});
|
|
116
112
|
|
|
117
|
-
const ModelDefinitionSchema =
|
|
118
|
-
id:
|
|
119
|
-
name:
|
|
120
|
-
api:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
113
|
+
const ModelDefinitionSchema = type({
|
|
114
|
+
id: "string",
|
|
115
|
+
"name?": "string",
|
|
116
|
+
"api?":
|
|
117
|
+
'"openai-completions" | "openai-responses" | "openai-codex-responses" | "azure-openai-responses" | "anthropic-messages" | "google-generative-ai" | "google-gemini-cli" | "google-vertex"',
|
|
118
|
+
"baseUrl?": "string",
|
|
119
|
+
"reasoning?": "boolean",
|
|
120
|
+
"thinking?": ModelThinkingSchema,
|
|
121
|
+
"input?": '("text" | "image")[]',
|
|
122
|
+
"supportsTools?": "boolean",
|
|
123
|
+
"cost?": {
|
|
124
|
+
input: "number",
|
|
125
|
+
output: "number",
|
|
126
|
+
cacheRead: "number",
|
|
127
|
+
cacheWrite: "number",
|
|
128
|
+
},
|
|
129
|
+
"premiumMultiplier?": "number",
|
|
130
|
+
"contextWindow?": "number",
|
|
131
|
+
"maxTokens?": "number",
|
|
132
|
+
"omitMaxOutputTokens?": "boolean",
|
|
133
|
+
"headers?": { "[string]": "string" },
|
|
134
|
+
"compat?": OpenAICompatSchema,
|
|
135
|
+
"contextPromotionTarget?": "string",
|
|
136
|
+
}).narrow((value, ctx) => {
|
|
137
|
+
// Enforce id non-empty
|
|
138
|
+
if (typeof value.id === "string" && value.id.length === 0) {
|
|
139
|
+
return ctx.mustBe("id a non-empty string");
|
|
140
|
+
}
|
|
141
|
+
if (value.name !== undefined && typeof value.name === "string" && value.name.length === 0) {
|
|
142
|
+
return ctx.mustBe("name a non-empty string");
|
|
143
|
+
}
|
|
144
|
+
if (value.baseUrl !== undefined && typeof value.baseUrl === "string" && value.baseUrl.length === 0) {
|
|
145
|
+
return ctx.mustBe("baseUrl a non-empty string");
|
|
146
|
+
}
|
|
147
|
+
if (
|
|
148
|
+
value.contextPromotionTarget !== undefined &&
|
|
149
|
+
typeof value.contextPromotionTarget === "string" &&
|
|
150
|
+
value.contextPromotionTarget.length === 0
|
|
151
|
+
) {
|
|
152
|
+
return ctx.mustBe("contextPromotionTarget a non-empty string");
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
152
155
|
});
|
|
153
156
|
|
|
154
|
-
export const ModelOverrideSchema =
|
|
155
|
-
name:
|
|
156
|
-
reasoning:
|
|
157
|
-
thinking: ModelThinkingSchema
|
|
158
|
-
input:
|
|
159
|
-
supportsTools:
|
|
160
|
-
cost:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
157
|
+
export const ModelOverrideSchema = type({
|
|
158
|
+
"name?": "string",
|
|
159
|
+
"reasoning?": "boolean",
|
|
160
|
+
"thinking?": ModelThinkingSchema,
|
|
161
|
+
"input?": '("text" | "image")[]',
|
|
162
|
+
"supportsTools?": "boolean",
|
|
163
|
+
"cost?": {
|
|
164
|
+
"input?": "number",
|
|
165
|
+
"output?": "number",
|
|
166
|
+
"cacheRead?": "number",
|
|
167
|
+
"cacheWrite?": "number",
|
|
168
|
+
},
|
|
169
|
+
"premiumMultiplier?": "number",
|
|
170
|
+
"contextWindow?": "number",
|
|
171
|
+
"maxTokens?": "number",
|
|
172
|
+
"omitMaxOutputTokens?": "boolean",
|
|
173
|
+
"headers?": { "[string]": "string" },
|
|
174
|
+
"compat?": OpenAICompatSchema,
|
|
175
|
+
"contextPromotionTarget?": "string",
|
|
176
|
+
}).narrow((value, ctx) => {
|
|
177
|
+
if (value.name !== undefined && typeof value.name === "string" && value.name.length === 0) {
|
|
178
|
+
return ctx.mustBe("name a non-empty string");
|
|
179
|
+
}
|
|
180
|
+
if (
|
|
181
|
+
value.contextPromotionTarget !== undefined &&
|
|
182
|
+
typeof value.contextPromotionTarget === "string" &&
|
|
183
|
+
value.contextPromotionTarget.length === 0
|
|
184
|
+
) {
|
|
185
|
+
return ctx.mustBe("contextPromotionTarget a non-empty string");
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
175
188
|
});
|
|
176
189
|
|
|
177
|
-
export type ModelOverride =
|
|
190
|
+
export type ModelOverride = typeof ModelOverrideSchema.infer;
|
|
178
191
|
|
|
179
|
-
export const ProviderDiscoverySchema =
|
|
180
|
-
type:
|
|
192
|
+
export const ProviderDiscoverySchema = type({
|
|
193
|
+
type: '"ollama" | "llama.cpp" | "lm-studio" | "openai-models-list" | "proxy"',
|
|
181
194
|
});
|
|
182
195
|
|
|
183
|
-
export const ProviderAuthSchema =
|
|
184
|
-
|
|
185
|
-
export type ProviderAuthMode =
|
|
186
|
-
export type ProviderDiscovery =
|
|
187
|
-
|
|
188
|
-
const ProviderConfigSchema =
|
|
189
|
-
baseUrl:
|
|
190
|
-
apiKey:
|
|
191
|
-
api:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
])
|
|
202
|
-
.optional(),
|
|
203
|
-
headers: z.record(z.string(), z.string()).optional(),
|
|
204
|
-
compat: OpenAICompatSchema.optional(),
|
|
205
|
-
authHeader: z.boolean().optional(),
|
|
206
|
-
auth: ProviderAuthSchema.optional(),
|
|
207
|
-
discovery: ProviderDiscoverySchema.optional(),
|
|
208
|
-
models: z.array(ModelDefinitionSchema).optional(),
|
|
209
|
-
modelOverrides: z.record(z.string(), ModelOverrideSchema).optional(),
|
|
210
|
-
disableStrictTools: z.boolean().optional(),
|
|
196
|
+
export const ProviderAuthSchema = type('"apiKey" | "none" | "oauth"');
|
|
197
|
+
|
|
198
|
+
export type ProviderAuthMode = typeof ProviderAuthSchema.infer;
|
|
199
|
+
export type ProviderDiscovery = typeof ProviderDiscoverySchema.infer;
|
|
200
|
+
|
|
201
|
+
const ProviderConfigSchema = type({
|
|
202
|
+
"baseUrl?": "string",
|
|
203
|
+
"apiKey?": "string",
|
|
204
|
+
"api?":
|
|
205
|
+
'"openai-completions" | "openai-responses" | "openai-codex-responses" | "azure-openai-responses" | "anthropic-messages" | "google-generative-ai" | "google-gemini-cli" | "google-vertex"',
|
|
206
|
+
"headers?": { "[string]": "string" },
|
|
207
|
+
"compat?": OpenAICompatSchema,
|
|
208
|
+
"authHeader?": "boolean",
|
|
209
|
+
"auth?": ProviderAuthSchema,
|
|
210
|
+
"discovery?": ProviderDiscoverySchema,
|
|
211
|
+
"models?": ModelDefinitionSchema.array(),
|
|
212
|
+
"modelOverrides?": { "[string]": ModelOverrideSchema },
|
|
213
|
+
"disableStrictTools?": "boolean",
|
|
211
214
|
/**
|
|
212
215
|
* Streaming transport override. When set to `"pi-native"`, omp dispatches
|
|
213
216
|
* every model under this provider via the auth-gateway's
|
|
@@ -215,17 +218,41 @@ const ProviderConfigSchema = z.object({
|
|
|
215
218
|
* provider's `baseUrl` must point at a compatible `omp auth-gateway`
|
|
216
219
|
* and `apiKey` must carry the gateway bearer.
|
|
217
220
|
*/
|
|
218
|
-
transport:
|
|
221
|
+
"transport?": '"pi-native"',
|
|
222
|
+
}).narrow((value, ctx) => {
|
|
223
|
+
if (value.baseUrl !== undefined && typeof value.baseUrl === "string" && value.baseUrl.length === 0) {
|
|
224
|
+
return ctx.mustBe("baseUrl a non-empty string");
|
|
225
|
+
}
|
|
226
|
+
if (value.apiKey !== undefined && typeof value.apiKey === "string" && value.apiKey.length === 0) {
|
|
227
|
+
return ctx.mustBe("apiKey a non-empty string");
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
219
230
|
});
|
|
220
231
|
|
|
221
|
-
const EquivalenceConfigSchema =
|
|
222
|
-
overrides:
|
|
223
|
-
exclude:
|
|
232
|
+
const EquivalenceConfigSchema = type({
|
|
233
|
+
"overrides?": { "[string]": "string" },
|
|
234
|
+
"exclude?": "string[]",
|
|
235
|
+
}).narrow((value, ctx) => {
|
|
236
|
+
if (value.overrides !== undefined) {
|
|
237
|
+
for (const [, v] of Object.entries(value.overrides)) {
|
|
238
|
+
if (typeof v === "string" && v.length === 0) {
|
|
239
|
+
return ctx.mustBe("overrides values non-empty strings");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (value.exclude !== undefined && Array.isArray(value.exclude)) {
|
|
244
|
+
for (const item of value.exclude) {
|
|
245
|
+
if (typeof item === "string" && item.length === 0) {
|
|
246
|
+
return ctx.mustBe("exclude items non-empty strings");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return true;
|
|
224
251
|
});
|
|
225
252
|
|
|
226
|
-
export const ModelsConfigSchema =
|
|
227
|
-
providers:
|
|
228
|
-
equivalence: EquivalenceConfigSchema
|
|
253
|
+
export const ModelsConfigSchema = type({
|
|
254
|
+
"providers?": { "[string]": ProviderConfigSchema },
|
|
255
|
+
"equivalence?": EquivalenceConfigSchema,
|
|
229
256
|
});
|
|
230
257
|
|
|
231
|
-
export type ModelsConfig =
|
|
258
|
+
export type ModelsConfig = typeof ModelsConfigSchema.infer;
|