@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
|
@@ -106,7 +106,7 @@ export const TAB_METADATA: Record<SettingTab, { label: string; icon: `tab.${stri
|
|
|
106
106
|
*/
|
|
107
107
|
export const TAB_GROUPS: Record<SettingTab, readonly string[]> = {
|
|
108
108
|
appearance: ["Theme", "Status Line", "Display", "Images"],
|
|
109
|
-
model: ["Thinking", "Sampling", "Prompt", "Retry & Fallback", "Advisor"],
|
|
109
|
+
model: ["Thinking", "Sampling", "Prompt", "Retry & Fallback", "Advisor", "Vision"],
|
|
110
110
|
interaction: [
|
|
111
111
|
"Input",
|
|
112
112
|
"Approvals",
|
|
@@ -117,6 +117,7 @@ export const TAB_GROUPS: Record<SettingTab, readonly string[]> = {
|
|
|
117
117
|
"Startup & Updates",
|
|
118
118
|
"Power (macOS)",
|
|
119
119
|
"Agent",
|
|
120
|
+
"Git",
|
|
120
121
|
],
|
|
121
122
|
context: ["General", "Compaction", "Rules (TTSR)", "Experimental"],
|
|
122
123
|
memory: ["General", "Auto-Learn", "Mnemopi", "Hindsight"],
|
|
@@ -414,7 +415,36 @@ export const SETTINGS_SCHEMA = {
|
|
|
414
415
|
"Pause the main agent for up to 30 seconds if the advisor falls behind by this many turns. Off disables catch-up delays.",
|
|
415
416
|
},
|
|
416
417
|
},
|
|
418
|
+
"advisor.immuneTurns": {
|
|
419
|
+
type: "number",
|
|
420
|
+
default: 1,
|
|
421
|
+
ui: {
|
|
422
|
+
tab: "model",
|
|
423
|
+
group: "Advisor",
|
|
424
|
+
label: "Advisor Immune Turns",
|
|
425
|
+
description:
|
|
426
|
+
"After an advisor concern or blocker interrupts, route further concerns/blockers non-interruptingly for this many primary turns.",
|
|
427
|
+
options: [
|
|
428
|
+
{ value: "0", label: "0 turns", description: "Allow every concern/blocker to interrupt." },
|
|
429
|
+
{ value: "1", label: "1 turn", description: "Default." },
|
|
430
|
+
{ value: "2", label: "2 turns" },
|
|
431
|
+
{ value: "3", label: "3 turns" },
|
|
432
|
+
{ value: "4", label: "4 turns" },
|
|
433
|
+
{ value: "5", label: "5 turns" },
|
|
434
|
+
],
|
|
435
|
+
},
|
|
436
|
+
},
|
|
417
437
|
shellPath: { type: "string", default: undefined },
|
|
438
|
+
"git.enabled": {
|
|
439
|
+
type: "boolean",
|
|
440
|
+
default: true,
|
|
441
|
+
ui: {
|
|
442
|
+
tab: "interaction",
|
|
443
|
+
group: "Git",
|
|
444
|
+
label: "Enable Git Integration",
|
|
445
|
+
description: "Show git branch, status, and PR information in the TUI and watch repository metadata.",
|
|
446
|
+
},
|
|
447
|
+
},
|
|
418
448
|
|
|
419
449
|
extensions: { type: "array", default: EMPTY_STRING_ARRAY },
|
|
420
450
|
|
|
@@ -712,6 +742,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
712
742
|
},
|
|
713
743
|
},
|
|
714
744
|
|
|
745
|
+
"images.describeForTextModels": {
|
|
746
|
+
type: "boolean",
|
|
747
|
+
default: true,
|
|
748
|
+
ui: {
|
|
749
|
+
tab: "model",
|
|
750
|
+
group: "Vision",
|
|
751
|
+
label: "Describe Images for Text Models",
|
|
752
|
+
description:
|
|
753
|
+
"When an image is attached to a model without vision support, save it under local:// and inject a description from a vision-capable model instead of dropping it",
|
|
754
|
+
},
|
|
755
|
+
},
|
|
756
|
+
|
|
715
757
|
"tui.maxInlineImageColumns": {
|
|
716
758
|
type: "number",
|
|
717
759
|
default: 100,
|
|
@@ -757,6 +799,16 @@ export const SETTINGS_SCHEMA = {
|
|
|
757
799
|
"Wrap paths and URLs in OSC 8 hyperlinks for terminal-native click-to-open (auto: detect support; off: never; always: unconditional)",
|
|
758
800
|
},
|
|
759
801
|
},
|
|
802
|
+
"tui.tight": {
|
|
803
|
+
type: "boolean",
|
|
804
|
+
default: false,
|
|
805
|
+
ui: {
|
|
806
|
+
tab: "appearance",
|
|
807
|
+
group: "Display",
|
|
808
|
+
label: "Tight Layout",
|
|
809
|
+
description: "Remove the 1-character horizontal padding from the left and right of the terminal output",
|
|
810
|
+
},
|
|
811
|
+
},
|
|
760
812
|
// Display rendering
|
|
761
813
|
"display.tabWidth": {
|
|
762
814
|
type: "number",
|
|
@@ -845,6 +897,28 @@ export const SETTINGS_SCHEMA = {
|
|
|
845
897
|
},
|
|
846
898
|
},
|
|
847
899
|
|
|
900
|
+
"model.loopGuard.enabled": {
|
|
901
|
+
type: "boolean",
|
|
902
|
+
default: true,
|
|
903
|
+
ui: {
|
|
904
|
+
tab: "model",
|
|
905
|
+
group: "Thinking",
|
|
906
|
+
label: "Loop Guard",
|
|
907
|
+
description: "Enable automatic stream loop detection for Gemini and DeepSeek models",
|
|
908
|
+
},
|
|
909
|
+
},
|
|
910
|
+
|
|
911
|
+
"model.loopGuard.checkAssistantContent": {
|
|
912
|
+
type: "boolean",
|
|
913
|
+
default: true,
|
|
914
|
+
ui: {
|
|
915
|
+
tab: "model",
|
|
916
|
+
group: "Thinking",
|
|
917
|
+
label: "Loop Guard Scan Prose",
|
|
918
|
+
description: "Apply loop guard to assistant prose messages in addition to thinking logs",
|
|
919
|
+
},
|
|
920
|
+
},
|
|
921
|
+
|
|
848
922
|
repeatToolDescriptions: {
|
|
849
923
|
type: "boolean",
|
|
850
924
|
default: false,
|
|
@@ -1284,6 +1358,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
1284
1358
|
},
|
|
1285
1359
|
},
|
|
1286
1360
|
|
|
1361
|
+
"startup.showSplash": {
|
|
1362
|
+
type: "boolean",
|
|
1363
|
+
default: false,
|
|
1364
|
+
ui: {
|
|
1365
|
+
tab: "interaction",
|
|
1366
|
+
group: "Startup & Updates",
|
|
1367
|
+
label: "Show Startup Splash",
|
|
1368
|
+
description:
|
|
1369
|
+
"Show the full animated setup splash on normal interactive startup without rerunning setup. Quiet Startup still suppresses it.",
|
|
1370
|
+
},
|
|
1371
|
+
},
|
|
1372
|
+
|
|
1287
1373
|
"startup.setupWizard": {
|
|
1288
1374
|
type: "boolean",
|
|
1289
1375
|
default: true,
|
|
@@ -1505,7 +1591,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
1505
1591
|
// Context promotion
|
|
1506
1592
|
"contextPromotion.enabled": {
|
|
1507
1593
|
type: "boolean",
|
|
1508
|
-
default:
|
|
1594
|
+
default: false,
|
|
1509
1595
|
ui: {
|
|
1510
1596
|
tab: "context",
|
|
1511
1597
|
group: "General",
|
|
@@ -1769,6 +1855,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
1769
1855
|
"qwen3",
|
|
1770
1856
|
"gemini",
|
|
1771
1857
|
"gemma",
|
|
1858
|
+
"minimax",
|
|
1772
1859
|
] as const,
|
|
1773
1860
|
default: "auto",
|
|
1774
1861
|
ui: {
|
|
@@ -1795,6 +1882,7 @@ export const SETTINGS_SCHEMA = {
|
|
|
1795
1882
|
{ value: "qwen3", label: "Qwen3", description: "Use the Qwen3 owned dialect." },
|
|
1796
1883
|
{ value: "gemini", label: "Gemini", description: "Use the Gemini owned dialect." },
|
|
1797
1884
|
{ value: "gemma", label: "Gemma", description: "Use the Gemma owned dialect." },
|
|
1885
|
+
{ value: "minimax", label: "MiniMax", description: "Use the MiniMax owned dialect." },
|
|
1798
1886
|
],
|
|
1799
1887
|
},
|
|
1800
1888
|
},
|
|
@@ -3857,6 +3945,34 @@ export const SETTINGS_SCHEMA = {
|
|
|
3857
3945
|
description: "Providers that web_search should never use, even as fallbacks",
|
|
3858
3946
|
},
|
|
3859
3947
|
},
|
|
3948
|
+
"providers.antigravityEndpoint": {
|
|
3949
|
+
type: "enum",
|
|
3950
|
+
values: ["auto", "production", "sandbox"] as const,
|
|
3951
|
+
default: "auto",
|
|
3952
|
+
ui: {
|
|
3953
|
+
tab: "providers",
|
|
3954
|
+
group: "Services",
|
|
3955
|
+
label: "Antigravity Endpoint Mode",
|
|
3956
|
+
description: "Endpoint routing strategy for google-antigravity providers (chat, search, image, discovery)",
|
|
3957
|
+
options: [
|
|
3958
|
+
{
|
|
3959
|
+
value: "auto",
|
|
3960
|
+
label: "Auto",
|
|
3961
|
+
description: "Try production endpoint, fail over to sandbox on 5xx/429",
|
|
3962
|
+
},
|
|
3963
|
+
{
|
|
3964
|
+
value: "production",
|
|
3965
|
+
label: "Production Only",
|
|
3966
|
+
description: "Force production endpoint only",
|
|
3967
|
+
},
|
|
3968
|
+
{
|
|
3969
|
+
value: "sandbox",
|
|
3970
|
+
label: "Sandbox Only",
|
|
3971
|
+
description: "Force sandbox endpoint only",
|
|
3972
|
+
},
|
|
3973
|
+
],
|
|
3974
|
+
},
|
|
3975
|
+
},
|
|
3860
3976
|
"providers.image": {
|
|
3861
3977
|
type: "enum",
|
|
3862
3978
|
values: ["auto", "openai", "antigravity", "xai", "gemini", "openrouter"] as const,
|
|
@@ -19,6 +19,7 @@ import tsImportType from "./ts-import-type.md" with { type: "text" };
|
|
|
19
19
|
import tsNoAny from "./ts-no-any.md" with { type: "text" };
|
|
20
20
|
import tsNoDeprecatedLeftovers from "./ts-no-deprecated-leftovers.md" with { type: "text" };
|
|
21
21
|
import tsNoDynamicImport from "./ts-no-dynamic-import.md" with { type: "text" };
|
|
22
|
+
import tsNoInlineCastAccess from "./ts-no-inline-cast-access.md" with { type: "text" };
|
|
22
23
|
import tsNoReturnType from "./ts-no-return-type.md" with { type: "text" };
|
|
23
24
|
import tsNoTestTimers from "./ts-no-test-timers.md" with { type: "text" };
|
|
24
25
|
import tsNoTinyFunctions from "./ts-no-tiny-functions.md" with { type: "text" };
|
|
@@ -45,6 +46,7 @@ export const BUILTIN_RULE_SOURCES: readonly BuiltinRuleSource[] = [
|
|
|
45
46
|
{ name: "ts-no-any", content: tsNoAny },
|
|
46
47
|
{ name: "ts-no-deprecated-leftovers", content: tsNoDeprecatedLeftovers },
|
|
47
48
|
{ name: "ts-no-dynamic-import", content: tsNoDynamicImport },
|
|
49
|
+
{ name: "ts-no-inline-cast-access", content: tsNoInlineCastAccess },
|
|
48
50
|
{ name: "ts-no-return-type", content: tsNoReturnType },
|
|
49
51
|
{ name: "ts-no-test-timers", content: tsNoTestTimers },
|
|
50
52
|
{ name: "ts-no-tiny-functions", content: tsNoTinyFunctions },
|
|
@@ -17,7 +17,7 @@ Use top-level `import type` declarations for type-only dependencies. NEVER write
|
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
19
|
// Bad — inline imports hide dependencies in signatures.
|
|
20
|
-
function run(client: import("some-sdk").Client, input: import("
|
|
20
|
+
function run(client: import("some-sdk").Client, input: import("arktype").infer<Schema>): Promise<Output>;
|
|
21
21
|
|
|
22
22
|
// Bad — annotations become path dumps.
|
|
23
23
|
const options: import("some-sdk/config").ClientOptions = { ... };
|
|
@@ -28,7 +28,7 @@ const options: import("some-sdk/config").ClientOptions = { ... };
|
|
|
28
28
|
```typescript
|
|
29
29
|
import type { Client } from "some-sdk";
|
|
30
30
|
import type { ClientOptions } from "some-sdk/config";
|
|
31
|
-
import type { infer as Infer } from "
|
|
31
|
+
import type { infer as Infer } from "arktype";
|
|
32
32
|
|
|
33
33
|
function run(client: Client, input: Infer<Schema>): Promise<Output>;
|
|
34
34
|
const options: ClientOptions = { ... };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Never use `any` in TypeScript annotations or assertions — use `unknown`, generics, or the actual type"
|
|
2
|
+
description: "Never use `any` in TypeScript annotations or assertions — use `unknown`, generics, a schema parse at trust boundaries, or the actual type"
|
|
3
3
|
condition: ": any|as any"
|
|
4
4
|
scope: "tool:edit(*.ts), tool:edit(*.tsx), tool:write(*.ts), tool:write(*.tsx)"
|
|
5
5
|
---
|
|
@@ -9,6 +9,7 @@ Never use `: any` or `as any`. They disable type checking exactly where the boun
|
|
|
9
9
|
## Use instead
|
|
10
10
|
|
|
11
11
|
- `unknown` for unvalidated input.
|
|
12
|
+
- A schema parse (Zod, Valibot, …; e.g. Zod v4 when it is already in the project) for untrusted or external input — validate once, then consume a typed value.
|
|
12
13
|
- A domain type when the shape is known.
|
|
13
14
|
- A generic when the caller supplies the shape.
|
|
14
15
|
- A type guard when runtime checks establish shape.
|
|
@@ -25,7 +26,7 @@ function readId(value: any): any {
|
|
|
25
26
|
// Good — validate unknown input.
|
|
26
27
|
function readId(value: unknown): string | undefined {
|
|
27
28
|
if (value && typeof value === "object" && "id" in value) {
|
|
28
|
-
const candidate =
|
|
29
|
+
const candidate = value.id; // `in` narrowing types this as unknown — no cast needed
|
|
29
30
|
return typeof candidate === "string" ? candidate : undefined;
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -53,4 +54,12 @@ const config = { port: 3000 } as any as ServerConfig;
|
|
|
53
54
|
const config = { port: 3000 } satisfies ServerConfig;
|
|
54
55
|
```
|
|
55
56
|
|
|
57
|
+
## Choosing: guard vs schema vs unchecked cast
|
|
58
|
+
|
|
59
|
+
| Situation | Reach for |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| Data from outside your control — network/RPC, parsed JSON, config files, env vars, CLI/IPC, persisted blobs — or a shape reused across the codebase | **Schema parse** (Zod/Valibot/…): runtime validation, typed output, and a clear error on bad shape |
|
|
62
|
+
| In-process value the compiler merely lost track of — an `unknown` from a generic, a union to discriminate, a one-off read of a field or two | **Type guard** (`in` / `typeof`): no dependency, but it only checks what you write, so keep the checked surface small |
|
|
63
|
+
| You genuinely know more than the compiler *and* a runtime check is impossible or meaningless — a well-known DOM node (`as HTMLElement`), structurally-identical types inference can't unify, a library type that is wrong or unexpressible, `as const` | **Unchecked cast** (`as` / `as unknown as T`): assign to a named const with a one-line reason; never for raw external input |
|
|
64
|
+
|
|
56
65
|
If a library boundary truly requires an unchecked cast, use `as unknown as T` with a short reason. Never leave a bare `any`.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Don't assert an inline object type and immediately read a property — `(x as { y: T }).y` trusts an unchecked shape; validate with a schema parse at trust boundaries, narrow with `in`/`typeof`, or use a validated named type"
|
|
3
|
+
scope: "tool:edit(*.{ts,tsx,mts,cts}), tool:write(*.{ts,tsx,mts,cts})"
|
|
4
|
+
interruptMode: tool-only
|
|
5
|
+
astCondition:
|
|
6
|
+
- "($X as { $$$BODY }).$PROP"
|
|
7
|
+
- "($X as { $$$BODY })?.$PROP"
|
|
8
|
+
- "($X as { $$$BODY })[$IDX]"
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
**Don't assert an inline object type just to read a property.** `(value as { content: unknown }).content` fabricates a shape the compiler never verified, then trusts it for exactly one access. If `value` isn't that shape, the read is silently wrong and no type error ever fires.
|
|
12
|
+
|
|
13
|
+
## Why it's wrong
|
|
14
|
+
|
|
15
|
+
- The cast is an unchecked assertion — it suppresses the type error instead of proving the shape.
|
|
16
|
+
- It localizes the lie to one expression, so the next reader can't tell whether the value was ever validated.
|
|
17
|
+
- It almost always stands in for the real fix: runtime narrowing or a validated type at the boundary.
|
|
18
|
+
|
|
19
|
+
## Avoid
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const content = (value as { content: unknown }).content;
|
|
23
|
+
const id = (resp as { data: { id: string } }).data.id;
|
|
24
|
+
const name = (payload as { name?: string })?.name;
|
|
25
|
+
const flag = (opts as { enabled: boolean })["enabled"];
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Use
|
|
29
|
+
|
|
30
|
+
Prefer a schema parse at the boundary when a validator is available (Zod, Valibot, …) — validate once, then read from a fully typed value. If Zod is already in the project (e.g. Zod v4):
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { z } from "zod/v4";
|
|
34
|
+
|
|
35
|
+
const Resp = z.object({ data: z.object({ id: z.string() }) });
|
|
36
|
+
|
|
37
|
+
const resp = Resp.parse(raw); // throws on bad input; resp.data.id is typed string
|
|
38
|
+
const id = resp.data.id;
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For a one-off read of a single field, narrow with `in` / `typeof` so the access is actually checked — TypeScript infers `unknown` for the property after `"content" in value`:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
if (value && typeof value === "object" && "content" in value) {
|
|
45
|
+
const content = value.content; // unknown — validate before use
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Choosing: guard vs schema vs unchecked cast
|
|
50
|
+
|
|
51
|
+
| Situation | Reach for |
|
|
52
|
+
| --- | --- |
|
|
53
|
+
| Data from outside your control — network/RPC, parsed JSON, config files, env vars, CLI/IPC, persisted blobs — or a shape reused across the codebase | **Schema parse** (Zod/Valibot/…): runtime validation, typed output, and a clear error on bad shape |
|
|
54
|
+
| In-process value the compiler merely lost track of — an `unknown` from a generic, a union to discriminate, a one-off read of a field or two | **Type guard** (`in` / `typeof`): no dependency, but it only checks what you write, so keep the checked surface small |
|
|
55
|
+
| You genuinely know more than the compiler *and* a runtime check is impossible or meaningless — a well-known DOM node (`as HTMLElement`), structurally-identical types inference can't unify, a library type that's wrong or unexpressible, `as const` | **Unchecked cast** (`as`): assign to a named const with a one-line reason; never for raw external input, never inlined into a member access |
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* deliberately permissive (
|
|
2
|
+
* Arktype schema for the `edit` tool's hashline mode payload. The schema is
|
|
3
|
+
* deliberately permissive (allows extra keys) so providers can attach extra
|
|
4
4
|
* keys without rejection; only `input` is required. `_input` is accepted as a
|
|
5
5
|
* provider-emitted alias for `input`.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import { type } from "arktype";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
const requiredInputSchema = type({ input: "string" });
|
|
10
|
+
const inputAliasSchema = type({ "input?": "string", "_input?": "string" });
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
export const hashlineEditParamsSchema = inputAliasSchema
|
|
13
|
+
.pipe(raw => {
|
|
14
|
+
if (raw.input !== undefined || raw._input === undefined) return raw;
|
|
15
|
+
return { ...raw, input: raw._input };
|
|
16
|
+
})
|
|
17
|
+
.pipe(requiredInputSchema);
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
}, z.object({ input: z.string() }).passthrough());
|
|
17
|
-
|
|
18
|
-
export type HashlineParams = z.infer<typeof hashlineEditParamsSchema>;
|
|
19
|
+
export type HashlineParams = Parameters<typeof hashlineEditParamsSchema.assert>[0];
|
package/src/edit/index.ts
CHANGED
|
@@ -4,7 +4,6 @@ import hashlineDescription from "@oh-my-pi/hashline/prompt.md" with { type: "tex
|
|
|
4
4
|
import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
|
|
5
5
|
import type { ToolExample } from "@oh-my-pi/pi-ai";
|
|
6
6
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
7
|
-
import type { z } from "zod/v4";
|
|
8
7
|
import {
|
|
9
8
|
createLspWritethrough,
|
|
10
9
|
type FileDiagnosticsResult,
|
|
@@ -20,7 +19,7 @@ import type { DeferredDiagnosticsEntry, ToolSession } from "../tools";
|
|
|
20
19
|
import { truncateForPrompt } from "../tools/approval";
|
|
21
20
|
import { isInternalUrlPath } from "../tools/path-utils";
|
|
22
21
|
import { type EditMode, normalizeEditMode, resolveEditMode } from "../utils/edit-mode";
|
|
23
|
-
import { executeHashlineSingle,
|
|
22
|
+
import { executeHashlineSingle, hashlineEditParamsSchema } from "./hashline";
|
|
24
23
|
import { type ApplyPatchParams, applyPatchSchema, expandApplyPatchToEntries } from "./modes/apply-patch";
|
|
25
24
|
import applyPatchGrammar from "./modes/apply-patch.lark" with { type: "text" };
|
|
26
25
|
import { executePatchSingle, type PatchEditEntry, type PatchParams, patchEditSchema } from "./modes/patch";
|
|
@@ -47,6 +46,8 @@ type TInput =
|
|
|
47
46
|
| typeof hashlineEditParamsSchema
|
|
48
47
|
| typeof applyPatchSchema;
|
|
49
48
|
|
|
49
|
+
type HashlineParams = typeof hashlineEditParamsSchema.infer;
|
|
50
|
+
|
|
50
51
|
type EditParams = ReplaceParams | PatchParams | HashlineParams | ApplyPatchParams;
|
|
51
52
|
|
|
52
53
|
type EditModeDefinition = {
|
|
@@ -443,7 +444,7 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
443
444
|
caption: "Multiple entries",
|
|
444
445
|
note: "All entries in one call apply to the top-level `path`; use separate calls for different files.",
|
|
445
446
|
},
|
|
446
|
-
] satisfies readonly ToolExample<
|
|
447
|
+
] satisfies readonly ToolExample<PatchParams>[],
|
|
447
448
|
execute: (
|
|
448
449
|
tool: EditTool,
|
|
449
450
|
params: EditParams,
|
|
@@ -479,7 +480,7 @@ export class EditTool implements AgentTool<TInput> {
|
|
|
479
480
|
input: '*** Begin Patch\n*** Add File: hello.txt\n+Hello world\n*** Update File: src/app.py\n*** Move to: src/main.py\n@@ def greet():\n-print("Hi")\n+print("Hello, world!")\n*** Delete File: obsolete.txt\n*** End Patch\n',
|
|
480
481
|
},
|
|
481
482
|
},
|
|
482
|
-
] satisfies readonly ToolExample<
|
|
483
|
+
] satisfies readonly ToolExample<ApplyPatchParams>[],
|
|
483
484
|
execute: (
|
|
484
485
|
tool: EditTool,
|
|
485
486
|
params: EditParams,
|
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
* the `patch` mode.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { type } from "arktype";
|
|
12
12
|
import { parseApplyPatch, parseApplyPatchStreaming } from "../apply-patch/parser";
|
|
13
13
|
import { ApplyPatchError } from "../diff";
|
|
14
14
|
import type { PatchEditEntry } from "./patch";
|
|
15
15
|
|
|
16
|
-
export const applyPatchSchema =
|
|
17
|
-
input:
|
|
16
|
+
export const applyPatchSchema = type({
|
|
17
|
+
input: "string",
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
export type ApplyPatchParams =
|
|
20
|
+
export type ApplyPatchParams = typeof applyPatchSchema.infer;
|
|
21
21
|
|
|
22
22
|
export type ApplyPatchEntry = PatchEditEntry & { path: string };
|
|
23
23
|
|
package/src/edit/modes/patch.ts
CHANGED
|
@@ -9,7 +9,7 @@ import * as fs from "node:fs";
|
|
|
9
9
|
import * as path from "node:path";
|
|
10
10
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
11
11
|
import { isEnoent } from "@oh-my-pi/pi-utils";
|
|
12
|
-
import {
|
|
12
|
+
import { type } from "arktype";
|
|
13
13
|
import {
|
|
14
14
|
type FileDiagnosticsResult,
|
|
15
15
|
flushLspWritethroughBatch,
|
|
@@ -1631,23 +1631,20 @@ export async function computePatchDiff(
|
|
|
1631
1631
|
}
|
|
1632
1632
|
}
|
|
1633
1633
|
|
|
1634
|
-
export const patchEditEntrySchema =
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
export const patchEditSchema =
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
export type PatchEditEntry = z.infer<typeof patchEditEntrySchema>;
|
|
1650
|
-
export type PatchParams = z.infer<typeof patchEditSchema>;
|
|
1634
|
+
export const patchEditEntrySchema = type({
|
|
1635
|
+
"op?": "'create' | 'delete' | 'update'",
|
|
1636
|
+
"rename?": "string",
|
|
1637
|
+
"diff?": "string",
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
export type PatchEditEntry = typeof patchEditEntrySchema.infer;
|
|
1641
|
+
|
|
1642
|
+
export const patchEditSchema = type({
|
|
1643
|
+
path: "string",
|
|
1644
|
+
edits: patchEditEntrySchema.array(),
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
export type PatchParams = typeof patchEditSchema.infer;
|
|
1651
1648
|
|
|
1652
1649
|
export interface ExecutePatchSingleOptions {
|
|
1653
1650
|
session: ToolSession;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* fallback strategies for finding text in files.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
8
|
-
import {
|
|
8
|
+
import { type } from "arktype";
|
|
9
9
|
import type { WritethroughCallback, WritethroughDeferredHandle } from "../../lsp";
|
|
10
10
|
import type { ToolSession } from "../../tools";
|
|
11
11
|
import { invalidateFsScanAfterWrite } from "../../tools/fs-cache-invalidation";
|
|
@@ -1010,23 +1010,19 @@ export function findContextLine(
|
|
|
1010
1010
|
return { index: undefined, confidence: bestScore };
|
|
1011
1011
|
}
|
|
1012
1012
|
|
|
1013
|
-
export const replaceEditEntrySchema =
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
})
|
|
1019
|
-
.strict();
|
|
1013
|
+
export const replaceEditEntrySchema = type({
|
|
1014
|
+
old_text: "string",
|
|
1015
|
+
new_text: "string",
|
|
1016
|
+
"all?": "boolean",
|
|
1017
|
+
});
|
|
1020
1018
|
|
|
1021
|
-
export const replaceEditSchema =
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
})
|
|
1026
|
-
.strict();
|
|
1019
|
+
export const replaceEditSchema = type({
|
|
1020
|
+
path: "string",
|
|
1021
|
+
edits: replaceEditEntrySchema.array(),
|
|
1022
|
+
});
|
|
1027
1023
|
|
|
1028
|
-
export type ReplaceEditEntry =
|
|
1029
|
-
export type ReplaceParams =
|
|
1024
|
+
export type ReplaceEditEntry = typeof replaceEditEntrySchema.infer;
|
|
1025
|
+
export type ReplaceParams = typeof replaceEditSchema.infer;
|
|
1030
1026
|
|
|
1031
1027
|
export interface ExecuteReplaceSingleOptions {
|
|
1032
1028
|
session: ToolSession;
|
|
@@ -1042,7 +1038,7 @@ export interface ExecuteReplaceSingleOptions {
|
|
|
1042
1038
|
|
|
1043
1039
|
export async function executeReplaceSingle(
|
|
1044
1040
|
options: ExecuteReplaceSingleOptions,
|
|
1045
|
-
): Promise<AgentToolResult<EditToolDetails,
|
|
1041
|
+
): Promise<AgentToolResult<EditToolDetails, ReplaceEditEntry>> {
|
|
1046
1042
|
const {
|
|
1047
1043
|
session,
|
|
1048
1044
|
path,
|
package/src/edit/renderer.ts
CHANGED
|
@@ -591,7 +591,6 @@ export const editToolRenderer = {
|
|
|
591
591
|
uiTheme: Theme,
|
|
592
592
|
): Component {
|
|
593
593
|
const renderContext = options.renderContext;
|
|
594
|
-
|
|
595
594
|
const editArgs = args as EditRenderArgs;
|
|
596
595
|
const hashlineInputSummary = getHashlineInputRenderSummary(editArgs, renderContext?.editMode);
|
|
597
596
|
const applyPatchSummary = getApplyPatchRenderSummary(editArgs, options.isPartial, renderContext?.editMode);
|
package/src/eval/agent-bridge.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as fs from "node:fs/promises";
|
|
|
5
5
|
import * as os from "node:os";
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import { prompt, Snowflake } from "@oh-my-pi/pi-utils";
|
|
8
|
-
import {
|
|
8
|
+
import { type } from "arktype";
|
|
9
9
|
import { resolveAgentModelPatterns } from "../config/model-resolver";
|
|
10
10
|
import type { LocalProtocolOptions } from "../internal-urls";
|
|
11
11
|
import { MCPManager } from "../mcp/manager";
|
|
@@ -31,12 +31,12 @@ export const EVAL_AGENT_MAX_DEPTH = 3;
|
|
|
31
31
|
const DEFAULT_AGENT_TYPE = "task";
|
|
32
32
|
const DEFAULT_AGENT_LABEL = "EvalAgent";
|
|
33
33
|
|
|
34
|
-
const agentArgsSchema =
|
|
35
|
-
prompt:
|
|
36
|
-
agentType:
|
|
37
|
-
model:
|
|
38
|
-
label:
|
|
39
|
-
schema:
|
|
34
|
+
const agentArgsSchema = type({
|
|
35
|
+
prompt: "string>0",
|
|
36
|
+
"agentType?": "string>0",
|
|
37
|
+
"model?": "string>0|string>0[]",
|
|
38
|
+
"label?": "string",
|
|
39
|
+
"schema?": "unknown",
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
interface EvalAgentArgs {
|
|
@@ -64,13 +64,11 @@ export interface EvalAgentResult {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function parseAgentArgs(args: unknown): EvalAgentArgs {
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
const where = issue?.path.length ? `${issue.path.join(".")}: ` : "";
|
|
71
|
-
throw new ToolError(`agent() received invalid arguments: ${where}${issue?.message ?? "bad input"}`);
|
|
67
|
+
const result = agentArgsSchema(args);
|
|
68
|
+
if (result instanceof type.errors) {
|
|
69
|
+
throw new ToolError(`agent() received invalid arguments: ${result.summary}`);
|
|
72
70
|
}
|
|
73
|
-
return
|
|
71
|
+
return result;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
function assertDepthAllowed(session: ToolSession): void {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { instrumentedCompleteSimple, resolveTelemetry } from "@oh-my-pi/pi-agent-core";
|
|
15
15
|
import { type Api, Effort, type Model, type Tool } from "@oh-my-pi/pi-ai";
|
|
16
16
|
import { getSupportedEfforts } from "@oh-my-pi/pi-catalog/model-thinking";
|
|
17
|
-
import {
|
|
17
|
+
import { type } from "arktype";
|
|
18
18
|
import { extractTextContent, extractToolCall, parseJsonPayload } from "../commit/utils";
|
|
19
19
|
|
|
20
20
|
import {
|
|
@@ -42,11 +42,11 @@ const TIER_TO_PATTERN: Record<CompletionTier, string> = {
|
|
|
42
42
|
slow: "pi/slow",
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
const completionArgsSchema =
|
|
46
|
-
prompt:
|
|
47
|
-
model:
|
|
48
|
-
system:
|
|
49
|
-
schema:
|
|
45
|
+
const completionArgsSchema = type({
|
|
46
|
+
prompt: "string>0",
|
|
47
|
+
"model?": "'smol'|'default'|'slow'",
|
|
48
|
+
"system?": "string",
|
|
49
|
+
"schema?": "Record<string,unknown>",
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
export interface EvalCompletionBridgeOptions {
|
|
@@ -107,18 +107,18 @@ export async function runEvalCompletion(
|
|
|
107
107
|
args: unknown,
|
|
108
108
|
options: EvalCompletionBridgeOptions,
|
|
109
109
|
): Promise<EvalCompletionResult> {
|
|
110
|
-
const parsed = completionArgsSchema
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
const where = issue?.path.length ? `${issue.path.join(".")}: ` : "";
|
|
114
|
-
throw new ToolError(`completion() received invalid arguments: ${where}${issue?.message ?? "bad input"}`);
|
|
110
|
+
const parsed = completionArgsSchema(args);
|
|
111
|
+
if (parsed instanceof type.errors) {
|
|
112
|
+
throw new ToolError(`completion() received invalid arguments: ${parsed.summary}`);
|
|
115
113
|
}
|
|
116
|
-
const { prompt, model:
|
|
114
|
+
const { prompt, model: modelTier, system, schema } = parsed;
|
|
115
|
+
// Apply default value for model if not provided
|
|
116
|
+
const finalTier: CompletionTier = modelTier ?? "default";
|
|
117
117
|
|
|
118
|
-
const model = resolveTierModel(
|
|
118
|
+
const model = resolveTierModel(finalTier, options.session);
|
|
119
119
|
if (!model) {
|
|
120
120
|
throw new ToolError(
|
|
121
|
-
`completion() could not resolve a model for the "${
|
|
121
|
+
`completion() could not resolve a model for the "${finalTier}" tier. Configure modelRoles.${finalTier === "default" ? "default" : finalTier} or ensure a provider is available.`,
|
|
122
122
|
);
|
|
123
123
|
}
|
|
124
124
|
|
|
@@ -162,7 +162,7 @@ export async function runEvalCompletion(
|
|
|
162
162
|
{
|
|
163
163
|
apiKey: registry.resolver(model, options.session.getSessionId?.() ?? undefined),
|
|
164
164
|
signal: options.signal,
|
|
165
|
-
reasoning: reasoningForTier(
|
|
165
|
+
reasoning: reasoningForTier(finalTier, model),
|
|
166
166
|
toolChoice: schema ? { type: "tool", name: STRUCTURED_TOOL_NAME } : undefined,
|
|
167
167
|
},
|
|
168
168
|
{ telemetry, oneshotKind: "eval_completion" },
|
|
@@ -197,7 +197,15 @@ export async function runEvalCompletion(
|
|
|
197
197
|
if (!resultText) throw new ToolError("completion() returned no text output.");
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
options.emitStatus?.({
|
|
200
|
+
options.emitStatus?.({
|
|
201
|
+
op: "completion",
|
|
202
|
+
model: formatModelString(model),
|
|
203
|
+
tier: finalTier,
|
|
204
|
+
chars: resultText.length,
|
|
205
|
+
});
|
|
201
206
|
|
|
202
|
-
return {
|
|
207
|
+
return {
|
|
208
|
+
text: resultText,
|
|
209
|
+
details: { model: formatModelString(model), tier: finalTier, structured: Boolean(schema) },
|
|
210
|
+
};
|
|
203
211
|
}
|