pullfrog 0.1.75 → 0.1.77
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 +174 -33
- package/dist/external.d.ts +20 -2
- package/dist/index.js +158 -31
- package/dist/internal/index.d.ts +2 -2
- package/dist/internal.js +169 -45
- package/dist/models.d.ts +73 -0
- package/dist/utils/payload.d.ts +14 -0
- package/dist/utils/runContext.d.ts +4 -0
- package/dist/utils/runContextData.d.ts +3 -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.77",
|
|
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",
|
|
@@ -126058,6 +126072,71 @@ var AUTO_TIER_TARGET = {
|
|
|
126058
126072
|
function isAutoTier(slug2) {
|
|
126059
126073
|
return slug2 === AUTO_EFFICIENT || slug2 === AUTO_INTELLIGENT;
|
|
126060
126074
|
}
|
|
126075
|
+
var PROVIDER_LADDERS = {
|
|
126076
|
+
anthropic: {
|
|
126077
|
+
minimal: "anthropic/claude-haiku",
|
|
126078
|
+
light: "anthropic/claude-sonnet",
|
|
126079
|
+
standard: "anthropic/claude-opus",
|
|
126080
|
+
deep: "anthropic/claude-opus"
|
|
126081
|
+
},
|
|
126082
|
+
openai: {
|
|
126083
|
+
minimal: "openai/gpt-luna",
|
|
126084
|
+
light: "openai/gpt-terra",
|
|
126085
|
+
standard: "openai/gpt-sol",
|
|
126086
|
+
deep: "openai/gpt-astra"
|
|
126087
|
+
},
|
|
126088
|
+
google: {
|
|
126089
|
+
minimal: "google/gemini-flash",
|
|
126090
|
+
light: "google/gemini-flash",
|
|
126091
|
+
standard: "google/gemini-pro",
|
|
126092
|
+
deep: "google/gemini-pro"
|
|
126093
|
+
},
|
|
126094
|
+
deepseek: {
|
|
126095
|
+
minimal: "deepseek/deepseek-flash",
|
|
126096
|
+
light: "deepseek/deepseek-flash",
|
|
126097
|
+
standard: "deepseek/deepseek-pro",
|
|
126098
|
+
deep: "deepseek/deepseek-pro"
|
|
126099
|
+
},
|
|
126100
|
+
xai: {
|
|
126101
|
+
minimal: "xai/grok-fast",
|
|
126102
|
+
light: "xai/grok-fast",
|
|
126103
|
+
standard: "xai/grok",
|
|
126104
|
+
deep: "xai/grok"
|
|
126105
|
+
},
|
|
126106
|
+
moonshotai: {
|
|
126107
|
+
minimal: "moonshotai/kimi-k2",
|
|
126108
|
+
light: "moonshotai/kimi-k2",
|
|
126109
|
+
standard: "moonshotai/kimi-k3",
|
|
126110
|
+
deep: "moonshotai/kimi-k3"
|
|
126111
|
+
},
|
|
126112
|
+
openrouter: {
|
|
126113
|
+
minimal: "openrouter/deepseek-flash",
|
|
126114
|
+
light: "openrouter/gpt-luna",
|
|
126115
|
+
standard: "openrouter/gpt-sol",
|
|
126116
|
+
deep: "openrouter/claude-opus"
|
|
126117
|
+
},
|
|
126118
|
+
opencode: {
|
|
126119
|
+
minimal: "opencode/gpt-luna",
|
|
126120
|
+
light: "opencode/gpt-luna",
|
|
126121
|
+
standard: "opencode/gpt-sol",
|
|
126122
|
+
deep: "opencode/claude-opus"
|
|
126123
|
+
}
|
|
126124
|
+
};
|
|
126125
|
+
var ROUTER_LADDER = {
|
|
126126
|
+
minimal: "deepseek/deepseek-flash",
|
|
126127
|
+
light: "openai/gpt-luna",
|
|
126128
|
+
standard: "openai/gpt-sol",
|
|
126129
|
+
deep: "anthropic/claude-opus"
|
|
126130
|
+
};
|
|
126131
|
+
var AUTO_PREFIX = "auto/";
|
|
126132
|
+
function autoLadder(slug2) {
|
|
126133
|
+
if (!slug2 || !slug2.startsWith(AUTO_PREFIX) || isAutoTier(slug2)) return void 0;
|
|
126134
|
+
const target = slug2.slice(AUTO_PREFIX.length);
|
|
126135
|
+
return target === "router" ? ROUTER_LADDER : PROVIDER_LADDERS[target];
|
|
126136
|
+
}
|
|
126137
|
+
var ROUTED_PROVIDERS = Object.keys(
|
|
126138
|
+
PROVIDER_LADDERS
|
|
126139
|
+
).map((key) => ({ key, displayName: providers[key].displayName }));
|
|
126061
126140
|
function isCardGatedModel(slug2) {
|
|
126062
126141
|
return resolveOpenRouterModel(slug2) !== void 0;
|
|
126063
126142
|
}
|
|
@@ -126066,7 +126145,7 @@ function resolveModelSlug(slug2) {
|
|
|
126066
126145
|
}
|
|
126067
126146
|
var MAX_FALLBACK_DEPTH = 10;
|
|
126068
126147
|
function resolveDisplayAlias(slug2) {
|
|
126069
|
-
let current = isAutoTier(slug2) ? AUTO_TIER_TARGET[slug2] : slug2;
|
|
126148
|
+
let current = isAutoTier(slug2) ? AUTO_TIER_TARGET[slug2] : autoLadder(slug2)?.standard ?? slug2;
|
|
126070
126149
|
const visited = /* @__PURE__ */ new Set();
|
|
126071
126150
|
for (let i2 = 0; i2 < MAX_FALLBACK_DEPTH; i2++) {
|
|
126072
126151
|
if (visited.has(current)) return void 0;
|
|
@@ -126101,6 +126180,11 @@ if (!defaultProxyAlias?.openRouterResolve) {
|
|
|
126101
126180
|
}
|
|
126102
126181
|
var DEFAULT_PROXY_MODEL = defaultProxyAlias.openRouterResolve;
|
|
126103
126182
|
var defaultProxyDisplayName = defaultProxyAlias.displayName;
|
|
126183
|
+
for (const [name, ladder] of Object.entries({ ...PROVIDER_LADDERS, router: ROUTER_LADDER })) {
|
|
126184
|
+
for (const slug2 of Object.values(ladder)) {
|
|
126185
|
+
if (!resolveDisplayAlias(slug2)) throw new Error(`${name} ladder names unknown alias ${slug2}`);
|
|
126186
|
+
}
|
|
126187
|
+
}
|
|
126104
126188
|
var OSS_MODEL_ALLOWLIST = [
|
|
126105
126189
|
"deepseek/deepseek-flash",
|
|
126106
126190
|
"deepseek/deepseek-pro",
|
|
@@ -126138,6 +126222,17 @@ var OPENAI_COMPATIBLE_API_KEY_ENV = "OPENAI_COMPATIBLE_API_KEY";
|
|
|
126138
126222
|
var OPENAI_COMPATIBLE_MODEL_ENV = "OPENAI_COMPATIBLE_MODEL";
|
|
126139
126223
|
var OPENAI_COMPATIBLE_CONTEXT_ENV = "OPENAI_COMPATIBLE_CONTEXT";
|
|
126140
126224
|
var OPENAI_COMPATIBLE_MAX_OUTPUT_ENV = "OPENAI_COMPATIBLE_MAX_OUTPUT";
|
|
126225
|
+
var PROVIDER_GATEWAY_URL_ENV = {
|
|
126226
|
+
anthropic: "ANTHROPIC_BASE_URL",
|
|
126227
|
+
openai: "OPENAI_BASE_URL"
|
|
126228
|
+
};
|
|
126229
|
+
function getProviderGatewayUrl(specifier) {
|
|
126230
|
+
const slashIndex = specifier?.indexOf("/") ?? -1;
|
|
126231
|
+
if (!specifier || slashIndex <= 0) return void 0;
|
|
126232
|
+
const envVar = PROVIDER_GATEWAY_URL_ENV[specifier.slice(0, slashIndex)];
|
|
126233
|
+
if (!envVar) return void 0;
|
|
126234
|
+
return process.env[envVar]?.trim().replace(/\/$/, "") || void 0;
|
|
126235
|
+
}
|
|
126141
126236
|
function isBedrockAnthropicId(bedrockModelId) {
|
|
126142
126237
|
return bedrockModelId.toLowerCase().split(/[./:]/).includes("anthropic");
|
|
126143
126238
|
}
|
|
@@ -127644,26 +127739,24 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
|
|
|
127644
127739
|
|
|
127645
127740
|
2. Checkout the PR branch via \`${t2("checkout_pr")}\`.
|
|
127646
127741
|
|
|
127647
|
-
3. Fetch review comments via \`${t2("get_review_comments")}
|
|
127742
|
+
3. Fetch review comments via \`${t2("get_review_comments")}\` and read the full conversation in each relevant thread.
|
|
127648
127743
|
|
|
127649
|
-
4. For each
|
|
127650
|
-
-
|
|
127744
|
+
4. For each thread:
|
|
127745
|
+
- **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.
|
|
127746
|
+
- under \`address_scope: mentions\`, unmentioned threads are context only unless the user's review-body request explicitly includes them
|
|
127651
127747
|
- **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
|
|
127748
|
+
- 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.
|
|
127749
|
+
- if intent permits a code change and the finding stands, implement it using your native tools; otherwise reply without editing
|
|
127654
127750
|
- record what was done (or why nothing was done)
|
|
127655
127751
|
|
|
127656
127752
|
5. Quality check:
|
|
127657
|
-
- re-call \`${t2("get_review_comments")}\` with \`fresh: true\` before
|
|
127658
|
-
-
|
|
127659
|
-
- ${commitStep}
|
|
127753
|
+
- 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.
|
|
127754
|
+
- if code changed, test and review the diff, remove unintended changes or bloat, then ${commitStep}
|
|
127660
127755
|
|
|
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.
|
|
127756
|
+
6. Finalize:
|
|
127757
|
+
- **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.
|
|
127758
|
+
- 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.
|
|
127759
|
+
- 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
127760
|
- 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
127761
|
},
|
|
127669
127762
|
// Review and IncrementalReview route the minimum reviewfrog specialists
|
|
@@ -129640,6 +129733,19 @@ function warnIfNativeEditsUnavailable(ctx) {
|
|
|
129640
129733
|
"\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
129734
|
);
|
|
129642
129735
|
}
|
|
129736
|
+
var CODEX_GATEWAY_PROVIDER = "pullfrog-gateway";
|
|
129737
|
+
function gatewayProvider(gatewayUrl) {
|
|
129738
|
+
if (!gatewayUrl) return [];
|
|
129739
|
+
return [
|
|
129740
|
+
`[model_providers.${CODEX_GATEWAY_PROVIDER}]`,
|
|
129741
|
+
'name = "OpenAI gateway"',
|
|
129742
|
+
`base_url = ${JSON.stringify(gatewayUrl)}`,
|
|
129743
|
+
'wire_api = "responses"',
|
|
129744
|
+
// where the harness puts the run's OPENAI_API_KEY
|
|
129745
|
+
'env_key = "CODEX_API_KEY"',
|
|
129746
|
+
""
|
|
129747
|
+
];
|
|
129748
|
+
}
|
|
129643
129749
|
function writeCodexConfig(params) {
|
|
129644
129750
|
const shellEnabled = params.ctx.payload.shell === "enabled";
|
|
129645
129751
|
const sandboxMode = params.ctx.payload.push === "disabled" ? "read-only" : "workspace-write";
|
|
@@ -129656,6 +129762,7 @@ function writeCodexConfig(params) {
|
|
|
129656
129762
|
'web_search = "live"',
|
|
129657
129763
|
...params.model ? [`model = ${JSON.stringify(params.model)}`] : [],
|
|
129658
129764
|
...params.effortRung ? [`model_reasoning_effort = ${JSON.stringify(params.effortRung)}`] : [],
|
|
129765
|
+
...params.gatewayUrl ? [`model_provider = ${JSON.stringify(CODEX_GATEWAY_PROVIDER)}`] : [],
|
|
129659
129766
|
"",
|
|
129660
129767
|
"[features]",
|
|
129661
129768
|
tomlBool(CODEX_DISABLED_FEATURES, false),
|
|
@@ -129685,6 +129792,7 @@ function writeCodexConfig(params) {
|
|
|
129685
129792
|
"tool_timeout_sec = 660",
|
|
129686
129793
|
"",
|
|
129687
129794
|
...repoMcpApprovals(repoDir),
|
|
129795
|
+
...gatewayProvider(params.gatewayUrl),
|
|
129688
129796
|
// UNTRUSTED, deliberately, and this one line is the whole config-precedence
|
|
129689
129797
|
// boundary. Codex loads `<repo>/.codex/config.toml` as a layer that
|
|
129690
129798
|
// OUTRANKS ours (project 25 vs user 20), and its denylist strips none of
|
|
@@ -129953,7 +130061,11 @@ var codex = agent({
|
|
|
129953
130061
|
ctx,
|
|
129954
130062
|
codexHome,
|
|
129955
130063
|
model: resolveCodexModel(ctx),
|
|
129956
|
-
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0
|
|
130064
|
+
effortRung: effort.rung && CODEX_EFFORTS.includes(effort.rung) ? effort.rung : void 0,
|
|
130065
|
+
// keyed off OpenAI, not the resolved model: codex serves nothing else, an
|
|
130066
|
+
// auto-selected run has no model, and a ChatGPT-subscription token is
|
|
130067
|
+
// valid only at ChatGPT's own backend
|
|
130068
|
+
gatewayUrl: codexHomeAuth ? void 0 : getProviderGatewayUrl("openai/")
|
|
129957
130069
|
});
|
|
129958
130070
|
if (codexHomeAuth) {
|
|
129959
130071
|
core3.saveState(
|
|
@@ -135720,6 +135832,14 @@ function openAICompatibleProvider(model) {
|
|
|
135720
135832
|
}
|
|
135721
135833
|
};
|
|
135722
135834
|
}
|
|
135835
|
+
var OPENCODE_GATEWAY_PATH = { anthropic: "/v1" };
|
|
135836
|
+
function providerGatewayOverride(model) {
|
|
135837
|
+
const gatewayUrl = getProviderGatewayUrl(model);
|
|
135838
|
+
if (!model || !gatewayUrl) return {};
|
|
135839
|
+
const provider2 = model.slice(0, model.indexOf("/"));
|
|
135840
|
+
const baseURL = `${gatewayUrl}${OPENCODE_GATEWAY_PATH[provider2] ?? ""}`;
|
|
135841
|
+
return { [provider2]: { options: { baseURL } } };
|
|
135842
|
+
}
|
|
135723
135843
|
function azureProvider(model) {
|
|
135724
135844
|
const prefix = `${AZURE_PROVIDER}/`;
|
|
135725
135845
|
if (!model?.startsWith(prefix)) return {};
|
|
@@ -135835,7 +135955,8 @@ function buildSecurityConfig(ctx, model) {
|
|
|
135835
135955
|
provider: {
|
|
135836
135956
|
openrouter: { models: kimiOpenRouterProviderOverrides() },
|
|
135837
135957
|
...openAICompatibleProvider(model),
|
|
135838
|
-
...azureProvider(model)
|
|
135958
|
+
...azureProvider(model),
|
|
135959
|
+
...providerGatewayOverride(model)
|
|
135839
135960
|
}
|
|
135840
135961
|
};
|
|
135841
135962
|
if (model) {
|
|
@@ -214306,7 +214427,7 @@ function GetReviewCommentsTool(ctx) {
|
|
|
214306
214427
|
threadCount: threadBlocks.length,
|
|
214307
214428
|
commentsPath,
|
|
214308
214429
|
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
|
|
214430
|
+
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
214431
|
};
|
|
214311
214432
|
})
|
|
214312
214433
|
});
|
|
@@ -214429,8 +214550,7 @@ An existing plan comment was found for this issue. Update that comment with the
|
|
|
214429
214550
|
};
|
|
214430
214551
|
}
|
|
214431
214552
|
var modeInstructionParent = {
|
|
214432
|
-
IncrementalReview: "Review"
|
|
214433
|
-
Fix: "Build"
|
|
214553
|
+
IncrementalReview: "Review"
|
|
214434
214554
|
};
|
|
214435
214555
|
function buildOrchestratorGuidance(ctx, mode, overrideGuidance) {
|
|
214436
214556
|
const hardcoded = overrideGuidance ?? mode.prompt ?? "";
|
|
@@ -215642,18 +215762,13 @@ function hasEnvVar4(name) {
|
|
|
215642
215762
|
const value2 = process.env[name];
|
|
215643
215763
|
return typeof value2 === "string" && value2.length > 0;
|
|
215644
215764
|
}
|
|
215645
|
-
var HOST_OVERRIDES = {
|
|
215646
|
-
ANTHROPIC_API_KEY: "ANTHROPIC_BASE_URL",
|
|
215647
|
-
CLAUDE_CODE_OAUTH_TOKEN: "ANTHROPIC_BASE_URL"
|
|
215648
|
-
};
|
|
215649
215765
|
function envVarsFor(model) {
|
|
215650
215766
|
return model.includes("/") ? getModelEnvVars(model) : [];
|
|
215651
215767
|
}
|
|
215652
215768
|
async function checkOne(params) {
|
|
215653
215769
|
const value2 = process.env[params.envVar];
|
|
215654
215770
|
if (!value2) return null;
|
|
215655
|
-
|
|
215656
|
-
if (hostOverride && hasEnvVar4(hostOverride)) return null;
|
|
215771
|
+
if (getProviderGatewayUrl(params.model)) return null;
|
|
215657
215772
|
if (params.envVar === "CLAUDE_CODE_OAUTH_TOKEN") {
|
|
215658
215773
|
const preflight = await preflightClaudeSubscription({
|
|
215659
215774
|
token: value2,
|
|
@@ -216571,6 +216686,15 @@ var JsonPayload = type({
|
|
|
216571
216686
|
"type?": "string | undefined",
|
|
216572
216687
|
"model?": "string | undefined",
|
|
216573
216688
|
"modelExplicit?": "boolean | undefined",
|
|
216689
|
+
// optional so a payload from a pre-router server build still parses against a
|
|
216690
|
+
// newer action across a rolling deploy.
|
|
216691
|
+
"routing?": type({
|
|
216692
|
+
tier: "'minimal' | 'light' | 'standard' | 'deep'",
|
|
216693
|
+
stakes: "number",
|
|
216694
|
+
workload: "number",
|
|
216695
|
+
source: "'scorer' | 'heuristic' | 'fixed'",
|
|
216696
|
+
rationale: "string"
|
|
216697
|
+
}).or("undefined"),
|
|
216574
216698
|
"effort?": "number | string | undefined",
|
|
216575
216699
|
"debug?": "boolean | undefined",
|
|
216576
216700
|
prompt: "string",
|
|
@@ -216752,6 +216876,7 @@ function resolvePayload(resolvedPromptInput, repoSettings) {
|
|
|
216752
216876
|
// explicit only when the model came from a per-run override flag (carried on
|
|
216753
216877
|
// the JSON payload). a GHA `model` input or the repo default is not explicit.
|
|
216754
216878
|
modelExplicit: jsonPayload?.modelExplicit ?? false,
|
|
216879
|
+
routing: jsonPayload?.routing,
|
|
216755
216880
|
effort,
|
|
216756
216881
|
debug: debug4 || void 0,
|
|
216757
216882
|
prompt,
|
|
@@ -217438,9 +217563,12 @@ async function fetchRunContext(params) {
|
|
|
217438
217563
|
if (params.oidcToken) {
|
|
217439
217564
|
headers["X-GitHub-OIDC-Token"] = params.oidcToken;
|
|
217440
217565
|
}
|
|
217441
|
-
const query =
|
|
217566
|
+
const query = new URLSearchParams();
|
|
217567
|
+
if (params.runType) query.set("type", params.runType);
|
|
217568
|
+
if (params.routedTier) query.set("tier", params.routedTier);
|
|
217569
|
+
const search2 = query.toString();
|
|
217442
217570
|
const response = await apiFetch({
|
|
217443
|
-
path: `/api/repo/${params.repoContext.owner}/${params.repoContext.name}/run-context${
|
|
217571
|
+
path: `/api/repo/${params.repoContext.owner}/${params.repoContext.name}/run-context${search2 ? `?${search2}` : ""}`,
|
|
217444
217572
|
headers,
|
|
217445
217573
|
signal: controller.signal
|
|
217446
217574
|
});
|
|
@@ -217507,7 +217635,13 @@ async function resolveRunContextData(params) {
|
|
|
217507
217635
|
retries: [100, 500],
|
|
217508
217636
|
bail: (error109) => !isTransientOctokitError(error109)
|
|
217509
217637
|
})(),
|
|
217510
|
-
fetchRunContext({
|
|
217638
|
+
fetchRunContext({
|
|
217639
|
+
token: params.token,
|
|
217640
|
+
repoContext,
|
|
217641
|
+
oidcToken,
|
|
217642
|
+
runType: params.runType,
|
|
217643
|
+
routedTier: params.routedTier
|
|
217644
|
+
})
|
|
217511
217645
|
]);
|
|
217512
217646
|
return {
|
|
217513
217647
|
repo: {
|
|
@@ -218415,6 +218549,12 @@ function logRunStartup(ctx) {
|
|
|
218415
218549
|
log2.info(
|
|
218416
218550
|
`\xBB effort: ${resolveEffortForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`
|
|
218417
218551
|
);
|
|
218552
|
+
const routing = ctx.payload.routing;
|
|
218553
|
+
if (routing) {
|
|
218554
|
+
log2.info(
|
|
218555
|
+
`\xBB routed: ${routing.tier} (${routing.source}: stakes ${routing.stakes}, workload ${routing.workload}) \u2014 ${routing.rationale}`
|
|
218556
|
+
);
|
|
218557
|
+
}
|
|
218418
218558
|
log2.info(
|
|
218419
218559
|
`\xBB agent: ${resolveAgentForLog({ agentName: ctx.agentName, resolvedModel: ctx.resolvedModel })}`
|
|
218420
218560
|
);
|
|
@@ -218609,7 +218749,8 @@ async function main() {
|
|
|
218609
218749
|
const runContext = await resolveRunContextData({
|
|
218610
218750
|
octokit: initialOctokit,
|
|
218611
218751
|
token: jobToken,
|
|
218612
|
-
runType: typeof resolvedPromptInput === "string" ? void 0 : resolvedPromptInput.type
|
|
218752
|
+
runType: typeof resolvedPromptInput === "string" ? void 0 : resolvedPromptInput.type,
|
|
218753
|
+
routedTier: typeof resolvedPromptInput === "string" ? void 0 : resolvedPromptInput.routing?.tier
|
|
218613
218754
|
});
|
|
218614
218755
|
timer.checkpoint("runContextData");
|
|
218615
218756
|
const payload = resolvePayload(resolvedPromptInput, runContext.repoSettings);
|
|
@@ -219730,7 +219871,7 @@ function resolveTarget2(repo) {
|
|
|
219730
219871
|
return { owner: match3[1], repo: match3[2] };
|
|
219731
219872
|
}
|
|
219732
219873
|
function cliVersion() {
|
|
219733
|
-
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.
|
|
219874
|
+
const parts = /^(\d+)\.(\d+)\.(\d+)$/.exec("0.1.77");
|
|
219734
219875
|
if (!parts) return "0.0.0";
|
|
219735
219876
|
return `${Number(parts[1])}.${Number(parts[2])}.${Number(parts[3])}`;
|
|
219736
219877
|
}
|
|
@@ -219897,7 +220038,7 @@ async function runCli8(input2) {
|
|
|
219897
220038
|
}
|
|
219898
220039
|
|
|
219899
220040
|
// cli.ts
|
|
219900
|
-
var VERSION10 = "0.1.
|
|
220041
|
+
var VERSION10 = "0.1.77";
|
|
219901
220042
|
var bin = basename2(process.argv[1] || "");
|
|
219902
220043
|
var PROG = bin === "pf" || bin === "pullfrog" ? bin : "pullfrog";
|
|
219903
220044
|
var rawArgs = process.argv.slice(2);
|
package/dist/external.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Other files in action/ re-export from this file for backward compatibility.
|
|
5
5
|
*/
|
|
6
6
|
import type { EffortPosition } from "./effort.ts";
|
|
7
|
+
import type { RouterTier } from "./models.ts";
|
|
7
8
|
export declare const pullfrogMcpName = "pullfrog";
|
|
8
9
|
/** @see {@link file://./agents/shared.ts} Agent interface that uses this type */
|
|
9
10
|
export type AgentId = "claude" | "codex" | "opencode";
|
|
@@ -51,8 +52,8 @@ export declare function findDanglingPromptToolRefs(params: {
|
|
|
51
52
|
}): string[];
|
|
52
53
|
export type { EffortPosition } from "./effort.ts";
|
|
53
54
|
export { DEFAULT_EFFORT_POSITION, EFFORT_ALIASES, isEffortPosition, offeredRungs, parseEffortPosition, resolveRung, rungLabel, rungPosition, SUBSIDY_RUNG, } from "./effort.ts";
|
|
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 type { AutoTier, ModelAlias, ModelProvider, ProviderConfig, RouterTier, } from "./models.ts";
|
|
56
|
+
export { AUTO_EFFICIENT, AUTO_INTELLIGENT, AUTO_ROUTER, autoLadder, autoRoutedSlug, DEFAULT_PROXY_MODEL, defaultAutoTier, getAutoSelectHintModel, getModelEffortLevels, getModelEnvVars, getModelManagedCredentials, getModelProvider, getProviderDisplayName, isAutoRouted, isAutoSlug, isAutoTier, isCardGatedModel, isOssAllowedModel, isRouterTier, ladderRungs, modelAliases, modelHasStoredAuth, OSS_MODEL_ALLOWLIST, OSS_RECOMMENDED_MODEL, ossFundedModelNames, PROVIDER_GATEWAY_URL_ENV, parseModel, providers, ROUTED_PROVIDERS, ROUTER_LADDER, ROUTER_TIERS, resolveAutoTier, resolveCliModel, resolveDisplayAlias, resolveModelRung, resolveModelSlug, resolveOpenRouterModel, resolveRoutedModel, } from "./models.ts";
|
|
56
57
|
export type ToolPermission = "disabled" | "enabled";
|
|
57
58
|
export type ShellPermission = "disabled" | "restricted" | "enabled";
|
|
58
59
|
export type PushPermission = "disabled" | "restricted" | "enabled";
|
|
@@ -262,6 +263,21 @@ export interface XrepoConfig {
|
|
|
262
263
|
*/
|
|
263
264
|
unavailable?: string[] | undefined;
|
|
264
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* the model router's decision, carried so the runner can log it and forward the
|
|
268
|
+
* tier to run-context as `?tier=` — the Router proxy mint happens there and
|
|
269
|
+
* never sees `model` below. see wiki/router.md.
|
|
270
|
+
*/
|
|
271
|
+
export interface PayloadRouting {
|
|
272
|
+
tier: RouterTier;
|
|
273
|
+
stakes: number;
|
|
274
|
+
workload: number;
|
|
275
|
+
/** who decided: the scorer, the heuristic it falls back to, or the fixed tier a non-review kind of work carries. mirrors the `RouterSource` enum. */
|
|
276
|
+
source: RouterSource;
|
|
277
|
+
/** the scorer's own sentence or two on what a reviewer must reconstruct */
|
|
278
|
+
rationale: string;
|
|
279
|
+
}
|
|
280
|
+
export type RouterSource = "scorer" | "heuristic" | "fixed";
|
|
265
281
|
export interface WriteablePayload {
|
|
266
282
|
"~pullfrog": true;
|
|
267
283
|
/** semantic version of the payload to ensure compatibility */
|
|
@@ -283,6 +299,8 @@ export interface WriteablePayload {
|
|
|
283
299
|
* baseInstructions flag) keeps the soft-fallback safety net. see modelAccess.ts.
|
|
284
300
|
*/
|
|
285
301
|
modelExplicit?: boolean | undefined;
|
|
302
|
+
/** the model router's decision, when it made one; `model` above already reflects it */
|
|
303
|
+
routing?: PayloadRouting | undefined;
|
|
286
304
|
/** reasoning-effort position on [0,1]; 0 is the model's cheapest rung, 1 its priciest */
|
|
287
305
|
effort?: EffortPosition | undefined;
|
|
288
306
|
/**
|