@oh-my-pi/pi-coding-agent 17.2.10 → 17.2.12
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 +53 -0
- package/dist/{CHANGELOG-rhwzpexa.md → CHANGELOG-k9ghy5sn.md} +53 -0
- package/dist/cli.js +10775 -10762
- package/dist/types/advisor/runtime.d.ts +1 -1
- package/dist/types/capability/mcp.d.ts +11 -0
- package/dist/types/capability/skill.d.ts +6 -0
- package/dist/types/cli/command-help.d.ts +3 -0
- package/dist/types/commands/share.d.ts +25 -0
- package/dist/types/commit/agentic/index.d.ts +3 -1
- package/dist/types/commit/execute.d.ts +32 -0
- package/dist/types/commit/index.d.ts +2 -1
- package/dist/types/commit/pipeline.d.ts +7 -1
- package/dist/types/config/custom-models.d.ts +31 -0
- package/dist/types/config/model-config-values.d.ts +19 -0
- package/dist/types/config/model-patch.d.ts +93 -0
- package/dist/types/config/model-provider-discovery.d.ts +51 -0
- package/dist/types/config/model-registry.d.ts +9 -52
- package/dist/types/config/settings-schema.d.ts +1 -34
- package/dist/types/config/settings.d.ts +5 -3
- package/dist/types/debug/raw-sse-buffer.d.ts +9 -0
- package/dist/types/discovery/agent-plugin-format.d.ts +136 -0
- package/dist/types/discovery/agent-plugins.d.ts +1 -0
- package/dist/types/discovery/contained-path.d.ts +33 -0
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/eval/executor-base.d.ts +8 -2
- package/dist/types/eval/kernel-session-registry.d.ts +60 -0
- package/dist/types/export/share.d.ts +1 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +7 -0
- package/dist/types/extensibility/extensions/types.d.ts +11 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -2
- package/dist/types/extensibility/skills.d.ts +5 -0
- package/dist/types/lsp/diagnostics.d.ts +96 -0
- package/dist/types/lsp/index.d.ts +7 -128
- package/dist/types/lsp/servers.d.ts +72 -0
- package/dist/types/lsp/tool.d.ts +42 -0
- package/dist/types/lsp/workspace-diagnostics.d.ts +12 -0
- package/dist/types/lsp/writethrough.d.ts +33 -0
- package/dist/types/mcp/transports/header-policy.d.ts +46 -0
- package/dist/types/mcp/types.d.ts +15 -0
- package/dist/types/modes/components/agent-hub-projection.d.ts +2 -7
- package/dist/types/modes/components/agent-hub-renderer.d.ts +0 -7
- package/dist/types/modes/components/agent-hub.d.ts +2 -0
- package/dist/types/modes/components/agent-transcript-viewer.d.ts +2 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +1 -2
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +2 -0
- package/dist/types/modes/theme/color.d.ts +19 -0
- package/dist/types/modes/theme/loader.d.ts +19 -0
- package/dist/types/modes/theme/schema.d.ts +175 -0
- package/dist/types/modes/theme/symbols.d.ts +28 -0
- package/dist/types/modes/theme/theme-class.d.ts +244 -0
- package/dist/types/modes/theme/theme.d.ts +9 -280
- package/dist/types/modes/theme/tui-adapters.d.ts +13 -0
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +3 -2
- package/dist/types/registry/agent-registry.d.ts +1 -3
- package/dist/types/secrets/index.d.ts +26 -2
- package/dist/types/secrets/message-transform.d.ts +40 -0
- package/dist/types/secrets/obfuscator.d.ts +0 -108
- package/dist/types/secrets/placeholder-scan.d.ts +95 -0
- package/dist/types/secrets/placeholder.d.ts +94 -0
- package/dist/types/secrets/replacement.d.ts +82 -0
- package/dist/types/session/agent-session-events.d.ts +2 -2
- package/dist/types/session/agent-session-types.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +2 -2
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/prewalk.d.ts +3 -1
- package/dist/types/session/session-handoff.d.ts +3 -3
- package/dist/types/session/session-manager.d.ts +32 -0
- package/dist/types/session/session-provider-boundary.d.ts +1 -1
- package/dist/types/session/session-tools.d.ts +8 -0
- package/dist/types/session/turn-recovery.d.ts +9 -4
- package/dist/types/slash-commands/builtin-collaboration.d.ts +2 -0
- package/dist/types/slash-commands/builtin-completions.d.ts +36 -0
- package/dist/types/slash-commands/builtin-control.d.ts +2 -0
- package/dist/types/slash-commands/builtin-lifecycle.d.ts +3 -0
- package/dist/types/slash-commands/builtin-marketplace.d.ts +11 -0
- package/dist/types/slash-commands/builtin-modes.d.ts +5 -0
- package/dist/types/slash-commands/builtin-registry.d.ts +1 -1
- package/dist/types/slash-commands/builtin-session.d.ts +2 -0
- package/dist/types/task/index.d.ts +2 -0
- package/dist/types/tools/gh-common.d.ts +69 -0
- package/dist/types/tools/gh-pr-checkout.d.ts +84 -0
- package/dist/types/tools/gh-pr-diff.d.ts +102 -0
- package/dist/types/tools/gh-run-watch.d.ts +78 -0
- package/dist/types/tools/gh-search.d.ts +61 -0
- package/dist/types/tools/gh-types.d.ts +340 -0
- package/dist/types/tools/gh-view.d.ts +88 -0
- package/dist/types/tools/gh.d.ts +4 -201
- package/dist/types/tools/read-archive.d.ts +16 -0
- package/dist/types/tools/read-format.d.ts +104 -0
- package/dist/types/tools/read-path-resolution.d.ts +19 -0
- package/dist/types/tools/read-pdf-images.d.ts +12 -0
- package/dist/types/tools/read-renderer.d.ts +24 -0
- package/dist/types/tools/read-selector.d.ts +27 -0
- package/dist/types/tools/read-sqlite.d.ts +16 -0
- package/dist/types/tools/read-summary.d.ts +19 -0
- package/dist/types/tools/read.d.ts +1 -23
- package/dist/types/tools/shell-tokenize.d.ts +18 -1
- package/dist/types/utils/changelog.d.ts +0 -5
- package/package.json +13 -13
- package/scripts/legacy-pi-virtual-module.ts +4 -1
- package/src/advisor/runtime.ts +12 -7
- package/src/capability/mcp.ts +11 -0
- package/src/capability/skill.ts +6 -0
- package/src/cli/command-help.ts +4 -0
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli-commands.ts +5 -0
- package/src/commands/commit.ts +16 -3
- package/src/commands/share.ts +71 -0
- package/src/commit/agentic/index.ts +39 -21
- package/src/commit/execute.ts +56 -0
- package/src/commit/index.ts +2 -1
- package/src/commit/pipeline.ts +20 -7
- package/src/config/custom-models.ts +188 -0
- package/src/config/model-config-values.ts +128 -0
- package/src/config/model-discovery.ts +1 -1
- package/src/config/model-patch.ts +252 -0
- package/src/config/model-provider-discovery.ts +132 -0
- package/src/config/model-registry.ts +84 -704
- package/src/config/settings-schema.ts +2 -33
- package/src/config/settings.ts +53 -3
- package/src/debug/raw-sse-buffer.ts +20 -0
- package/src/discovery/agent-plugin-format.ts +551 -0
- package/src/discovery/agent-plugins.ts +341 -0
- package/src/discovery/claude-plugins.ts +21 -5
- package/src/discovery/contained-path.ts +75 -0
- package/src/discovery/helpers.ts +23 -9
- package/src/discovery/index.ts +1 -0
- package/src/discovery/omp-plugins.ts +20 -7
- package/src/edit/hashline/diff.ts +5 -1
- package/src/eval/executor-base.ts +39 -6
- package/src/eval/jl/executor.ts +82 -371
- package/src/eval/kernel-session-registry.ts +398 -0
- package/src/eval/py/executor.ts +53 -261
- package/src/eval/rb/executor.ts +36 -279
- package/src/exec/non-interactive-env.ts +1 -0
- package/src/export/share.ts +2 -1
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/extensions/loader.ts +78 -14
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +12 -0
- package/src/extensibility/plugins/marketplace/manager.ts +2 -1
- package/src/extensibility/shared-events.ts +3 -2
- package/src/extensibility/skills.ts +9 -0
- package/src/internal-urls/skill-protocol.ts +14 -0
- package/src/internal-urls/vault-protocol.ts +2 -2
- package/src/launch/client.ts +11 -1
- package/src/launch/protocol.ts +7 -2
- package/src/lsp/diagnostics.ts +516 -0
- package/src/lsp/index.ts +20 -2819
- package/src/lsp/servers.ts +296 -0
- package/src/lsp/tool.ts +1352 -0
- package/src/lsp/workspace-diagnostics.ts +170 -0
- package/src/lsp/writethrough.ts +561 -0
- package/src/main.ts +3 -2
- package/src/mcp/config.ts +3 -0
- package/src/mcp/manager.ts +12 -9
- package/src/mcp/transports/header-policy.ts +95 -0
- package/src/mcp/transports/http.ts +35 -52
- package/src/mcp/transports/sse.ts +20 -27
- package/src/mcp/types.ts +15 -0
- package/src/modes/acp/acp-agent.ts +15 -4
- package/src/modes/components/agent-dashboard.ts +2 -0
- package/src/modes/components/agent-hub-projection.ts +2 -2
- package/src/modes/components/agent-hub-renderer.ts +3 -7
- package/src/modes/components/agent-hub.ts +5 -0
- package/src/modes/components/agent-transcript-viewer.ts +3 -0
- package/src/modes/components/chat-transcript-builder.ts +3 -0
- package/src/modes/components/custom-editor.ts +0 -9
- package/src/modes/components/status-line/component.ts +1 -0
- package/src/modes/components/status-line/segments.ts +6 -4
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/tool-execution.ts +13 -16
- package/src/modes/components/tree-selector.ts +62 -3
- package/src/modes/controllers/command-controller.ts +8 -2
- package/src/modes/controllers/event-controller.ts +15 -15
- package/src/modes/controllers/input-controller.ts +20 -2
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/modes/theme/color.ts +133 -0
- package/src/modes/theme/loader.ts +178 -0
- package/src/modes/theme/schema.ts +263 -0
- package/src/modes/theme/symbols.ts +1000 -0
- package/src/modes/theme/theme-class.ts +611 -0
- package/src/modes/theme/theme.ts +27 -2453
- package/src/modes/theme/tui-adapters.ts +279 -0
- package/src/modes/utils/transcript-render-helpers.ts +4 -2
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/registry/agent-registry.ts +2 -2
- package/src/sdk.ts +6 -49
- package/src/secrets/index.ts +51 -6
- package/src/secrets/message-transform.ts +287 -0
- package/src/secrets/obfuscator.ts +39 -1303
- package/src/secrets/placeholder-scan.ts +506 -0
- package/src/secrets/placeholder.ts +309 -0
- package/src/secrets/replacement.ts +216 -0
- package/src/session/agent-session-events.ts +2 -2
- package/src/session/agent-session-types.ts +6 -0
- package/src/session/agent-session.ts +146 -21
- package/src/session/indexed-session-storage.ts +7 -2
- package/src/session/messages.ts +1 -0
- package/src/session/prewalk.ts +57 -17
- package/src/session/session-advisors.ts +32 -34
- package/src/session/session-context.ts +3 -5
- package/src/session/session-handoff.ts +39 -16
- package/src/session/session-manager.ts +67 -3
- package/src/session/session-provider-boundary.ts +3 -6
- package/src/session/session-tools.ts +37 -3
- package/src/session/todo-tracker.ts +11 -1
- package/src/session/turn-recovery.ts +115 -84
- package/src/slash-commands/builtin-collaboration.ts +504 -0
- package/src/slash-commands/builtin-completions.ts +291 -0
- package/src/slash-commands/builtin-control.ts +78 -0
- package/src/slash-commands/builtin-lifecycle.ts +506 -0
- package/src/slash-commands/builtin-marketplace.ts +567 -0
- package/src/slash-commands/builtin-modes.ts +518 -0
- package/src/slash-commands/builtin-registry.ts +21 -2996
- package/src/slash-commands/builtin-session.ts +592 -0
- package/src/task/executor.ts +17 -14
- package/src/task/index.ts +21 -6
- package/src/tools/bash-skill-urls.ts +15 -0
- package/src/tools/bash.ts +10 -11
- package/src/tools/debug.ts +1 -1
- package/src/tools/gh-common.ts +288 -0
- package/src/tools/gh-pr-checkout.ts +679 -0
- package/src/tools/gh-pr-diff.ts +473 -0
- package/src/tools/gh-run-watch.ts +1015 -0
- package/src/tools/gh-search.ts +500 -0
- package/src/tools/gh-types.ts +379 -0
- package/src/tools/gh-view.ts +612 -0
- package/src/tools/gh.ts +109 -3821
- package/src/tools/jtd-to-json-schema.ts +123 -21
- package/src/tools/read-archive.ts +209 -0
- package/src/tools/read-format.ts +593 -0
- package/src/tools/read-path-resolution.ts +36 -0
- package/src/tools/read-pdf-images.ts +250 -0
- package/src/tools/read-renderer.ts +289 -0
- package/src/tools/read-selector.ts +84 -0
- package/src/tools/read-sqlite.ts +215 -0
- package/src/tools/read-summary.ts +199 -0
- package/src/tools/read.ts +82 -1824
- package/src/tools/shell-tokenize.ts +99 -1
- package/src/utils/changelog.ts +1 -1
- package/src/utils/title-generator.ts +3 -1
- package/src/web/search/providers/exa.ts +1 -1
- package/src/web/search/providers/zai.ts +12 -3
|
@@ -11,6 +11,7 @@ import { ModelRegistry } from "../../config/model-registry";
|
|
|
11
11
|
import { Settings } from "../../config/settings";
|
|
12
12
|
import { discoverAuthStorage, discoverContextFiles, loadCliExtensionProviders } from "../../sdk";
|
|
13
13
|
import * as git from "../../utils/git";
|
|
14
|
+
import { abortOnGitFailure, pushOrAbort } from "../execute";
|
|
14
15
|
import { type ExistingChangelogEntries, runCommitAgentSession } from "./agent";
|
|
15
16
|
import { generateFallbackProposal } from "./fallback";
|
|
16
17
|
import { assignLockFilesToPlan } from "./lock-files";
|
|
@@ -25,7 +26,7 @@ interface CommitExecutionContext {
|
|
|
25
26
|
push: boolean;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
export async function runAgenticCommit(args: CommitCommandArgs): Promise<
|
|
29
|
+
export async function runAgenticCommit(args: CommitCommandArgs): Promise<{ usedFallback: boolean }> {
|
|
29
30
|
const cwd = getProjectDir();
|
|
30
31
|
const [settings, authStorage] = await Promise.all([Settings.init({ cwd }), discoverAuthStorage()]);
|
|
31
32
|
|
|
@@ -56,8 +57,13 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
56
57
|
);
|
|
57
58
|
|
|
58
59
|
if (stagedFiles.length === 0) {
|
|
60
|
+
if (args.push) {
|
|
61
|
+
process.stdout.write("No changes to commit; pushing existing commits...\n");
|
|
62
|
+
await pushOrAbort(cwd);
|
|
63
|
+
return { usedFallback: false };
|
|
64
|
+
}
|
|
59
65
|
process.stderr.write("No changes to commit.\n");
|
|
60
|
-
return;
|
|
66
|
+
return { usedFallback: false };
|
|
61
67
|
}
|
|
62
68
|
|
|
63
69
|
if (!args.noChangelog) {
|
|
@@ -94,7 +100,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
94
100
|
process.stdout.write("● Forcing fallback commit generation...\n");
|
|
95
101
|
const fallbackProposal = generateFallbackProposal(numstat);
|
|
96
102
|
await runSingleCommit(fallbackProposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
97
|
-
return;
|
|
103
|
+
return { usedFallback: true };
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
const trivialChange = detectTrivialChange(diff);
|
|
@@ -111,7 +117,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
111
117
|
warnings: [],
|
|
112
118
|
};
|
|
113
119
|
await runSingleCommit(trivialProposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
114
|
-
return;
|
|
120
|
+
return { usedFallback: false };
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
let existingChangelogEntries: ExistingChangelogEntries[] | undefined;
|
|
@@ -124,6 +130,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
124
130
|
|
|
125
131
|
process.stdout.write("● Starting commit agent...\n");
|
|
126
132
|
let agentSessionCompleted = false;
|
|
133
|
+
let usedFallback = false;
|
|
127
134
|
|
|
128
135
|
try {
|
|
129
136
|
await runCommitAgentSession({
|
|
@@ -141,7 +148,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
141
148
|
existingChangelogEntries,
|
|
142
149
|
onComplete: async commitState => {
|
|
143
150
|
agentSessionCompleted = true;
|
|
144
|
-
await completeAgentCommitState(commitState, {
|
|
151
|
+
usedFallback = await completeAgentCommitState(commitState, {
|
|
145
152
|
cwd,
|
|
146
153
|
dryRun: args.dryRun,
|
|
147
154
|
push: args.push,
|
|
@@ -151,7 +158,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
151
158
|
});
|
|
152
159
|
},
|
|
153
160
|
});
|
|
154
|
-
return;
|
|
161
|
+
return { usedFallback };
|
|
155
162
|
} catch (error) {
|
|
156
163
|
if (agentSessionCompleted) {
|
|
157
164
|
throw error;
|
|
@@ -164,7 +171,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
164
171
|
process.stdout.write("● Using fallback commit generation...\n");
|
|
165
172
|
const fallbackProposal = generateFallbackProposal(numstat);
|
|
166
173
|
await runSingleCommit(fallbackProposal, { cwd, dryRun: args.dryRun, push: args.push });
|
|
167
|
-
return;
|
|
174
|
+
return { usedFallback: true };
|
|
168
175
|
}
|
|
169
176
|
}
|
|
170
177
|
|
|
@@ -175,7 +182,7 @@ async function completeAgentCommitState(
|
|
|
175
182
|
changelogTargets: string[];
|
|
176
183
|
numstat: NumstatEntry[];
|
|
177
184
|
},
|
|
178
|
-
): Promise<
|
|
185
|
+
): Promise<boolean> {
|
|
179
186
|
let usedFallback = false;
|
|
180
187
|
if (!commitState.proposal && !commitState.splitProposal) {
|
|
181
188
|
if ($env.PI_COMMIT_NO_FALLBACK?.toLowerCase() !== "true") {
|
|
@@ -211,7 +218,7 @@ async function completeAgentCommitState(
|
|
|
211
218
|
|
|
212
219
|
if (commitState.proposal) {
|
|
213
220
|
await runSingleCommit(commitState.proposal, ctx);
|
|
214
|
-
return;
|
|
221
|
+
return usedFallback;
|
|
215
222
|
}
|
|
216
223
|
|
|
217
224
|
if (commitState.splitProposal) {
|
|
@@ -221,7 +228,7 @@ async function completeAgentCommitState(
|
|
|
221
228
|
push: ctx.push,
|
|
222
229
|
additionalFiles: updatedChangelogFiles,
|
|
223
230
|
});
|
|
224
|
-
return;
|
|
231
|
+
return usedFallback;
|
|
225
232
|
}
|
|
226
233
|
|
|
227
234
|
throw new Error("Commit agent did not provide a proposal.");
|
|
@@ -238,12 +245,14 @@ async function runSingleCommit(proposal: CommitProposal, ctx: CommitExecutionCon
|
|
|
238
245
|
return;
|
|
239
246
|
}
|
|
240
247
|
process.stdout.write("● Creating commit...\n");
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
248
|
+
try {
|
|
249
|
+
await git.commit(ctx.cwd, commitMessage);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
if (error instanceof git.GitCommandError) abortOnGitFailure("Commit failed", error);
|
|
252
|
+
throw error;
|
|
246
253
|
}
|
|
254
|
+
process.stdout.write("Commit created.\n");
|
|
255
|
+
if (ctx.push) await pushOrAbort(ctx.cwd);
|
|
247
256
|
}
|
|
248
257
|
|
|
249
258
|
async function runSplitCommit(
|
|
@@ -296,7 +305,7 @@ async function runSplitCommit(
|
|
|
296
305
|
process.stdout.write("● Creating split commits...\n");
|
|
297
306
|
const stagedDiff = await git.diff(ctx.cwd, { cached: true, binary: true });
|
|
298
307
|
await git.stage.reset(ctx.cwd);
|
|
299
|
-
for (const commitIndex of order) {
|
|
308
|
+
for (const [position, commitIndex] of order.entries()) {
|
|
300
309
|
const commit = plan.commits[commitIndex];
|
|
301
310
|
await git.stage.hunks(ctx.cwd, commit.changes, { rawDiff: stagedDiff, diffCached: true });
|
|
302
311
|
const analysis: ConventionalAnalysis = {
|
|
@@ -306,14 +315,23 @@ async function runSplitCommit(
|
|
|
306
315
|
issueRefs: commit.issueRefs,
|
|
307
316
|
};
|
|
308
317
|
const message = formatCommitMessage(analysis, commit.summary);
|
|
309
|
-
|
|
318
|
+
try {
|
|
319
|
+
await git.commit(ctx.cwd, message);
|
|
320
|
+
} catch (error) {
|
|
321
|
+
if (error instanceof git.GitCommandError) {
|
|
322
|
+
const stagedNow = await git.diff.changedFiles(ctx.cwd, { cached: true });
|
|
323
|
+
abortOnGitFailure(
|
|
324
|
+
`Commit ${position + 1} of ${order.length} failed`,
|
|
325
|
+
error,
|
|
326
|
+
`${position} of ${order.length} commits created; ${stagedNow.length} file(s) remain staged. No changes were lost.`,
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
throw error;
|
|
330
|
+
}
|
|
310
331
|
await git.stage.reset(ctx.cwd);
|
|
311
332
|
}
|
|
312
333
|
process.stdout.write("Split commits created.\n");
|
|
313
|
-
if (ctx.push)
|
|
314
|
-
await git.push(ctx.cwd);
|
|
315
|
-
process.stdout.write("Pushed to remote.\n");
|
|
316
|
-
}
|
|
334
|
+
if (ctx.push) await pushOrAbort(ctx.cwd);
|
|
317
335
|
}
|
|
318
336
|
|
|
319
337
|
function appendFilesToLastCommit(plan: SplitCommitPlan, files: string[]): void {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared commit-execution helpers for the agentic and legacy `omp commit`
|
|
3
|
+
* pipelines: readable failure reporting for refusing git hooks and a push
|
|
4
|
+
* wrapper that keeps a requested `--push` honest.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as git from "../utils/git";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A commit or push failure that has already been reported to the user with a
|
|
11
|
+
* readable message. It is thrown so the CLI exits non-zero without the runtime
|
|
12
|
+
* dumping a stack trace — in a bundled build that trace is several kilobytes of
|
|
13
|
+
* minified source, which buries the one line the user needs (issue #7834).
|
|
14
|
+
*
|
|
15
|
+
* `runCommitCommand`'s caller (`commands/commit.ts`) maps this to exit code 1.
|
|
16
|
+
*/
|
|
17
|
+
export class CommitAbortedError extends Error {
|
|
18
|
+
constructor() {
|
|
19
|
+
super("commit aborted");
|
|
20
|
+
this.name = "CommitAbortedError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Print a git-command failure — most often a `pre-commit`/`commit-msg` hook
|
|
26
|
+
* that exited non-zero — as an indented message under `context`, then abort.
|
|
27
|
+
*
|
|
28
|
+
* @param context Label for the failed step, e.g. `"Commit 1 of 2 failed"`.
|
|
29
|
+
* @param error The failure to surface; its captured stderr/stdout is shown.
|
|
30
|
+
* @param note Optional trailing status line (split-plan progress, recovery).
|
|
31
|
+
*/
|
|
32
|
+
export function abortOnGitFailure(context: string, error: git.GitCommandError, note?: string): never {
|
|
33
|
+
const detail = error.result.stderr.trim() || error.result.stdout.trim() || error.message;
|
|
34
|
+
const body = detail
|
|
35
|
+
.split("\n")
|
|
36
|
+
.map(line => ` ${line}`)
|
|
37
|
+
.join("\n");
|
|
38
|
+
process.stderr.write(`✗ ${context}:\n${body}\n`);
|
|
39
|
+
if (note) process.stderr.write(` ${note}\n`);
|
|
40
|
+
throw new CommitAbortedError();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Push the current branch, reporting a refused push (missing upstream, rejected
|
|
45
|
+
* ref) through {@link abortOnGitFailure} instead of letting the raw
|
|
46
|
+
* `GitCommandError` escape. Prints the success line on completion.
|
|
47
|
+
*/
|
|
48
|
+
export async function pushOrAbort(cwd: string): Promise<void> {
|
|
49
|
+
try {
|
|
50
|
+
await git.push(cwd);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (error instanceof git.GitCommandError) abortOnGitFailure("Push failed", error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
process.stdout.write("Pushed to remote.\n");
|
|
56
|
+
}
|
package/src/commit/index.ts
CHANGED
package/src/commit/pipeline.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
validateSummary,
|
|
17
17
|
} from "./analysis";
|
|
18
18
|
import { runChangelogFlow } from "./changelog";
|
|
19
|
+
import { abortOnGitFailure, pushOrAbort } from "./execute";
|
|
19
20
|
import { runMapReduceAnalysis, shouldUseMapReduce } from "./map-reduce";
|
|
20
21
|
import { formatCommitMessage } from "./message";
|
|
21
22
|
import { resolvePrimaryModel, resolveSmolModel } from "./model-selection";
|
|
@@ -30,10 +31,15 @@ const TYPES_DESCRIPTION = (): string => (typesDescription ??= prompt.render(type
|
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Execute the omp commit pipeline for staged changes.
|
|
34
|
+
*
|
|
35
|
+
* Returns whether the commit was generated by the mechanical fallback rather
|
|
36
|
+
* than by the commit agent, so callers can signal a degraded outcome (issue
|
|
37
|
+
* #7835). The legacy pipeline has no fallback: model failures throw.
|
|
33
38
|
*/
|
|
34
|
-
export async function runCommitCommand(args: CommitCommandArgs): Promise<
|
|
39
|
+
export async function runCommitCommand(args: CommitCommandArgs): Promise<{ usedFallback: boolean }> {
|
|
35
40
|
if (args.legacy) {
|
|
36
|
-
|
|
41
|
+
await runLegacyCommitCommand(args);
|
|
42
|
+
return { usedFallback: false };
|
|
37
43
|
}
|
|
38
44
|
return runAgenticCommit(args);
|
|
39
45
|
}
|
|
@@ -65,6 +71,11 @@ async function runLegacyCommitCommand(args: CommitCommandArgs): Promise<void> {
|
|
|
65
71
|
stagedFiles = await git.diff.changedFiles(cwd, { cached: true });
|
|
66
72
|
}
|
|
67
73
|
if (stagedFiles.length === 0) {
|
|
74
|
+
if (args.push) {
|
|
75
|
+
process.stdout.write("No changes to commit; pushing existing commits...\n");
|
|
76
|
+
await pushOrAbort(cwd);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
68
79
|
process.stderr.write("No changes to commit.\n");
|
|
69
80
|
return;
|
|
70
81
|
}
|
|
@@ -130,12 +141,14 @@ async function runLegacyCommitCommand(args: CommitCommandArgs): Promise<void> {
|
|
|
130
141
|
return;
|
|
131
142
|
}
|
|
132
143
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
144
|
+
try {
|
|
145
|
+
await git.commit(cwd, commitMessage);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
if (error instanceof git.GitCommandError) abortOnGitFailure("Commit failed", error);
|
|
148
|
+
throw error;
|
|
138
149
|
}
|
|
150
|
+
process.stdout.write("Commit created.\n");
|
|
151
|
+
if (args.push) await pushOrAbort(cwd);
|
|
139
152
|
}
|
|
140
153
|
|
|
141
154
|
async function generateAnalysis(input: {
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import type { Api, Model, ModelSpec, RemoteCompactionConfig } from "@oh-my-pi/pi-ai/types";
|
|
2
|
+
import { buildModel } from "@oh-my-pi/pi-catalog/build";
|
|
3
|
+
import {
|
|
4
|
+
getBundledModelReferenceIndex,
|
|
5
|
+
inheritReferenceThinking,
|
|
6
|
+
resolveModelReference,
|
|
7
|
+
} from "@oh-my-pi/pi-catalog/identity";
|
|
8
|
+
import { getVariantAliasSources, resolveVariantAlias } from "@oh-my-pi/pi-catalog/variant-collapse";
|
|
9
|
+
import { logger } from "@oh-my-pi/pi-utils";
|
|
10
|
+
import { createLiveConfigHeaders, type HeaderSource } from "./model-config-values";
|
|
11
|
+
import { type ModelPatch, mergeCompat, mergeRemoteCompactionConfig } from "./model-patch";
|
|
12
|
+
import { parseModelString } from "./model-resolver";
|
|
13
|
+
import type { ModelOverride, ProviderAuthMode } from "./models-config-schema";
|
|
14
|
+
export interface CustomModelDefinitionLike extends ModelPatch {
|
|
15
|
+
id: string;
|
|
16
|
+
api?: Api;
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
cost?: Model<Api>["cost"];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CustomModelBuildOptions {
|
|
22
|
+
useDefaults: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface CustomModelOverlay extends ModelPatch {
|
|
26
|
+
id: string;
|
|
27
|
+
provider: string;
|
|
28
|
+
api: Api;
|
|
29
|
+
baseUrl: string;
|
|
30
|
+
cost?: Model<Api>["cost"];
|
|
31
|
+
isOAuth?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function mergeCustomModelHeaders(
|
|
35
|
+
providerHeaders: Record<string, string> | undefined,
|
|
36
|
+
modelHeaders: Record<string, string> | undefined,
|
|
37
|
+
authHeader: boolean | undefined,
|
|
38
|
+
apiKeyConfig: string | undefined,
|
|
39
|
+
): Record<string, string> | undefined {
|
|
40
|
+
return createLiveConfigHeaders([providerHeaders, modelHeaders], { authHeader, apiKeyConfig });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function mergeAuthHeaderSources(
|
|
44
|
+
sources: readonly HeaderSource[],
|
|
45
|
+
authHeader: boolean | undefined,
|
|
46
|
+
apiKeyConfig: string | undefined,
|
|
47
|
+
): Record<string, string> | undefined {
|
|
48
|
+
return createLiveConfigHeaders(sources, { authHeader, apiKeyConfig });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Decide whether a custom-yaml model should force OAuth-style request shaping.
|
|
53
|
+
* - Explicit `auth: oauth` → force on.
|
|
54
|
+
* endpoints are typically Claude-Code-style proxies (e.g. CLIProxyAPI) that expect
|
|
55
|
+
* the cloaked request shape regardless of how the proxy itself is authenticated.
|
|
56
|
+
* - Otherwise → unset.
|
|
57
|
+
*/
|
|
58
|
+
function resolveCustomModelIsOAuth(api: Api, providerAuth: ProviderAuthMode | undefined): boolean | undefined {
|
|
59
|
+
if (providerAuth === "oauth") return true;
|
|
60
|
+
if (providerAuth !== undefined) return undefined;
|
|
61
|
+
if (api === "anthropic-messages") return true;
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function buildCustomModelOverlay(
|
|
66
|
+
providerName: string,
|
|
67
|
+
providerBaseUrl: string,
|
|
68
|
+
providerApi: Api | undefined,
|
|
69
|
+
providerHeaders: Record<string, string> | undefined,
|
|
70
|
+
providerApiKey: string | undefined,
|
|
71
|
+
authHeader: boolean | undefined,
|
|
72
|
+
providerCompat: ModelSpec<Api>["compat"] | undefined,
|
|
73
|
+
providerAuth: ProviderAuthMode | undefined,
|
|
74
|
+
providerRemoteCompaction: RemoteCompactionConfig<Api> | undefined,
|
|
75
|
+
modelDef: CustomModelDefinitionLike,
|
|
76
|
+
): CustomModelOverlay | undefined {
|
|
77
|
+
const api = modelDef.api ?? providerApi;
|
|
78
|
+
if (!api) return undefined;
|
|
79
|
+
return {
|
|
80
|
+
id: modelDef.id,
|
|
81
|
+
provider: providerName,
|
|
82
|
+
api,
|
|
83
|
+
baseUrl: modelDef.baseUrl ?? providerBaseUrl,
|
|
84
|
+
name: modelDef.name,
|
|
85
|
+
reasoning: modelDef.reasoning,
|
|
86
|
+
thinking: modelDef.thinking,
|
|
87
|
+
input: modelDef.input,
|
|
88
|
+
supportsTools: modelDef.supportsTools,
|
|
89
|
+
cost: modelDef.cost,
|
|
90
|
+
contextWindow: modelDef.contextWindow,
|
|
91
|
+
maxTokens: modelDef.maxTokens,
|
|
92
|
+
omitMaxOutputTokens: modelDef.omitMaxOutputTokens,
|
|
93
|
+
headers: mergeCustomModelHeaders(providerHeaders, modelDef.headers, authHeader, providerApiKey),
|
|
94
|
+
compat: mergeCompat(providerCompat, modelDef.compat),
|
|
95
|
+
contextPromotionTarget: modelDef.contextPromotionTarget,
|
|
96
|
+
compactionModel: modelDef.compactionModel,
|
|
97
|
+
remoteCompaction: mergeRemoteCompactionConfig(providerRemoteCompaction, modelDef.remoteCompaction),
|
|
98
|
+
premiumMultiplier: modelDef.premiumMultiplier,
|
|
99
|
+
isOAuth: resolveCustomModelIsOAuth(api, providerAuth),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function applyStandaloneCustomModelPolicies(model: CustomModelOverlay): CustomModelOverlay {
|
|
104
|
+
if (model.id !== "gpt-5.4" || model.provider === "github-copilot" || model.contextWindow !== undefined) {
|
|
105
|
+
return model;
|
|
106
|
+
}
|
|
107
|
+
return { ...model, contextWindow: 1_000_000 };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function finalizeCustomModel(model: CustomModelOverlay, options: CustomModelBuildOptions): Model<Api> {
|
|
111
|
+
const resolvedModel = options.useDefaults ? applyStandaloneCustomModelPolicies(model) : model;
|
|
112
|
+
const reference = options.useDefaults
|
|
113
|
+
? resolveModelReference(resolvedModel.id, getBundledModelReferenceIndex())
|
|
114
|
+
: undefined;
|
|
115
|
+
const cost =
|
|
116
|
+
resolvedModel.cost ??
|
|
117
|
+
reference?.cost ??
|
|
118
|
+
(options.useDefaults ? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } : undefined);
|
|
119
|
+
const input = resolvedModel.input ?? reference?.input ?? (options.useDefaults ? ["text"] : undefined);
|
|
120
|
+
const supportsTools = resolvedModel.supportsTools ?? reference?.supportsTools;
|
|
121
|
+
return buildModel({
|
|
122
|
+
id: resolvedModel.id,
|
|
123
|
+
name: resolvedModel.name ?? (options.useDefaults ? resolvedModel.id : undefined),
|
|
124
|
+
api: resolvedModel.api,
|
|
125
|
+
provider: resolvedModel.provider,
|
|
126
|
+
baseUrl: resolvedModel.baseUrl,
|
|
127
|
+
reasoning: resolvedModel.reasoning ?? reference?.reasoning ?? (options.useDefaults ? false : undefined),
|
|
128
|
+
thinking: inheritReferenceThinking(resolvedModel.thinking, reference, resolvedModel.provider),
|
|
129
|
+
input: input as ("text" | "image")[],
|
|
130
|
+
...(supportsTools !== undefined ? { supportsTools } : {}),
|
|
131
|
+
cost,
|
|
132
|
+
contextWindow: resolvedModel.contextWindow ?? reference?.contextWindow ?? (options.useDefaults ? 128000 : null),
|
|
133
|
+
maxTokens: resolvedModel.maxTokens ?? reference?.maxTokens ?? (options.useDefaults ? 16384 : null),
|
|
134
|
+
headers: resolvedModel.headers,
|
|
135
|
+
omitMaxOutputTokens: resolvedModel.omitMaxOutputTokens ?? reference?.omitMaxOutputTokens,
|
|
136
|
+
compat: mergeCompat(reference?.compatConfig, resolvedModel.compat),
|
|
137
|
+
contextPromotionTarget: resolvedModel.contextPromotionTarget,
|
|
138
|
+
compactionModel: resolvedModel.compactionModel,
|
|
139
|
+
remoteCompaction: resolvedModel.remoteCompaction,
|
|
140
|
+
premiumMultiplier: resolvedModel.premiumMultiplier,
|
|
141
|
+
isOAuth: resolvedModel.isOAuth,
|
|
142
|
+
} as ModelSpec<Api>);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function normalizeSuppressedSelector(
|
|
146
|
+
selector: string,
|
|
147
|
+
hasLiveModel?: (provider: string, id: string) => boolean,
|
|
148
|
+
): string {
|
|
149
|
+
const trimmed = selector.trim();
|
|
150
|
+
if (!trimmed) return trimmed;
|
|
151
|
+
const parsed = parseModelString(trimmed, {
|
|
152
|
+
allowMaxSuffix: true,
|
|
153
|
+
allowAutoAlias: true,
|
|
154
|
+
isLiteralModelId: (provider, id) => hasLiveModel?.(provider, id) === true,
|
|
155
|
+
});
|
|
156
|
+
if (!parsed) return trimmed;
|
|
157
|
+
// Retired effort-tier variant ids normalize to their collapsed logical id
|
|
158
|
+
// so persisted suppressions keyed by raw member ids still bind.
|
|
159
|
+
const aliasId = resolveVariantAlias(parsed.provider, parsed.id);
|
|
160
|
+
return `${parsed.provider}/${aliasId ?? parsed.id}`;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Look up a model's override, falling back to entries keyed by retired
|
|
165
|
+
* effort-tier variant ids (models.yml authored before collapsing). A raw key
|
|
166
|
+
* only re-binds when no live model holds that id.
|
|
167
|
+
*/
|
|
168
|
+
export function resolveModelOverrideWithAliases(
|
|
169
|
+
overrides: Map<string, ModelOverride>,
|
|
170
|
+
model: Model<Api>,
|
|
171
|
+
hasLiveModel: (provider: string, id: string) => boolean,
|
|
172
|
+
): ModelOverride | undefined {
|
|
173
|
+
const direct = overrides.get(model.id);
|
|
174
|
+
if (direct) return direct;
|
|
175
|
+
for (const rawId of getVariantAliasSources(model.provider, model.id)) {
|
|
176
|
+
if (hasLiveModel(model.provider, rawId)) continue;
|
|
177
|
+
const remapped = overrides.get(rawId);
|
|
178
|
+
if (remapped) {
|
|
179
|
+
logger.debug("model override re-keyed through variant alias", {
|
|
180
|
+
provider: model.provider,
|
|
181
|
+
from: rawId,
|
|
182
|
+
to: model.id,
|
|
183
|
+
});
|
|
184
|
+
return remapped;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { $envExact } from "@oh-my-pi/pi-utils";
|
|
3
|
+
|
|
4
|
+
const commandValueCache = new Map<string, string>();
|
|
5
|
+
// Failed `!command` resolutions (non-zero exit, empty stdout) are negative-cached
|
|
6
|
+
// with a TTL instead of forever: a transient failure (locked password manager,
|
|
7
|
+
// network hiccup) must not disable the key until process restart, but re-running
|
|
8
|
+
// the command on every resolution would restore the execSync storm this cache
|
|
9
|
+
// exists to prevent. One probe per TTL window bounds both.
|
|
10
|
+
const COMMAND_FAILURE_RETRY_MS = 30_000;
|
|
11
|
+
const commandFailureRetryAt = new Map<string, number>();
|
|
12
|
+
|
|
13
|
+
export function isCommandConfigValue(valueConfig: string | undefined): valueConfig is string {
|
|
14
|
+
return valueConfig?.startsWith("!") === true;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resolveCommandConfig(command: string): string | undefined {
|
|
18
|
+
const cached = commandValueCache.get(command);
|
|
19
|
+
if (cached !== undefined) return cached;
|
|
20
|
+
const retryAt = commandFailureRetryAt.get(command);
|
|
21
|
+
if (retryAt !== undefined && Date.now() < retryAt) return undefined;
|
|
22
|
+
try {
|
|
23
|
+
const stdout = execSync(command, { encoding: "utf8", timeout: 10_000, windowsHide: true });
|
|
24
|
+
const trimmed = stdout.trim();
|
|
25
|
+
if (trimmed.length === 0) {
|
|
26
|
+
commandFailureRetryAt.set(command, Date.now() + COMMAND_FAILURE_RETRY_MS);
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
commandFailureRetryAt.delete(command);
|
|
30
|
+
commandValueCache.set(command, trimmed);
|
|
31
|
+
return trimmed;
|
|
32
|
+
} catch {
|
|
33
|
+
commandFailureRetryAt.set(command, Date.now() + COMMAND_FAILURE_RETRY_MS);
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CommandApiKeyResolution {
|
|
39
|
+
configured: boolean;
|
|
40
|
+
value?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a models.yml/models.yaml secret/config value to an actual value.
|
|
44
|
+
* `!cmd` runs a shell command and returns trimmed stdout, otherwise env vars are
|
|
45
|
+
* checked first and the input falls back to a literal value.
|
|
46
|
+
*/
|
|
47
|
+
export function resolveConfigValue(valueConfig: string): string | undefined {
|
|
48
|
+
if (valueConfig.startsWith("!")) return resolveCommandConfig(valueConfig.slice(1).trim());
|
|
49
|
+
const envValue = $envExact(valueConfig);
|
|
50
|
+
if (envValue) return envValue;
|
|
51
|
+
return valueConfig;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type HeaderSource = Record<string, string> | undefined;
|
|
55
|
+
|
|
56
|
+
interface HeaderResolutionOptions {
|
|
57
|
+
authHeader?: boolean;
|
|
58
|
+
apiKeyConfig?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function materializeConfigHeaderSources(
|
|
62
|
+
sources: readonly HeaderSource[],
|
|
63
|
+
options?: HeaderResolutionOptions,
|
|
64
|
+
): Record<string, string> | undefined {
|
|
65
|
+
const resolved: Record<string, string> = {};
|
|
66
|
+
for (const source of sources) {
|
|
67
|
+
if (!source) continue;
|
|
68
|
+
for (const [key, value] of Object.entries(source)) {
|
|
69
|
+
const next = resolveConfigValue(value);
|
|
70
|
+
if (next) resolved[key] = next;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (options?.authHeader && options.apiKeyConfig) {
|
|
74
|
+
const resolvedKey = resolveConfigValue(options.apiKeyConfig);
|
|
75
|
+
if (resolvedKey) resolved.Authorization = `Bearer ${resolvedKey}`;
|
|
76
|
+
}
|
|
77
|
+
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function createLiveConfigHeaders(
|
|
81
|
+
sources: readonly HeaderSource[],
|
|
82
|
+
options?: HeaderResolutionOptions,
|
|
83
|
+
): Record<string, string> | undefined {
|
|
84
|
+
const liveSources = sources.filter((source): source is Record<string, string> => source !== undefined);
|
|
85
|
+
if (liveSources.length === 0 && (!options?.authHeader || !options.apiKeyConfig)) return undefined;
|
|
86
|
+
|
|
87
|
+
const localHeaders: Record<string, string> = {};
|
|
88
|
+
const allSources = [...liveSources, localHeaders];
|
|
89
|
+
const current = () => materializeConfigHeaderSources(allSources, options) ?? {};
|
|
90
|
+
return new Proxy(localHeaders, {
|
|
91
|
+
get(target, property, receiver) {
|
|
92
|
+
if (typeof property !== "string") return Reflect.get(target, property, receiver);
|
|
93
|
+
return current()[property];
|
|
94
|
+
},
|
|
95
|
+
set(target, property, value) {
|
|
96
|
+
if (typeof property !== "string" || typeof value !== "string") return false;
|
|
97
|
+
target[property] = value;
|
|
98
|
+
return true;
|
|
99
|
+
},
|
|
100
|
+
deleteProperty(target, property) {
|
|
101
|
+
if (typeof property !== "string") return false;
|
|
102
|
+
delete target[property];
|
|
103
|
+
return true;
|
|
104
|
+
},
|
|
105
|
+
has(_target, property) {
|
|
106
|
+
if (typeof property !== "string") return false;
|
|
107
|
+
return Object.hasOwn(current(), property);
|
|
108
|
+
},
|
|
109
|
+
ownKeys() {
|
|
110
|
+
return Reflect.ownKeys(current());
|
|
111
|
+
},
|
|
112
|
+
getOwnPropertyDescriptor(_target, property) {
|
|
113
|
+
if (typeof property !== "string") return undefined;
|
|
114
|
+
const headers = current();
|
|
115
|
+
if (!Object.hasOwn(headers, property)) return undefined;
|
|
116
|
+
return {
|
|
117
|
+
configurable: true,
|
|
118
|
+
enumerable: true,
|
|
119
|
+
value: headers[property],
|
|
120
|
+
writable: true,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function resolveConfigHeaders(headers: Record<string, string> | undefined): Record<string, string> | undefined {
|
|
127
|
+
return materializeConfigHeaderSources([headers]);
|
|
128
|
+
}
|
|
@@ -974,8 +974,8 @@ export async function discoverProxyModels(
|
|
|
974
974
|
const reference = resolveModelReference(id, getBundledModelReferenceIndex());
|
|
975
975
|
const discoveryName = typeof item.name === "string" ? item.name.trim() : "";
|
|
976
976
|
const displayName =
|
|
977
|
-
reference?.name ??
|
|
978
977
|
(discoveryName && discoveryName !== id ? discoveryName : undefined) ??
|
|
978
|
+
reference?.name ??
|
|
979
979
|
stripBracketedModelIdAffixes(id) ??
|
|
980
980
|
id;
|
|
981
981
|
discovered.push(
|