pullfrog 0.1.75 → 0.1.76
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/dist/agents/opencodeShared.d.ts +20 -0
- package/dist/cli.mjs +73 -28
- package/dist/external.d.ts +1 -1
- package/dist/index.js +57 -26
- package/dist/internal/index.d.ts +1 -1
- package/dist/internal.js +61 -44
- package/dist/models.d.ts +21 -0
- package/package.json +1 -1
|
@@ -42,6 +42,26 @@ interface AzureProviderEntry {
|
|
|
42
42
|
* guaranteed present by `validateOpenAICompatibleSetup`.
|
|
43
43
|
*/
|
|
44
44
|
export declare function openAICompatibleProvider(model: string | undefined): Record<string, OpenAICompatibleProviderEntry>;
|
|
45
|
+
/**
|
|
46
|
+
* Customer-gateway block for OPENCODE_CONFIG_CONTENT. opencode resolves a
|
|
47
|
+
* provider's endpoint as `options.baseURL ?? model.api.url` (`getSDK`), and
|
|
48
|
+
* models.dev declares no base-URL env var for any provider we catalog — so a
|
|
49
|
+
* config override is the ONLY lever that re-points one. Unlike
|
|
50
|
+
* `openAICompatibleProvider` this declares no `npm` and no models: the native
|
|
51
|
+
* provider and its catalog metadata (including token limits) stay exactly as
|
|
52
|
+
* they are, and only the host changes. `{}` when unset so the caller can spread
|
|
53
|
+
* it unconditionally.
|
|
54
|
+
*
|
|
55
|
+
* `anthropic/*` normally never reaches here — `resolveAgent` routes it to
|
|
56
|
+
* claude-code, which reads ANTHROPIC_BASE_URL natively — but keying off the
|
|
57
|
+
* resolved specifier rather than the harness means it still holds on the paths
|
|
58
|
+
* that do send a Claude model through opencode (`PULLFROG_AGENT=opencode`).
|
|
59
|
+
*/
|
|
60
|
+
export declare function providerGatewayOverride(model: string | undefined): Record<string, {
|
|
61
|
+
options: {
|
|
62
|
+
baseURL: string;
|
|
63
|
+
};
|
|
64
|
+
}>;
|
|
45
65
|
/**
|
|
46
66
|
* Azure model block for OPENCODE_CONFIG_CONTENT. Unlike openai-compatible this
|
|
47
67
|
* does NOT declare a provider — opencode has a native `azure` one and the env
|
package/dist/cli.mjs
CHANGED
|
@@ -123000,7 +123000,7 @@ var import_picocolors = __toESM(require_picocolors(), 1);
|
|
|
123000
123000
|
// package.json
|
|
123001
123001
|
var package_default = {
|
|
123002
123002
|
name: "pullfrog",
|
|
123003
|
-
version: "0.1.
|
|
123003
|
+
version: "0.1.76",
|
|
123004
123004
|
cliContractVersion: "1",
|
|
123005
123005
|
type: "module",
|
|
123006
123006
|
bin: {
|
|
@@ -124108,6 +124108,20 @@ var repoConfigFields = [
|
|
|
124108
124108
|
nullable: true,
|
|
124109
124109
|
description: "additional instructions for planning"
|
|
124110
124110
|
},
|
|
124111
|
+
{
|
|
124112
|
+
key: "prompts.address-reviews",
|
|
124113
|
+
field: "AddressReviews",
|
|
124114
|
+
kind: "prompt",
|
|
124115
|
+
nullable: true,
|
|
124116
|
+
description: "additional instructions for addressing review feedback"
|
|
124117
|
+
},
|
|
124118
|
+
{
|
|
124119
|
+
key: "prompts.fix-ci",
|
|
124120
|
+
field: "Fix",
|
|
124121
|
+
kind: "prompt",
|
|
124122
|
+
nullable: true,
|
|
124123
|
+
description: "additional instructions for fixing CI failures"
|
|
124124
|
+
},
|
|
124111
124125
|
{ key: "mention.enabled", field: "mention", kind: "toggle", description: "respond to mentions" },
|
|
124112
124126
|
{
|
|
124113
124127
|
key: "mention.instructions",
|
|
@@ -126138,6 +126152,17 @@ var OPENAI_COMPATIBLE_API_KEY_ENV = "OPENAI_COMPATIBLE_API_KEY";
|
|
|
126138
126152
|
var OPENAI_COMPATIBLE_MODEL_ENV = "OPENAI_COMPATIBLE_MODEL";
|
|
126139
126153
|
var OPENAI_COMPATIBLE_CONTEXT_ENV = "OPENAI_COMPATIBLE_CONTEXT";
|
|
126140
126154
|
var OPENAI_COMPATIBLE_MAX_OUTPUT_ENV = "OPENAI_COMPATIBLE_MAX_OUTPUT";
|
|
126155
|
+
var PROVIDER_GATEWAY_URL_ENV = {
|
|
126156
|
+
anthropic: "ANTHROPIC_BASE_URL",
|
|
126157
|
+
openai: "OPENAI_BASE_URL"
|
|
126158
|
+
};
|
|
126159
|
+
function getProviderGatewayUrl(specifier) {
|
|
126160
|
+
const slashIndex = specifier?.indexOf("/") ?? -1;
|
|
126161
|
+
if (!specifier || slashIndex <= 0) return void 0;
|
|
126162
|
+
const envVar = PROVIDER_GATEWAY_URL_ENV[specifier.slice(0, slashIndex)];
|
|
126163
|
+
if (!envVar) return void 0;
|
|
126164
|
+
return process.env[envVar]?.trim().replace(/\/$/, "") || void 0;
|
|
126165
|
+
}
|
|
126141
126166
|
function isBedrockAnthropicId(bedrockModelId) {
|
|
126142
126167
|
return bedrockModelId.toLowerCase().split(/[./:]/).includes("anthropic");
|
|
126143
126168
|
}
|
|
@@ -127644,26 +127669,24 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
127644
127669
|
|
|
127645
127670
|
2. Checkout the PR branch via \`${t2("checkout_pr")}\`.
|
|
127646
127671
|
|
|
127647
|
-
3. Fetch review comments via \`${t2("get_review_comments")}
|
|
127672
|
+
3. Fetch review comments via \`${t2("get_review_comments")}\` and read the full conversation in each relevant thread.
|
|
127648
127673
|
|
|
127649
|
-
4. For each
|
|
127650
|
-
-
|
|
127674
|
+
4. For each thread:
|
|
127675
|
+
- **check intent first**: questions, explanations, and disagreement call for a reply, not a code change. Change code only when explicitly requested. Automatic review feedback on Pullfrog-authored PRs (\`address_scope: all\`) remains actionable without a separate request; later replies can narrow or withdraw that permission.
|
|
127676
|
+
- under \`address_scope: mentions\`, unmentioned threads are context only unless the user's review-body request explicitly includes them
|
|
127651
127677
|
- **verify the finding yourself** against the actual code before deciding whether to apply \u2014 every comment (human or agent) is a hypothesis, not a directive. agent reviewers especially are fallible.
|
|
127652
|
-
-
|
|
127653
|
-
- if the
|
|
127678
|
+
- keep requested changes **sound, minimal, and elegant**. Reject defensive checks for impossible cases, single-use abstractions, redundant comments, and tautological tests rather than mechanically applying reviewer suggestions.
|
|
127679
|
+
- if intent permits a code change and the finding stands, implement it using your native tools; otherwise reply without editing
|
|
127654
127680
|
- record what was done (or why nothing was done)
|
|
127655
127681
|
|
|
127656
127682
|
5. Quality check:
|
|
127657
|
-
- re-call \`${t2("get_review_comments")}\` with \`fresh: true\` before
|
|
127658
|
-
-
|
|
127659
|
-
- ${commitStep}
|
|
127683
|
+
- re-call \`${t2("get_review_comments")}\` with \`fresh: true\` before finishing, even when only replying. Apply the same scope and intent checks to new comments; respect requests to stop or change direction before committing.
|
|
127684
|
+
- if code changed, test and review the diff, remove unintended changes or bloat, then ${commitStep}
|
|
127660
127685
|
|
|
127661
|
-
6. Finalize
|
|
127662
|
-
- ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*)
|
|
127663
|
-
-
|
|
127664
|
-
-
|
|
127665
|
-
- reply ONCE via \`${t2("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t2("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
127666
|
-
- **immediately** call \`${t2("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
127686
|
+
6. Finalize:
|
|
127687
|
+
- **only if code changed**, ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*). If push/commit fails, report the exact error and STOP without claiming a fix or resolving its threads.
|
|
127688
|
+
- reply ONCE per relevant thread via \`${t2("reply_to_review_comment")}\`, including when no code changed. The \`comment_id\` is the root comment's numeric \`id=\`, NOT the \`thread=\` value from \`${t2("get_review_comments")}\`. The runtime dedupes identical bodies within a session.
|
|
127689
|
+
- resolve a thread via \`${t2("resolve_review_thread")}\` (using \`thread=\` as \`thread_id\`) only after its requested fix is fully on the remote, or the user explicitly asks to resolve it. Leave discussion-only replies, partial fixes, and disagreements open.
|
|
127667
127690
|
- call \`${t2("report_progress")}\` with a brief summary. If your last \`${t2("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
127668
127691
|
},
|
|
127669
127692
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
@@ -129640,6 +129663,19 @@ function warnIfNativeEditsUnavailable(ctx) {
|
|
|
129640
129663
|
"\xBB this run cannot change files: codex's native write tool depends on bubblewrap, which Ubuntu 24.04 blocks (https://github.com/openai/codex/issues/29908), and the MCP shell is disabled for this repo. read-only work is unaffected \u2014 set `shell: restricted` if the agent needs to edit anything."
|
|
129641
129664
|
);
|
|
129642
129665
|
}
|
|
129666
|
+
var CODEX_GATEWAY_PROVIDER = "pullfrog-gateway";
|
|
129667
|
+
function gatewayProvider(gatewayUrl) {
|
|
129668
|
+
if (!gatewayUrl) return [];
|
|
129669
|
+
return [
|
|
129670
|
+
`[model_providers.${CODEX_GATEWAY_PROVIDER}]`,
|
|
129671
|
+
'name = "OpenAI gateway"',
|
|
129672
|
+
`base_url = ${JSON.stringify(gatewayUrl)}`,
|
|
129673
|
+
'wire_api = "responses"',
|
|
129674
|
+
// where the harness puts the run's OPENAI_API_KEY
|
|
129675
|
+
'env_key = "CODEX_API_KEY"',
|
|
129676
|
+
""
|
|
129677
|
+
];
|
|
129678
|
+
}
|
|
129643
129679
|
function writeCodexConfig(params) {
|
|
129644
129680
|
const shellEnabled = params.ctx.payload.shell === "enabled";
|
|
129645
129681
|
const sandboxMode = params.ctx.payload.push === "disabled" ? "read-only" : "workspace-write";
|
|
@@ -129656,6 +129692,7 @@ function writeCodexConfig(params) {
|
|
|
129656
129692
|
'web_search = "live"',
|
|
129657
129693
|
...params.model ? [`model = ${JSON.stringify(params.model)}`] : [],
|
|
129658
129694
|
...params.effortRung ? [`model_reasoning_effort = ${JSON.stringify(params.effortRung)}`] : [],
|
|
129695
|
+
...params.gatewayUrl ? [`model_provider = ${JSON.stringify(CODEX_GATEWAY_PROVIDER)}`] : [],
|
|
129659
129696
|
"",
|
|
129660
129697
|
"[features]",
|
|
129661
129698
|
tomlBool(CODEX_DISABLED_FEATURES, false),
|
|
@@ -129685,6 +129722,7 @@ function writeCodexConfig(params) {
|
|
|
129685
129722
|
"tool_timeout_sec = 660",
|
|
129686
129723
|
"",
|
|
129687
129724
|
...repoMcpApprovals(repoDir),
|
|
129725
|
+
...gatewayProvider(params.gatewayUrl),
|
|
129688
129726
|
// UNTRUSTED, deliberately, and this one line is the whole config-precedence
|
|
129689
129727
|
// boundary. Codex loads `<repo>/.codex/config.toml` as a layer that
|
|
129690
129728
|
// OUTRANKS ours (project 25 vs user 20), and its denylist strips none of
|
|
@@ -129953,7 +129991,11 @@ var codex = agent({
|
|
|
129953
129991
|
ctx,
|
|
129954
129992
|
codexHome,
|
|
129955
129993
|
model: resolveCodexModel(ctx),
|
|
129956
|
-
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0
|
|
129994
|
+
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0,
|
|
129995
|
+
// keyed off OpenAI, not the resolved model: codex serves nothing else, an
|
|
129996
|
+
// auto-selected run has no model, and a ChatGPT-subscription token is
|
|
129997
|
+
// valid only at ChatGPT's own backend
|
|
129998
|
+
gatewayUrl: codexHomeAuth ? void 0 : getProviderGatewayUrl("openai/")
|
|
129957
129999
|
});
|
|
129958
130000
|
if (codexHomeAuth) {
|
|
129959
130001
|
core3.saveState(
|
|
@@ -135720,6 +135762,14 @@ function openAICompatibleProvider(model) {
|
|
|
135720
135762
|
}
|
|
135721
135763
|
};
|
|
135722
135764
|
}
|
|
135765
|
+
var OPENCODE_GATEWAY_PATH = { anthropic: "/v1" };
|
|
135766
|
+
function providerGatewayOverride(model) {
|
|
135767
|
+
const gatewayUrl = getProviderGatewayUrl(model);
|
|
135768
|
+
if (!model || !gatewayUrl) return {};
|
|
135769
|
+
const provider2 = model.slice(0, model.indexOf("/"));
|
|
135770
|
+
const baseURL = `${gatewayUrl}${OPENCODE_GATEWAY_PATH[provider2] ?? ""}`;
|
|
135771
|
+
return { [provider2]: { options: { baseURL } } };
|
|
135772
|
+
}
|
|
135723
135773
|
function azureProvider(model) {
|
|
135724
135774
|
const prefix = `${AZURE_PROVIDER}/`;
|
|
135725
135775
|
if (!model?.startsWith(prefix)) return {};
|
|
@@ -135835,7 +135885,8 @@ function buildSecurityConfig(ctx, model) {
|
|
|
135835
135885
|
provider: {
|
|
135836
135886
|
openrouter: { models: kimiOpenRouterProviderOverrides() },
|
|
135837
135887
|
...openAICompatibleProvider(model),
|
|
135838
|
-
...azureProvider(model)
|
|
135888
|
+
...azureProvider(model),
|
|
135889
|
+
...providerGatewayOverride(model)
|
|
135839
135890
|
}
|
|
135840
135891
|
};
|
|
135841
135892
|
if (model) {
|
|
@@ -214306,7 +214357,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
214306
214357
|
threadCount: threadBlocks.length,
|
|
214307
214358
|
commentsPath,
|
|
214308
214359
|
toc: formatted.toc,
|
|
214309
|
-
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR
|
|
214360
|
+
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR, including comments that landed after this run started. Being returned does not authorize a code change; follow the task's scope and each thread's latest request. the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). read each full thread before deciding whether it calls for a reply or a code change.`
|
|
214310
214361
|
};
|
|
214311
214362
|
})
|
|
214312
214363
|
});
|
|
@@ -214429,8 +214480,7 @@ An existing plan comment was found for this issue. Update that comment with the
|
|
|
214429
214480
|
};
|
|
214430
214481
|
}
|
|
214431
214482
|
var modeInstructionParent = {
|
|
214432
|
-
IncrementalReview: "Review"
|
|
214433
|
-
Fix: "Build"
|
|
214483
|
+
IncrementalReview: "Review"
|
|
214434
214484
|
};
|
|
214435
214485
|
function buildOrchestratorGuidance(ctx, mode, overrideGuidance) {
|
|
214436
214486
|
const hardcoded = overrideGuidance ?? mode.prompt ?? "";
|
|
@@ -215642,18 +215692,13 @@ function hasEnvVar4(name) {
|
|
|
215642
215692
|
const value2 = process.env[name];
|
|
215643
215693
|
return typeof value2 === "string" && value2.length > 0;
|
|
215644
215694
|
}
|
|
215645
|
-
var HOST_OVERRIDES = {
|
|
215646
|
-
ANTHROPIC_API_KEY: "ANTHROPIC_BASE_URL",
|
|
215647
|
-
CLAUDE_CODE_OAUTH_TOKEN: "ANTHROPIC_BASE_URL"
|
|
215648
|
-
};
|
|
215649
215695
|
function envVarsFor(model) {
|
|
215650
215696
|
return model.includes("/") ? getModelEnvVars(model) : [];
|
|
215651
215697
|
}
|
|
215652
215698
|
async function checkOne(params) {
|
|
215653
215699
|
const value2 = process.env[params.envVar];
|
|
215654
215700
|
if (!value2) return null;
|
|
215655
|
-
|
|
215656
|
-
if (hostOverride && hasEnvVar4(hostOverride)) return null;
|
|
215701
|
+
if (getProviderGatewayUrl(params.model)) return null;
|
|
215657
215702
|
if (params.envVar === "CLAUDE_CODE_OAUTH_TOKEN") {
|
|
215658
215703
|
const preflight = await preflightClaudeSubscription({
|
|
215659
215704
|
token: value2,
|
|
@@ -219730,7 +219775,7 @@ function resolveTarget2(repo) {
|
|
|
219730
219775
|
return { owner: match3[1], repo: match3[2] };
|
|
219731
219776
|
}
|
|
219732
219777
|
function cliVersion() {
|
|
219733
|
-
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.
|
|
219778
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.76");
|
|
219734
219779
|
if (!parts) return "0.0.0";
|
|
219735
219780
|
return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
|
|
219736
219781
|
}
|
|
@@ -219897,7 +219942,7 @@ async function runCli8(input2) {
|
|
|
219897
219942
|
}
|
|
219898
219943
|
|
|
219899
219944
|
// cli.ts
|
|
219900
|
-
var VERSION10 = "0.1.
|
|
219945
|
+
var VERSION10 = "0.1.76";
|
|
219901
219946
|
var bin = basename2(process.argv[1] || "");
|
|
219902
219947
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
219903
219948
|
var rawArgs = process.argv.slice(2);
|
package/dist/external.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ export declare function findDanglingPromptToolRefs(params: {
|
|
|
52
52
|
export type { EffortPosition } from "./effort.ts";
|
|
53
53
|
export { DEFAULT_EFFORT_POSITION, EFFORT_ALIASES, isEffortPosition, offeredRungs, parseEffortPosition, resolveRung, rungLabel, rungPosition, SUBSIDY_RUNG, } from "./effort.ts";
|
|
54
54
|
export type { AutoTier, ModelAlias, ModelProvider, ProviderConfig } from "./models.ts";
|
|
55
|
-
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_PROXY_MODEL, defaultAutoTier, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, ossFundedModelNames, parseModel, providers, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, } from "./models.ts";
|
|
55
|
+
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_PROXY_MODEL, defaultAutoTier, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, ossFundedModelNames, PROVIDER_GATEWAY_URL_ENV, parseModel, providers, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, } from "./models.ts";
|
|
56
56
|
export type ToolPermission = "disabled" | "enabled";
|
|
57
57
|
export type ShellPermission = "disabled" | "restricted" | "enabled";
|
|
58
58
|
export type PushPermission = "disabled" | "restricted" | "enabled";
|
package/dist/index.js
CHANGED
|
@@ -108971,6 +108971,17 @@ var OPENAI_COMPATIBLE_API_KEY_ENV = "OPENAI_COMPATIBLE_API_KEY";
|
|
|
108971
108971
|
var OPENAI_COMPATIBLE_MODEL_ENV = "OPENAI_COMPATIBLE_MODEL";
|
|
108972
108972
|
var OPENAI_COMPATIBLE_CONTEXT_ENV = "OPENAI_COMPATIBLE_CONTEXT";
|
|
108973
108973
|
var OPENAI_COMPATIBLE_MAX_OUTPUT_ENV = "OPENAI_COMPATIBLE_MAX_OUTPUT";
|
|
108974
|
+
var PROVIDER_GATEWAY_URL_ENV = {
|
|
108975
|
+
anthropic: "ANTHROPIC_BASE_URL",
|
|
108976
|
+
openai: "OPENAI_BASE_URL"
|
|
108977
|
+
};
|
|
108978
|
+
function getProviderGatewayUrl(specifier) {
|
|
108979
|
+
const slashIndex = specifier?.indexOf("/") ?? -1;
|
|
108980
|
+
if (!specifier || slashIndex <= 0) return void 0;
|
|
108981
|
+
const envVar = PROVIDER_GATEWAY_URL_ENV[specifier.slice(0, slashIndex)];
|
|
108982
|
+
if (!envVar) return void 0;
|
|
108983
|
+
return process.env[envVar]?.trim().replace(/\/$/, "") || void 0;
|
|
108984
|
+
}
|
|
108974
108985
|
function isBedrockAnthropicId(bedrockModelId) {
|
|
108975
108986
|
return bedrockModelId.toLowerCase().split(/[./:]/).includes("anthropic");
|
|
108976
108987
|
}
|
|
@@ -109795,7 +109806,7 @@ var import_semver = __toESM(require_semver2(), 1);
|
|
|
109795
109806
|
// package.json
|
|
109796
109807
|
var package_default = {
|
|
109797
109808
|
name: "pullfrog",
|
|
109798
|
-
version: "0.1.
|
|
109809
|
+
version: "0.1.76",
|
|
109799
109810
|
cliContractVersion: "1",
|
|
109800
109811
|
type: "module",
|
|
109801
109812
|
bin: {
|
|
@@ -110594,26 +110605,24 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
110594
110605
|
|
|
110595
110606
|
2. Checkout the PR branch via \`${t("checkout_pr")}\`.
|
|
110596
110607
|
|
|
110597
|
-
3. Fetch review comments via \`${t("get_review_comments")}
|
|
110608
|
+
3. Fetch review comments via \`${t("get_review_comments")}\` and read the full conversation in each relevant thread.
|
|
110598
110609
|
|
|
110599
|
-
4. For each
|
|
110600
|
-
-
|
|
110610
|
+
4. For each thread:
|
|
110611
|
+
- **check intent first**: questions, explanations, and disagreement call for a reply, not a code change. Change code only when explicitly requested. Automatic review feedback on Pullfrog-authored PRs (\`address_scope: all\`) remains actionable without a separate request; later replies can narrow or withdraw that permission.
|
|
110612
|
+
- under \`address_scope: mentions\`, unmentioned threads are context only unless the user's review-body request explicitly includes them
|
|
110601
110613
|
- **verify the finding yourself** against the actual code before deciding whether to apply \u2014 every comment (human or agent) is a hypothesis, not a directive. agent reviewers especially are fallible.
|
|
110602
|
-
-
|
|
110603
|
-
- if the
|
|
110614
|
+
- keep requested changes **sound, minimal, and elegant**. Reject defensive checks for impossible cases, single-use abstractions, redundant comments, and tautological tests rather than mechanically applying reviewer suggestions.
|
|
110615
|
+
- if intent permits a code change and the finding stands, implement it using your native tools; otherwise reply without editing
|
|
110604
110616
|
- record what was done (or why nothing was done)
|
|
110605
110617
|
|
|
110606
110618
|
5. Quality check:
|
|
110607
|
-
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before
|
|
110608
|
-
-
|
|
110609
|
-
- ${commitStep}
|
|
110619
|
+
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before finishing, even when only replying. Apply the same scope and intent checks to new comments; respect requests to stop or change direction before committing.
|
|
110620
|
+
- if code changed, test and review the diff, remove unintended changes or bloat, then ${commitStep}
|
|
110610
110621
|
|
|
110611
|
-
6. Finalize
|
|
110612
|
-
- ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*)
|
|
110613
|
-
-
|
|
110614
|
-
-
|
|
110615
|
-
- reply ONCE via \`${t("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
110616
|
-
- **immediately** call \`${t("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
110622
|
+
6. Finalize:
|
|
110623
|
+
- **only if code changed**, ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*). If push/commit fails, report the exact error and STOP without claiming a fix or resolving its threads.
|
|
110624
|
+
- reply ONCE per relevant thread via \`${t("reply_to_review_comment")}\`, including when no code changed. The \`comment_id\` is the root comment's numeric \`id=\`, NOT the \`thread=\` value from \`${t("get_review_comments")}\`. The runtime dedupes identical bodies within a session.
|
|
110625
|
+
- resolve a thread via \`${t("resolve_review_thread")}\` (using \`thread=\` as \`thread_id\`) only after its requested fix is fully on the remote, or the user explicitly asks to resolve it. Leave discussion-only replies, partial fixes, and disagreements open.
|
|
110617
110626
|
- call \`${t("report_progress")}\` with a brief summary. If your last \`${t("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
110618
110627
|
},
|
|
110619
110628
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
@@ -112514,6 +112523,19 @@ function warnIfNativeEditsUnavailable(ctx) {
|
|
|
112514
112523
|
"\xBB this run cannot change files: codex's native write tool depends on bubblewrap, which Ubuntu 24.04 blocks (https://github.com/openai/codex/issues/29908), and the MCP shell is disabled for this repo. read-only work is unaffected \u2014 set `shell: restricted` if the agent needs to edit anything."
|
|
112515
112524
|
);
|
|
112516
112525
|
}
|
|
112526
|
+
var CODEX_GATEWAY_PROVIDER = "pullfrog-gateway";
|
|
112527
|
+
function gatewayProvider(gatewayUrl) {
|
|
112528
|
+
if (!gatewayUrl) return [];
|
|
112529
|
+
return [
|
|
112530
|
+
`[model_providers.${CODEX_GATEWAY_PROVIDER}]`,
|
|
112531
|
+
'name = "OpenAI gateway"',
|
|
112532
|
+
`base_url = ${JSON.stringify(gatewayUrl)}`,
|
|
112533
|
+
'wire_api = "responses"',
|
|
112534
|
+
// where the harness puts the run's OPENAI_API_KEY
|
|
112535
|
+
'env_key = "CODEX_API_KEY"',
|
|
112536
|
+
""
|
|
112537
|
+
];
|
|
112538
|
+
}
|
|
112517
112539
|
function writeCodexConfig(params) {
|
|
112518
112540
|
const shellEnabled = params.ctx.payload.shell === "enabled";
|
|
112519
112541
|
const sandboxMode = params.ctx.payload.push === "disabled" ? "read-only" : "workspace-write";
|
|
@@ -112530,6 +112552,7 @@ function writeCodexConfig(params) {
|
|
|
112530
112552
|
'web_search = "live"',
|
|
112531
112553
|
...params.model ? [`model = ${JSON.stringify(params.model)}`] : [],
|
|
112532
112554
|
...params.effortRung ? [`model_reasoning_effort = ${JSON.stringify(params.effortRung)}`] : [],
|
|
112555
|
+
...params.gatewayUrl ? [`model_provider = ${JSON.stringify(CODEX_GATEWAY_PROVIDER)}`] : [],
|
|
112533
112556
|
"",
|
|
112534
112557
|
"[features]",
|
|
112535
112558
|
tomlBool(CODEX_DISABLED_FEATURES, false),
|
|
@@ -112559,6 +112582,7 @@ function writeCodexConfig(params) {
|
|
|
112559
112582
|
"tool_timeout_sec = 660",
|
|
112560
112583
|
"",
|
|
112561
112584
|
...repoMcpApprovals(repoDir),
|
|
112585
|
+
...gatewayProvider(params.gatewayUrl),
|
|
112562
112586
|
// UNTRUSTED, deliberately, and this one line is the whole config-precedence
|
|
112563
112587
|
// boundary. Codex loads `<repo>/.codex/config.toml` as a layer that
|
|
112564
112588
|
// OUTRANKS ours (project 25 vs user 20), and its denylist strips none of
|
|
@@ -112827,7 +112851,11 @@ var codex = agent({
|
|
|
112827
112851
|
ctx,
|
|
112828
112852
|
codexHome,
|
|
112829
112853
|
model: resolveCodexModel(ctx),
|
|
112830
|
-
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0
|
|
112854
|
+
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0,
|
|
112855
|
+
// keyed off OpenAI, not the resolved model: codex serves nothing else, an
|
|
112856
|
+
// auto-selected run has no model, and a ChatGPT-subscription token is
|
|
112857
|
+
// valid only at ChatGPT's own backend
|
|
112858
|
+
gatewayUrl: codexHomeAuth ? void 0 : getProviderGatewayUrl("openai/")
|
|
112831
112859
|
});
|
|
112832
112860
|
if (codexHomeAuth) {
|
|
112833
112861
|
core3.saveState(
|
|
@@ -118594,6 +118622,14 @@ function openAICompatibleProvider(model) {
|
|
|
118594
118622
|
}
|
|
118595
118623
|
};
|
|
118596
118624
|
}
|
|
118625
|
+
var OPENCODE_GATEWAY_PATH = { anthropic: "/v1" };
|
|
118626
|
+
function providerGatewayOverride(model) {
|
|
118627
|
+
const gatewayUrl = getProviderGatewayUrl(model);
|
|
118628
|
+
if (!model || !gatewayUrl) return {};
|
|
118629
|
+
const provider2 = model.slice(0, model.indexOf("/"));
|
|
118630
|
+
const baseURL = `${gatewayUrl}${OPENCODE_GATEWAY_PATH[provider2] ?? ""}`;
|
|
118631
|
+
return { [provider2]: { options: { baseURL } } };
|
|
118632
|
+
}
|
|
118597
118633
|
function azureProvider(model) {
|
|
118598
118634
|
const prefix = `${AZURE_PROVIDER}/`;
|
|
118599
118635
|
if (!model?.startsWith(prefix)) return {};
|
|
@@ -118709,7 +118745,8 @@ function buildSecurityConfig(ctx, model) {
|
|
|
118709
118745
|
provider: {
|
|
118710
118746
|
openrouter: { models: kimiOpenRouterProviderOverrides() },
|
|
118711
118747
|
...openAICompatibleProvider(model),
|
|
118712
|
-
...azureProvider(model)
|
|
118748
|
+
...azureProvider(model),
|
|
118749
|
+
...providerGatewayOverride(model)
|
|
118713
118750
|
}
|
|
118714
118751
|
};
|
|
118715
118752
|
if (model) {
|
|
@@ -197180,7 +197217,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
197180
197217
|
threadCount: threadBlocks.length,
|
|
197181
197218
|
commentsPath,
|
|
197182
197219
|
toc: formatted.toc,
|
|
197183
|
-
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR
|
|
197220
|
+
instructions: `the file at commentsPath contains ${threadBlocks.length} review threads with full conversation history. comments marked with * are from the target review (${params.review_id}); any other thread is open feedback on this PR, including comments that landed after this run started. Being returned does not authorize a code change; follow the task's scope and each thread's latest request. the TOC shows each thread's file:line and the line number where it appears in the file. to read a specific thread, use: grep -A 50 "^## <file:line>" ${commentsPath} (replace <file:line> with the path from the TOC, e.g. "^## action/utils/foo.ts:42"). read each full thread before deciding whether it calls for a reply or a code change.`
|
|
197184
197221
|
};
|
|
197185
197222
|
})
|
|
197186
197223
|
});
|
|
@@ -197303,8 +197340,7 @@ An existing plan comment was found for this issue. Update that comment with the
|
|
|
197303
197340
|
};
|
|
197304
197341
|
}
|
|
197305
197342
|
var modeInstructionParent = {
|
|
197306
|
-
IncrementalReview: "Review"
|
|
197307
|
-
Fix: "Build"
|
|
197343
|
+
IncrementalReview: "Review"
|
|
197308
197344
|
};
|
|
197309
197345
|
function buildOrchestratorGuidance(ctx, mode, overrideGuidance) {
|
|
197310
197346
|
const hardcoded = overrideGuidance ?? mode.prompt ?? "";
|
|
@@ -198516,18 +198552,13 @@ function hasEnvVar4(name) {
|
|
|
198516
198552
|
const value2 = process.env[name];
|
|
198517
198553
|
return typeof value2 === "string" && value2.length > 0;
|
|
198518
198554
|
}
|
|
198519
|
-
var HOST_OVERRIDES = {
|
|
198520
|
-
ANTHROPIC_API_KEY: "ANTHROPIC_BASE_URL",
|
|
198521
|
-
CLAUDE_CODE_OAUTH_TOKEN: "ANTHROPIC_BASE_URL"
|
|
198522
|
-
};
|
|
198523
198555
|
function envVarsFor(model) {
|
|
198524
198556
|
return model.includes("/") ? getModelEnvVars(model) : [];
|
|
198525
198557
|
}
|
|
198526
198558
|
async function checkOne(params) {
|
|
198527
198559
|
const value2 = process.env[params.envVar];
|
|
198528
198560
|
if (!value2) return null;
|
|
198529
|
-
|
|
198530
|
-
if (hostOverride && hasEnvVar4(hostOverride)) return null;
|
|
198561
|
+
if (getProviderGatewayUrl(params.model)) return null;
|
|
198531
198562
|
if (params.envVar === "CLAUDE_CODE_OAUTH_TOKEN") {
|
|
198532
198563
|
const preflight = await preflightClaudeSubscription({
|
|
198533
198564
|
token: value2,
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { CLI_CONTRACT_HEADER, CLI_CONTRACT_VERSION, CLI_UPGRADE_MESSAGE } from "
|
|
|
6
6
|
export type { ConfigField, ConfigScope, ConfigValue } from "../configuration.ts";
|
|
7
7
|
export { configEntrySchema, configFields, configResponseSchema, configValueSchema, } from "../configuration.ts";
|
|
8
8
|
export type { AuthorPermission, AutoTier, EffortPosition, ModelAlias, ModelProvider, Payload, PayloadEvent, ProviderConfig, PushPermission, ShellPermission, ToolPermission, WriteablePayload, XrepoConfig, } from "../external.ts";
|
|
9
|
-
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, parseEffortPosition, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRung, rungLabel, rungPosition, SUBSIDY_RUNG, } from "../external.ts";
|
|
9
|
+
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, DEFAULT_EFFORT_POSITION, DEFAULT_PROXY_MODEL, defaultAutoTier, EFFORT_ALIASES, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoTier, isCardGatedModel, isEffortPosition, isOssAllowedModel, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, offeredRungs, ossFundedModelNames, PROVIDER_GATEWAY_URL_ENV, parseEffortPosition, parseModel, providers, pullfrogMcpName, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRung, rungLabel, rungPosition, SUBSIDY_RUNG, } from "../external.ts";
|
|
10
10
|
export type { Mode } from "../modes.ts";
|
|
11
11
|
export { modes } from "../modes.ts";
|
|
12
12
|
export { commercialPaywallBody } from "../utils/billingErrors.ts";
|
package/dist/internal.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "pullfrog",
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.76",
|
|
12
12
|
cliContractVersion: "1",
|
|
13
13
|
type: "module",
|
|
14
14
|
bin: {
|
|
@@ -628,7 +628,7 @@ __export(core_exports2, {
|
|
|
628
628
|
parse: () => parse,
|
|
629
629
|
parseAsync: () => parseAsync,
|
|
630
630
|
prettifyError: () => prettifyError,
|
|
631
|
-
process: () =>
|
|
631
|
+
process: () => process2,
|
|
632
632
|
regexes: () => regexes_exports,
|
|
633
633
|
registry: () => registry,
|
|
634
634
|
safeDecode: () => safeDecode,
|
|
@@ -11029,7 +11029,7 @@ function initializeContext(params) {
|
|
|
11029
11029
|
external: params?.external ?? void 0
|
|
11030
11030
|
};
|
|
11031
11031
|
}
|
|
11032
|
-
function
|
|
11032
|
+
function process2(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
11033
11033
|
var _a2;
|
|
11034
11034
|
const def = schema._zod.def;
|
|
11035
11035
|
const seen = ctx.seen.get(schema);
|
|
@@ -11066,7 +11066,7 @@ function process(schema, ctx, _params = { path: [], schemaPath: [] }) {
|
|
|
11066
11066
|
if (parent) {
|
|
11067
11067
|
if (!result.ref)
|
|
11068
11068
|
result.ref = parent;
|
|
11069
|
-
|
|
11069
|
+
process2(parent, ctx, params);
|
|
11070
11070
|
ctx.seen.get(parent).isParent = true;
|
|
11071
11071
|
}
|
|
11072
11072
|
}
|
|
@@ -11347,14 +11347,14 @@ function isTransforming(_schema, _ctx) {
|
|
|
11347
11347
|
}
|
|
11348
11348
|
var createToJSONSchemaMethod = (schema, processors = {}) => (params) => {
|
|
11349
11349
|
const ctx = initializeContext({ ...params, processors });
|
|
11350
|
-
|
|
11350
|
+
process2(schema, ctx);
|
|
11351
11351
|
extractDefs(ctx, schema);
|
|
11352
11352
|
return finalize(ctx, schema);
|
|
11353
11353
|
};
|
|
11354
11354
|
var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {
|
|
11355
11355
|
const { libraryOptions, target } = params ?? {};
|
|
11356
11356
|
const ctx = initializeContext({ ...libraryOptions ?? {}, target, io, processors });
|
|
11357
|
-
|
|
11357
|
+
process2(schema, ctx);
|
|
11358
11358
|
extractDefs(ctx, schema);
|
|
11359
11359
|
return finalize(ctx, schema);
|
|
11360
11360
|
};
|
|
@@ -11611,7 +11611,7 @@ var arrayProcessor = (schema, ctx, _json, params) => {
|
|
|
11611
11611
|
if (typeof maximum === "number")
|
|
11612
11612
|
json2.maxItems = maximum;
|
|
11613
11613
|
json2.type = "array";
|
|
11614
|
-
json2.items =
|
|
11614
|
+
json2.items = process2(def.element, ctx, { ...params, path: [...params.path, "items"] });
|
|
11615
11615
|
};
|
|
11616
11616
|
var objectProcessor = (schema, ctx, _json, params) => {
|
|
11617
11617
|
const json2 = _json;
|
|
@@ -11620,7 +11620,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
11620
11620
|
json2.properties = {};
|
|
11621
11621
|
const shape = def.shape;
|
|
11622
11622
|
for (const key in shape) {
|
|
11623
|
-
json2.properties[key] =
|
|
11623
|
+
json2.properties[key] = process2(shape[key], ctx, {
|
|
11624
11624
|
...params,
|
|
11625
11625
|
path: [...params.path, "properties", key]
|
|
11626
11626
|
});
|
|
@@ -11643,7 +11643,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
11643
11643
|
if (ctx.io === "output")
|
|
11644
11644
|
json2.additionalProperties = false;
|
|
11645
11645
|
} else if (def.catchall) {
|
|
11646
|
-
json2.additionalProperties =
|
|
11646
|
+
json2.additionalProperties = process2(def.catchall, ctx, {
|
|
11647
11647
|
...params,
|
|
11648
11648
|
path: [...params.path, "additionalProperties"]
|
|
11649
11649
|
});
|
|
@@ -11652,7 +11652,7 @@ var objectProcessor = (schema, ctx, _json, params) => {
|
|
|
11652
11652
|
var unionProcessor = (schema, ctx, json2, params) => {
|
|
11653
11653
|
const def = schema._zod.def;
|
|
11654
11654
|
const isExclusive = def.inclusive === false;
|
|
11655
|
-
const options = def.options.map((x, i) =>
|
|
11655
|
+
const options = def.options.map((x, i) => process2(x, ctx, {
|
|
11656
11656
|
...params,
|
|
11657
11657
|
path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
|
|
11658
11658
|
}));
|
|
@@ -11664,11 +11664,11 @@ var unionProcessor = (schema, ctx, json2, params) => {
|
|
|
11664
11664
|
};
|
|
11665
11665
|
var intersectionProcessor = (schema, ctx, json2, params) => {
|
|
11666
11666
|
const def = schema._zod.def;
|
|
11667
|
-
const a =
|
|
11667
|
+
const a = process2(def.left, ctx, {
|
|
11668
11668
|
...params,
|
|
11669
11669
|
path: [...params.path, "allOf", 0]
|
|
11670
11670
|
});
|
|
11671
|
-
const b =
|
|
11671
|
+
const b = process2(def.right, ctx, {
|
|
11672
11672
|
...params,
|
|
11673
11673
|
path: [...params.path, "allOf", 1]
|
|
11674
11674
|
});
|
|
@@ -11685,11 +11685,11 @@ var tupleProcessor = (schema, ctx, _json, params) => {
|
|
|
11685
11685
|
json2.type = "array";
|
|
11686
11686
|
const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
|
|
11687
11687
|
const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
|
|
11688
|
-
const prefixItems = def.items.map((x, i) =>
|
|
11688
|
+
const prefixItems = def.items.map((x, i) => process2(x, ctx, {
|
|
11689
11689
|
...params,
|
|
11690
11690
|
path: [...params.path, prefixPath, i]
|
|
11691
11691
|
}));
|
|
11692
|
-
const rest = def.rest ?
|
|
11692
|
+
const rest = def.rest ? process2(def.rest, ctx, {
|
|
11693
11693
|
...params,
|
|
11694
11694
|
path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
|
|
11695
11695
|
}) : null;
|
|
@@ -11729,7 +11729,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
11729
11729
|
const keyBag = keyType._zod.bag;
|
|
11730
11730
|
const patterns = keyBag?.patterns;
|
|
11731
11731
|
if (def.mode === "loose" && patterns && patterns.size > 0) {
|
|
11732
|
-
const valueSchema =
|
|
11732
|
+
const valueSchema = process2(def.valueType, ctx, {
|
|
11733
11733
|
...params,
|
|
11734
11734
|
path: [...params.path, "patternProperties", "*"]
|
|
11735
11735
|
});
|
|
@@ -11739,12 +11739,12 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
11739
11739
|
}
|
|
11740
11740
|
} else {
|
|
11741
11741
|
if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
|
|
11742
|
-
json2.propertyNames =
|
|
11742
|
+
json2.propertyNames = process2(def.keyType, ctx, {
|
|
11743
11743
|
...params,
|
|
11744
11744
|
path: [...params.path, "propertyNames"]
|
|
11745
11745
|
});
|
|
11746
11746
|
}
|
|
11747
|
-
json2.additionalProperties =
|
|
11747
|
+
json2.additionalProperties = process2(def.valueType, ctx, {
|
|
11748
11748
|
...params,
|
|
11749
11749
|
path: [...params.path, "additionalProperties"]
|
|
11750
11750
|
});
|
|
@@ -11759,7 +11759,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
|
|
|
11759
11759
|
};
|
|
11760
11760
|
var nullableProcessor = (schema, ctx, json2, params) => {
|
|
11761
11761
|
const def = schema._zod.def;
|
|
11762
|
-
const inner =
|
|
11762
|
+
const inner = process2(def.innerType, ctx, params);
|
|
11763
11763
|
const seen = ctx.seen.get(schema);
|
|
11764
11764
|
if (ctx.target === "openapi-3.0") {
|
|
11765
11765
|
seen.ref = def.innerType;
|
|
@@ -11770,20 +11770,20 @@ var nullableProcessor = (schema, ctx, json2, params) => {
|
|
|
11770
11770
|
};
|
|
11771
11771
|
var nonoptionalProcessor = (schema, ctx, _json, params) => {
|
|
11772
11772
|
const def = schema._zod.def;
|
|
11773
|
-
|
|
11773
|
+
process2(def.innerType, ctx, params);
|
|
11774
11774
|
const seen = ctx.seen.get(schema);
|
|
11775
11775
|
seen.ref = def.innerType;
|
|
11776
11776
|
};
|
|
11777
11777
|
var defaultProcessor = (schema, ctx, json2, params) => {
|
|
11778
11778
|
const def = schema._zod.def;
|
|
11779
|
-
|
|
11779
|
+
process2(def.innerType, ctx, params);
|
|
11780
11780
|
const seen = ctx.seen.get(schema);
|
|
11781
11781
|
seen.ref = def.innerType;
|
|
11782
11782
|
json2.default = JSON.parse(JSON.stringify(def.defaultValue));
|
|
11783
11783
|
};
|
|
11784
11784
|
var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
11785
11785
|
const def = schema._zod.def;
|
|
11786
|
-
|
|
11786
|
+
process2(def.innerType, ctx, params);
|
|
11787
11787
|
const seen = ctx.seen.get(schema);
|
|
11788
11788
|
seen.ref = def.innerType;
|
|
11789
11789
|
if (ctx.io === "input")
|
|
@@ -11791,7 +11791,7 @@ var prefaultProcessor = (schema, ctx, json2, params) => {
|
|
|
11791
11791
|
};
|
|
11792
11792
|
var catchProcessor = (schema, ctx, json2, params) => {
|
|
11793
11793
|
const def = schema._zod.def;
|
|
11794
|
-
|
|
11794
|
+
process2(def.innerType, ctx, params);
|
|
11795
11795
|
const seen = ctx.seen.get(schema);
|
|
11796
11796
|
seen.ref = def.innerType;
|
|
11797
11797
|
let catchValue;
|
|
@@ -11805,32 +11805,32 @@ var catchProcessor = (schema, ctx, json2, params) => {
|
|
|
11805
11805
|
var pipeProcessor = (schema, ctx, _json, params) => {
|
|
11806
11806
|
const def = schema._zod.def;
|
|
11807
11807
|
const innerType = ctx.io === "input" ? def.in._zod.def.type === "transform" ? def.out : def.in : def.out;
|
|
11808
|
-
|
|
11808
|
+
process2(innerType, ctx, params);
|
|
11809
11809
|
const seen = ctx.seen.get(schema);
|
|
11810
11810
|
seen.ref = innerType;
|
|
11811
11811
|
};
|
|
11812
11812
|
var readonlyProcessor = (schema, ctx, json2, params) => {
|
|
11813
11813
|
const def = schema._zod.def;
|
|
11814
|
-
|
|
11814
|
+
process2(def.innerType, ctx, params);
|
|
11815
11815
|
const seen = ctx.seen.get(schema);
|
|
11816
11816
|
seen.ref = def.innerType;
|
|
11817
11817
|
json2.readOnly = true;
|
|
11818
11818
|
};
|
|
11819
11819
|
var promiseProcessor = (schema, ctx, _json, params) => {
|
|
11820
11820
|
const def = schema._zod.def;
|
|
11821
|
-
|
|
11821
|
+
process2(def.innerType, ctx, params);
|
|
11822
11822
|
const seen = ctx.seen.get(schema);
|
|
11823
11823
|
seen.ref = def.innerType;
|
|
11824
11824
|
};
|
|
11825
11825
|
var optionalProcessor = (schema, ctx, _json, params) => {
|
|
11826
11826
|
const def = schema._zod.def;
|
|
11827
|
-
|
|
11827
|
+
process2(def.innerType, ctx, params);
|
|
11828
11828
|
const seen = ctx.seen.get(schema);
|
|
11829
11829
|
seen.ref = def.innerType;
|
|
11830
11830
|
};
|
|
11831
11831
|
var lazyProcessor = (schema, ctx, _json, params) => {
|
|
11832
11832
|
const innerType = schema._zod.innerType;
|
|
11833
|
-
|
|
11833
|
+
process2(innerType, ctx, params);
|
|
11834
11834
|
const seen = ctx.seen.get(schema);
|
|
11835
11835
|
seen.ref = innerType;
|
|
11836
11836
|
};
|
|
@@ -11882,7 +11882,7 @@ function toJSONSchema(input, params) {
|
|
|
11882
11882
|
const defs = {};
|
|
11883
11883
|
for (const entry of registry2._idmap.entries()) {
|
|
11884
11884
|
const [_, schema] = entry;
|
|
11885
|
-
|
|
11885
|
+
process2(schema, ctx2);
|
|
11886
11886
|
}
|
|
11887
11887
|
const schemas = {};
|
|
11888
11888
|
const external = {
|
|
@@ -11905,7 +11905,7 @@ function toJSONSchema(input, params) {
|
|
|
11905
11905
|
return { schemas };
|
|
11906
11906
|
}
|
|
11907
11907
|
const ctx = initializeContext({ ...params, processors: allProcessors });
|
|
11908
|
-
|
|
11908
|
+
process2(input, ctx);
|
|
11909
11909
|
extractDefs(ctx, input);
|
|
11910
11910
|
return finalize(ctx, input);
|
|
11911
11911
|
}
|
|
@@ -11963,7 +11963,7 @@ var JSONSchemaGenerator = class {
|
|
|
11963
11963
|
* This must be called before emit().
|
|
11964
11964
|
*/
|
|
11965
11965
|
process(schema, _params = { path: [], schemaPath: [] }) {
|
|
11966
|
-
return
|
|
11966
|
+
return process2(schema, this.ctx, _params);
|
|
11967
11967
|
}
|
|
11968
11968
|
/**
|
|
11969
11969
|
* Emit the final JSON Schema after processing.
|
|
@@ -14023,6 +14023,20 @@ var repoConfigFields = [
|
|
|
14023
14023
|
nullable: true,
|
|
14024
14024
|
description: "additional instructions for planning"
|
|
14025
14025
|
},
|
|
14026
|
+
{
|
|
14027
|
+
key: "prompts.address-reviews",
|
|
14028
|
+
field: "AddressReviews",
|
|
14029
|
+
kind: "prompt",
|
|
14030
|
+
nullable: true,
|
|
14031
|
+
description: "additional instructions for addressing review feedback"
|
|
14032
|
+
},
|
|
14033
|
+
{
|
|
14034
|
+
key: "prompts.fix-ci",
|
|
14035
|
+
field: "Fix",
|
|
14036
|
+
kind: "prompt",
|
|
14037
|
+
nullable: true,
|
|
14038
|
+
description: "additional instructions for fixing CI failures"
|
|
14039
|
+
},
|
|
14026
14040
|
{ key: "mention.enabled", field: "mention", kind: "toggle", description: "respond to mentions" },
|
|
14027
14041
|
{
|
|
14028
14042
|
key: "mention.instructions",
|
|
@@ -15529,6 +15543,10 @@ function isOssAllowedModel(slug) {
|
|
|
15529
15543
|
function getAutoSelectHintModel() {
|
|
15530
15544
|
return defaultProxyDisplayName;
|
|
15531
15545
|
}
|
|
15546
|
+
var PROVIDER_GATEWAY_URL_ENV = {
|
|
15547
|
+
anthropic: "ANTHROPIC_BASE_URL",
|
|
15548
|
+
openai: "OPENAI_BASE_URL"
|
|
15549
|
+
};
|
|
15532
15550
|
|
|
15533
15551
|
// external.ts
|
|
15534
15552
|
var pullfrogMcpName = "pullfrog";
|
|
@@ -15661,26 +15679,24 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
15661
15679
|
|
|
15662
15680
|
2. Checkout the PR branch via \`${t("checkout_pr")}\`.
|
|
15663
15681
|
|
|
15664
|
-
3. Fetch review comments via \`${t("get_review_comments")}
|
|
15682
|
+
3. Fetch review comments via \`${t("get_review_comments")}\` and read the full conversation in each relevant thread.
|
|
15665
15683
|
|
|
15666
|
-
4. For each
|
|
15667
|
-
-
|
|
15684
|
+
4. For each thread:
|
|
15685
|
+
- **check intent first**: questions, explanations, and disagreement call for a reply, not a code change. Change code only when explicitly requested. Automatic review feedback on Pullfrog-authored PRs (\`address_scope: all\`) remains actionable without a separate request; later replies can narrow or withdraw that permission.
|
|
15686
|
+
- under \`address_scope: mentions\`, unmentioned threads are context only unless the user's review-body request explicitly includes them
|
|
15668
15687
|
- **verify the finding yourself** against the actual code before deciding whether to apply \u2014 every comment (human or agent) is a hypothesis, not a directive. agent reviewers especially are fallible.
|
|
15669
|
-
-
|
|
15670
|
-
- if the
|
|
15688
|
+
- keep requested changes **sound, minimal, and elegant**. Reject defensive checks for impossible cases, single-use abstractions, redundant comments, and tautological tests rather than mechanically applying reviewer suggestions.
|
|
15689
|
+
- if intent permits a code change and the finding stands, implement it using your native tools; otherwise reply without editing
|
|
15671
15690
|
- record what was done (or why nothing was done)
|
|
15672
15691
|
|
|
15673
15692
|
5. Quality check:
|
|
15674
|
-
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before
|
|
15675
|
-
-
|
|
15676
|
-
- ${commitStep}
|
|
15693
|
+
- re-call \`${t("get_review_comments")}\` with \`fresh: true\` before finishing, even when only replying. Apply the same scope and intent checks to new comments; respect requests to stop or change direction before committing.
|
|
15694
|
+
- if code changed, test and review the diff, remove unintended changes or bloat, then ${commitStep}
|
|
15677
15695
|
|
|
15678
|
-
6. Finalize
|
|
15679
|
-
- ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*)
|
|
15680
|
-
-
|
|
15681
|
-
-
|
|
15682
|
-
- reply ONCE via \`${t("reply_to_review_comment")}\`. The \`comment_id\` parameter takes the root comment's numeric \`id=\` (from the first \`comment author=...\` tag in the \`${t("get_review_comments")}\` output) \u2014 NOT the \`thread=\` value; that's a separate GraphQL ID used by resolve. The runtime dedupes identical bodies within a session.
|
|
15683
|
-
- **immediately** call \`${t("resolve_review_thread")}\` with that thread's \`thread=\` value as \`thread_id\`. Resolve every thread where you (a) made the requested code change in full \u2014 partial fixes leave the thread open \u2014 OR (b) replied with a substantive answer the user explicitly asked for. Do NOT resolve threads where you pushed back on the request and the disagreement is unresolved; leave those open for the human to mediate.
|
|
15696
|
+
6. Finalize:
|
|
15697
|
+
- **only if code changed**, ${finalizeStep} (same push/prepush guidance as Build mode in *SYSTEM*). If push/commit fails, report the exact error and STOP without claiming a fix or resolving its threads.
|
|
15698
|
+
- reply ONCE per relevant thread via \`${t("reply_to_review_comment")}\`, including when no code changed. The \`comment_id\` is the root comment's numeric \`id=\`, NOT the \`thread=\` value from \`${t("get_review_comments")}\`. The runtime dedupes identical bodies within a session.
|
|
15699
|
+
- resolve a thread via \`${t("resolve_review_thread")}\` (using \`thread=\` as \`thread_id\`) only after its requested fix is fully on the remote, or the user explicitly asks to resolve it. Leave discussion-only replies, partial fixes, and disagreements open.
|
|
15684
15700
|
- call \`${t("report_progress")}\` with a brief summary. If your last \`${t("get_review_comments")}\` turned up threads you did not address, name them there \u2014 a review arriving this late is suppressed as a duplicate and nothing else will pick it up.`
|
|
15685
15701
|
},
|
|
15686
15702
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
@@ -16594,6 +16610,7 @@ export {
|
|
|
16594
16610
|
OAuthInvalidGrantError,
|
|
16595
16611
|
OSS_MODEL_ALLOWLIST,
|
|
16596
16612
|
OSS_RECOMMENDED_MODEL,
|
|
16613
|
+
PROVIDER_GATEWAY_URL_ENV,
|
|
16597
16614
|
PULLFROG_DIVIDER,
|
|
16598
16615
|
RUN_STATUS_CHECK_NAME,
|
|
16599
16616
|
SUBSIDY_RUNG,
|
package/dist/models.d.ts
CHANGED
|
@@ -376,6 +376,27 @@ export declare const OPENAI_COMPATIBLE_CONTEXT_ENV = "OPENAI_COMPATIBLE_CONTEXT"
|
|
|
376
376
|
* `context` + `output` together, so the pair is validated and emitted as a unit.
|
|
377
377
|
*/
|
|
378
378
|
export declare const OPENAI_COMPATIBLE_MAX_OUTPUT_ENV = "OPENAI_COMPATIBLE_MAX_OUTPUT";
|
|
379
|
+
/**
|
|
380
|
+
* Providers whose endpoint can be re-pointed at a customer gateway, and the env
|
|
381
|
+
* var that does it. Deliberately a short explicit map rather than a derived
|
|
382
|
+
* `<PROVIDER>_BASE_URL` rule: only a provider we have confirmed reachable
|
|
383
|
+
* through a proxy belongs here, and three of them must never be.
|
|
384
|
+
* `openai-compatible` already owns its endpoint via OPENAI_COMPATIBLE_BASE_URL,
|
|
385
|
+
* `azure` derives one from AZURE_RESOURCE_NAME, and bedrock/vertex authenticate
|
|
386
|
+
* against a cloud SDK rather than a URL.
|
|
387
|
+
*
|
|
388
|
+
* models.dev declares no base-URL env var for any catalogued provider (2 of 213
|
|
389
|
+
* do, and neither is one of these), so nothing reads these names on its own —
|
|
390
|
+
* `providerGatewayOverride` is what makes them mean anything to opencode and
|
|
391
|
+
* `gatewayProvider` to codex, while claude-code reads ANTHROPIC_BASE_URL itself.
|
|
392
|
+
*
|
|
393
|
+
* Adding a provider that ALREADY has a block in `buildSecurityConfig` needs a
|
|
394
|
+
* merge, not an entry here: that spread replaces the whole key, so listing
|
|
395
|
+
* `openrouter` would silently drop `kimiOpenRouterProviderOverrides()`.
|
|
396
|
+
*/
|
|
397
|
+
export declare const PROVIDER_GATEWAY_URL_ENV: Record<string, string>;
|
|
398
|
+
/** the customer gateway a model's provider is re-pointed at, if any. */
|
|
399
|
+
export declare function getProviderGatewayUrl(specifier: string | undefined): string | undefined;
|
|
379
400
|
/**
|
|
380
401
|
* the Bedrock model ID passed to claude-code or opencode is whatever the
|
|
381
402
|
* user set in `BEDROCK_MODEL_ID` — Pullfrog never resolves or upgrades it.
|