@jx-grxf/patchpilot 0.3.1-beta → 0.4.0
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/README.md +14 -11
- package/SECURITY.md +3 -1
- package/dist/core/gemini.js +27 -14
- package/dist/core/gemini.js.map +1 -1
- package/dist/core/nvidia.js +19 -1
- package/dist/core/nvidia.js.map +1 -1
- package/dist/core/openrouter.d.ts +2 -0
- package/dist/core/openrouter.js +51 -7
- package/dist/core/openrouter.js.map +1 -1
- package/dist/core/workspace.js +26 -5
- package/dist/core/workspace.js.map +1 -1
- package/dist/tui/App.js +39 -16
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/components/ApprovalPanel.d.ts +6 -0
- package/dist/tui/components/ApprovalPanel.js +16 -0
- package/dist/tui/components/ApprovalPanel.js.map +1 -0
- package/dist/tui/components/Composer.d.ts +1 -0
- package/dist/tui/components/Composer.js +1 -1
- package/dist/tui/components/Composer.js.map +1 -1
- package/dist/tui/components/Sidebar.js +18 -16
- package/dist/tui/components/Sidebar.js.map +1 -1
- package/dist/tui/components/Transcript.js +3 -2
- package/dist/tui/components/Transcript.js.map +1 -1
- package/docs/releases/v0.4.0.md +27 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**A local-first coding-agent TUI that makes repo changes visible, permissioned, and easy to review across local, remote, and cloud model routes.**
|
|
6
6
|
|
|
7
7
|
[](https://github.com/jx-grxf/PatchPilot/actions/workflows/ci.yml)
|
|
8
|
-

|
|
9
9
|

|
|
10
10
|

|
|
11
11
|

|
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
PatchPilot is a terminal interface for running coding-agent tasks inside a repository. It shows what the agent is doing, keeps risky actions behind explicit permissions, and supports local Ollama, remote Ollama, Google Gemini, OpenRouter, NVIDIA NIM-compatible endpoints, and Codex CLI OAuth.
|
|
30
30
|
|
|
31
|
+
PatchPilot is still preview software. The v0.4 line focuses on making the TUI, approvals, and provider selection reliable enough for real project use; it is not a finished autonomous PR bot or a v1 desktop product.
|
|
32
|
+
|
|
31
33
|
---
|
|
32
34
|
|
|
33
35
|
## Contents
|
|
@@ -56,7 +58,7 @@ PatchPilot is a terminal interface for running coding-agent tasks inside a repos
|
|
|
56
58
|
| Cloud provider routes | Gemini, OpenRouter, NVIDIA, and Codex CLI OAuth are available from one TUI. |
|
|
57
59
|
| Guided onboarding | First-run setup walks through local/remote mode, provider auth, host discovery, and model choice. |
|
|
58
60
|
| Observable agent loop | Transcript, tool calls, telemetry, token counts, provider cache hits, latency, and cost estimates are visible. |
|
|
59
|
-
| Explicit permissions | Risky tools
|
|
61
|
+
| Explicit permissions | Risky tools show a sticky approval box unless trusted bypass is explicitly accepted. |
|
|
60
62
|
| Workspace boundary | File tools are constrained to the selected project root and block common secret files. |
|
|
61
63
|
| Slash-command palette | Type `/` for browsable commands, provider switching, modes, models, diagnostics, and host selection. |
|
|
62
64
|
| Advisor subagents | Explorer, planner, and reviewer advisor calls can brief the main agent before it edits. |
|
|
@@ -132,7 +134,7 @@ cd /path/to/your/project
|
|
|
132
134
|
patchpilot "find likely test gaps in this repo"
|
|
133
135
|
```
|
|
134
136
|
|
|
135
|
-
Use
|
|
137
|
+
Use bypass permissions only when you intentionally want PatchPilot to modify files or run commands without per-tool approval:
|
|
136
138
|
|
|
137
139
|
```bash
|
|
138
140
|
patchpilot "add tests for the parser" --apply --allow-shell
|
|
@@ -172,11 +174,11 @@ Useful slash commands inside the TUI:
|
|
|
172
174
|
| `/help <command>` | Explain one command, for example `/help think` or `/help model`. |
|
|
173
175
|
| `/onboarding` | Open guided provider/auth/model setup. |
|
|
174
176
|
| `/mode plan` | Read-only planning mode. |
|
|
175
|
-
| `/mode build` | Implementation mode; writes and shell
|
|
177
|
+
| `/mode build` | Implementation mode; writes, scripts, tests, and shell require per-tool approval. |
|
|
176
178
|
| `/think fixed\|adaptive` | Switch between fixed and adaptive step budgets. |
|
|
177
179
|
| `/reasoning none\|low\|medium\|high\|xhigh\|adaptive` | Set provider reasoning effort where supported. |
|
|
178
|
-
| `/write on\|off` |
|
|
179
|
-
| `/shell on\|off` |
|
|
180
|
+
| `/write on\|off` | Requests trusted bypass for direct writes, or returns to approval-gated build mode. |
|
|
181
|
+
| `/shell on\|off` | Requests trusted bypass for direct shell commands, or returns to approval-gated build mode. |
|
|
180
182
|
| `/agents on\|off` | Enable or disable advisor subagents. |
|
|
181
183
|
| `/provider ollama\|gemini\|openrouter\|nvidia\|codex` | Switch inference provider. |
|
|
182
184
|
| `/model <query>` | Search and switch the model for the current provider. |
|
|
@@ -234,9 +236,9 @@ PatchPilot caches model discovery for a short TTL inside the running TUI, so nor
|
|
|
234
236
|
|
|
235
237
|
PatchPilot reads provider cache telemetry when the provider reports it, for example Codex cached input tokens or OpenRouter `prompt_tokens_details.cached_tokens`, then displays cache hit rate as `cached / input`.
|
|
236
238
|
|
|
237
|
-
Reasoning support is provider and model dependent. Codex accepts fixed reasoning levels. OpenRouter receives
|
|
239
|
+
Reasoning support is provider and model dependent. Codex accepts fixed reasoning levels. OpenRouter receives `reasoning.effort` only for models whose metadata advertises reasoning support. Gemini uses Thinking configuration where the selected model exposes it; some Gemini models cannot disable thinking. Ollama only receives native `think` values for known thinking model families. NVIDIA reasoning effort is limited to supported GPT-OSS NIM routes.
|
|
238
240
|
|
|
239
|
-
OpenRouter `:free` models are rate-limited by OpenRouter. PatchPilot warns when a selected model ID ends in `:free
|
|
241
|
+
OpenRouter `:free` models are rate-limited by OpenRouter. PatchPilot warns when a selected model ID ends in `:free`, and OpenRouter credit or rate-limit failures are surfaced as explicit provider errors.
|
|
240
242
|
|
|
241
243
|
## Remote Ollama
|
|
242
244
|
|
|
@@ -277,9 +279,9 @@ PATCHPILOT_NUM_CTX=4096 PATCHPILOT_NUM_PREDICT=768 patchpilot
|
|
|
277
279
|
PatchPilot is designed to keep powerful actions boring and reviewable:
|
|
278
280
|
|
|
279
281
|
- File access is constrained to one workspace root.
|
|
280
|
-
- Secret-like files such as `.env`, `.npmrc`, SSH keys, and
|
|
282
|
+
- Secret-like files such as `.env`, `.envrc`, `.npmrc`, `.netrc`, SSH keys, PEM/key/cert bundles, and credential files are blocked from normal file tools.
|
|
281
283
|
- Writes are blocked by default; in the TUI, risky write tools request approval, and `--apply` keeps the legacy always-allow write path.
|
|
282
|
-
- Shell commands are blocked by default; dedicated script/test tools request approval
|
|
284
|
+
- Shell commands are blocked by default; dedicated script/test tools request approval and show the package script body before running. `--allow-shell` keeps the legacy always-allow shell path.
|
|
283
285
|
- Shell execution uses a restricted single-command runner.
|
|
284
286
|
- Provider config is stored in `~/.patchpilot/.env`, not in the current repository by default.
|
|
285
287
|
- Session logs are stored as append-only JSONL in `.patchpilot/sessions/`; that folder is gitignored. A global index in `~/.patchpilot/session-index.json` powers `patchpilot sessions` and `/resume`.
|
|
@@ -300,7 +302,7 @@ run tests
|
|
|
300
302
|
commit manually with git
|
|
301
303
|
```
|
|
302
304
|
|
|
303
|
-
PatchPilot now has approval prompts and a Git diff command, but it still does not replace human review. Inline rich diff review and commit/PR automation remain future work.
|
|
305
|
+
PatchPilot now has sticky approval prompts and a Git diff command, but it still does not replace human review. Inline rich diff review, real context resume, and commit/PR automation remain future work.
|
|
304
306
|
|
|
305
307
|
## Tech Stack
|
|
306
308
|
|
|
@@ -353,6 +355,7 @@ Release notes are kept in [docs/releases](docs/releases).
|
|
|
353
355
|
|
|
354
356
|
| Version | Notes |
|
|
355
357
|
|---|---|
|
|
358
|
+
| `v0.4.0` | [Release notes](docs/releases/v0.4.0.md) |
|
|
356
359
|
| `v0.3.1-beta` | [Release notes](docs/releases/v0.3.1-beta.md) |
|
|
357
360
|
| `v0.3.0` | [Release notes](docs/releases/v0.3.0.md) |
|
|
358
361
|
| `v0.2.1` | [Release notes](docs/releases/v0.2.1.md) |
|
package/SECURITY.md
CHANGED
|
@@ -17,4 +17,6 @@ Do not open a public issue for a vulnerability before the maintainer has had tim
|
|
|
17
17
|
|
|
18
18
|
## Security Model
|
|
19
19
|
|
|
20
|
-
PatchPilot keeps file tools inside one workspace root, blocks common secret files, and requires explicit
|
|
20
|
+
PatchPilot keeps file tools inside one workspace root, blocks common secret files and credential-like extensions, and requires approval or explicit trusted bypass for writes and shell commands. Package-script approvals include the resolved script body because scripts can hide publish, push, or destructive commands.
|
|
21
|
+
|
|
22
|
+
Session logs are stored in `.patchpilot/sessions/` under the workspace and summarized in `~/.patchpilot/session-index.json`. Treat those logs as local project metadata: they may contain prompts, tool names, summaries, and clipped command output. Do not use cloud providers or trusted bypass in repositories containing secrets you do not want processed by external model providers.
|
package/dist/core/gemini.js
CHANGED
|
@@ -44,20 +44,26 @@ export class GeminiClient {
|
|
|
44
44
|
}
|
|
45
45
|
async listModels() {
|
|
46
46
|
this.assertConfigured();
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
const models = [];
|
|
48
|
+
let pageToken = "";
|
|
49
|
+
do {
|
|
50
|
+
const response = await this.fetchGemini(`models?pageSize=1000${pageToken ? `&pageToken=${encodeURIComponent(pageToken)}` : ""}`, {
|
|
51
|
+
headers: {
|
|
52
|
+
"x-goog-api-key": this.apiKey
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const payload = (await readJsonSafely(response));
|
|
56
|
+
if (!response.ok || payload.error) {
|
|
57
|
+
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
58
|
+
throw new Error(`Gemini models failed with HTTP ${response.status}.${reason}`);
|
|
50
59
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
return (
|
|
58
|
-
?.filter((model) => model.supportedGenerationMethods?.includes("generateContent"))
|
|
59
|
-
.map((model) => stripModelPrefix(model.name))
|
|
60
|
-
.sort() ?? []);
|
|
60
|
+
models.push(...(payload.models
|
|
61
|
+
?.filter((model) => model.supportedGenerationMethods?.includes("generateContent"))
|
|
62
|
+
.map((model) => stripModelPrefix(model.name))
|
|
63
|
+
.filter(isLikelyGeminiAgentModel) ?? []));
|
|
64
|
+
pageToken = payload.nextPageToken ?? "";
|
|
65
|
+
} while (pageToken);
|
|
66
|
+
return [...new Set(models)].sort();
|
|
61
67
|
}
|
|
62
68
|
async fetchGemini(path, init) {
|
|
63
69
|
try {
|
|
@@ -135,7 +141,7 @@ function toTelemetry(payload, durationMs, model) {
|
|
|
135
141
|
const responseTokens = payload.usageMetadata?.candidatesTokenCount ?? 0;
|
|
136
142
|
const cachedPromptTokens = payload.usageMetadata?.cachedContentTokenCount ?? 0;
|
|
137
143
|
const thoughtsTokens = payload.usageMetadata?.thoughtsTokenCount ?? 0;
|
|
138
|
-
const totalTokens = payload.usageMetadata?.totalTokenCount ?? promptTokens + responseTokens;
|
|
144
|
+
const totalTokens = payload.usageMetadata?.totalTokenCount ?? promptTokens + responseTokens + thoughtsTokens;
|
|
139
145
|
return attachTokenCost({
|
|
140
146
|
promptTokens,
|
|
141
147
|
cachedPromptTokens,
|
|
@@ -149,6 +155,13 @@ function toTelemetry(payload, durationMs, model) {
|
|
|
149
155
|
tokenSource: "provider"
|
|
150
156
|
}, "gemini", model);
|
|
151
157
|
}
|
|
158
|
+
function isLikelyGeminiAgentModel(model) {
|
|
159
|
+
const normalizedModel = model.toLowerCase();
|
|
160
|
+
if (/(embedding|imagen|veo|tts|aqa|live|bidi|audio|speech)/.test(normalizedModel)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return normalizedModel.startsWith("gemini-");
|
|
164
|
+
}
|
|
152
165
|
async function readJsonSafely(response) {
|
|
153
166
|
try {
|
|
154
167
|
return await response.json();
|
package/dist/core/gemini.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/core/gemini.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AACrD,MAAM,CAAC,MAAM,oBAAoB,GAAG,kDAAkD,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/core/gemini.ts"],"names":[],"mappings":"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"}
|
package/dist/core/nvidia.js
CHANGED
|
@@ -35,6 +35,12 @@ export class NvidiaClient {
|
|
|
35
35
|
const payload = (await readJsonSafely(response));
|
|
36
36
|
if (!response.ok || payload.error) {
|
|
37
37
|
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
38
|
+
if (response.status === 401) {
|
|
39
|
+
throw new Error("NVIDIA authentication failed. Check NVIDIA_API_KEY.");
|
|
40
|
+
}
|
|
41
|
+
if (response.status === 429) {
|
|
42
|
+
throw new Error(`NVIDIA rate limit hit for model "${options.model}".${reason}`);
|
|
43
|
+
}
|
|
38
44
|
throw new Error(`NVIDIA chat failed for model "${options.model}": HTTP ${response.status}.${reason}`);
|
|
39
45
|
}
|
|
40
46
|
const content = payload.choices?.[0]?.message?.content?.trim() ?? "";
|
|
@@ -54,7 +60,12 @@ export class NvidiaClient {
|
|
|
54
60
|
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
55
61
|
throw new Error(`NVIDIA models failed with HTTP ${response.status}.${reason}`);
|
|
56
62
|
}
|
|
57
|
-
const models =
|
|
63
|
+
const models = [
|
|
64
|
+
...new Set(payload.data
|
|
65
|
+
?.map((model) => model.id?.trim())
|
|
66
|
+
.filter((model) => Boolean(model))
|
|
67
|
+
.filter(isLikelyNvidiaChatModel) ?? [])
|
|
68
|
+
].sort();
|
|
58
69
|
return models.length > 0 ? models : [defaultNvidiaModel];
|
|
59
70
|
}
|
|
60
71
|
async fetchNvidia(path, init) {
|
|
@@ -126,6 +137,13 @@ const agentResponseFormat = {
|
|
|
126
137
|
export function readNvidiaApiKey(env = process.env) {
|
|
127
138
|
return env.NVIDIA_API_KEY?.trim() || env.PATCHPILOT_NVIDIA_API_KEY?.trim() || "";
|
|
128
139
|
}
|
|
140
|
+
function isLikelyNvidiaChatModel(model) {
|
|
141
|
+
const normalizedModel = model.toLowerCase();
|
|
142
|
+
if (/(^|\/)(embed|rerank|rank|guard|safety|audio|asr|tts|ocr|vlm|vision|bge|nvlm|kosmos|phi-3-vision)/.test(normalizedModel)) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return /(llama|mistral|mixtral|nemotron|qwen|deepseek|gpt-oss|gemma|phi|granite)/.test(normalizedModel);
|
|
146
|
+
}
|
|
129
147
|
function readNvidiaRuntimeOptions(env = process.env) {
|
|
130
148
|
return {
|
|
131
149
|
maxTokens: readPositiveInteger(env.PATCHPILOT_NUM_PREDICT, 1024),
|
package/dist/core/nvidia.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nvidia.js","sourceRoot":"","sources":["../../src/core/nvidia.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"nvidia.js","sourceRoot":"","sources":["../../src/core/nvidia.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,8 @@ export declare class OpenRouterClient {
|
|
|
18
18
|
constructor(apiKey?: string, baseUrl?: string, runtimeOptions?: OpenRouterRuntimeOptions);
|
|
19
19
|
chat(options: ModelChatOptions): Promise<ModelChatResult>;
|
|
20
20
|
listModels(): Promise<string[]>;
|
|
21
|
+
private supportsJson;
|
|
22
|
+
private supportsReasoning;
|
|
21
23
|
private fetchOpenRouter;
|
|
22
24
|
private assertConfigured;
|
|
23
25
|
}
|
package/dist/core/openrouter.js
CHANGED
|
@@ -5,6 +5,7 @@ export const defaultOpenRouterModel = "openrouter/auto";
|
|
|
5
5
|
export const defaultOpenRouterBaseUrl = "https://openrouter.ai/api/v1";
|
|
6
6
|
const modelPricingCacheTtlMs = 15 * 60_000;
|
|
7
7
|
let modelPricingCache = null;
|
|
8
|
+
const modelCapabilityCache = new Map();
|
|
8
9
|
export class OpenRouterClient {
|
|
9
10
|
apiKey;
|
|
10
11
|
baseUrl;
|
|
@@ -25,20 +26,30 @@ export class OpenRouterClient {
|
|
|
25
26
|
"HTTP-Referer": "https://github.com/jx-grxf/PatchPilot",
|
|
26
27
|
"X-Title": "PatchPilot"
|
|
27
28
|
},
|
|
28
|
-
body: JSON.stringify({
|
|
29
|
+
body: JSON.stringify(cleanUndefined({
|
|
29
30
|
model: normalizeOpenRouterModel(options.model),
|
|
30
31
|
messages: options.messages,
|
|
31
32
|
max_tokens: this.runtimeOptions.maxTokens,
|
|
32
33
|
temperature: this.runtimeOptions.temperature,
|
|
33
|
-
reasoning: getOpenRouterReasoningConfig(options.reasoningEffort),
|
|
34
|
-
response_format: options.formatJson ? { type: "json_object" } : undefined
|
|
35
|
-
}),
|
|
34
|
+
reasoning: this.supportsReasoning(options.model) ? getOpenRouterReasoningConfig(options.reasoningEffort) : undefined,
|
|
35
|
+
response_format: options.formatJson && this.supportsJson(options.model) !== false ? { type: "json_object" } : undefined
|
|
36
|
+
})),
|
|
36
37
|
signal: options.signal
|
|
37
38
|
});
|
|
38
39
|
const durationMs = Date.now() - startedAt;
|
|
39
40
|
const payload = (await readJsonSafely(response));
|
|
40
41
|
if (!response.ok || payload.error) {
|
|
41
42
|
const reason = payload.error?.message ? ` ${payload.error.message}` : "";
|
|
43
|
+
if (response.status === 401) {
|
|
44
|
+
throw new Error(`OpenRouter authentication failed for model "${options.model}". Check OPENROUTER_API_KEY.`);
|
|
45
|
+
}
|
|
46
|
+
if (response.status === 402) {
|
|
47
|
+
throw new Error(`OpenRouter credit is exhausted for model "${options.model}". Add credits or use a free/cheaper route.${reason}`);
|
|
48
|
+
}
|
|
49
|
+
if (response.status === 429) {
|
|
50
|
+
const retryAfter = response.headers.get("retry-after");
|
|
51
|
+
throw new Error(`OpenRouter rate limit hit for model "${options.model}".${retryAfter ? ` Retry after ${retryAfter}s.` : ""}${reason}`);
|
|
52
|
+
}
|
|
42
53
|
throw new Error(`OpenRouter chat failed for model "${options.model}": HTTP ${response.status}.${reason}`);
|
|
43
54
|
}
|
|
44
55
|
const content = payload.choices?.[0]?.message?.content?.trim() ?? "";
|
|
@@ -52,7 +63,16 @@ export class OpenRouterClient {
|
|
|
52
63
|
}
|
|
53
64
|
async listModels() {
|
|
54
65
|
const models = await fetchOpenRouterModels(this.baseUrl);
|
|
55
|
-
|
|
66
|
+
for (const model of models) {
|
|
67
|
+
modelCapabilityCache.set(capabilityKey(this.baseUrl, model.id), readOpenRouterCapability(model));
|
|
68
|
+
}
|
|
69
|
+
return [defaultOpenRouterModel, ...models.filter(isAgentCompatibleOpenRouterModel).map((model) => model.id).sort()];
|
|
70
|
+
}
|
|
71
|
+
supportsJson(model) {
|
|
72
|
+
return modelCapabilityCache.get(capabilityKey(this.baseUrl, normalizeOpenRouterModel(model)))?.supportsJson ?? null;
|
|
73
|
+
}
|
|
74
|
+
supportsReasoning(model) {
|
|
75
|
+
return modelCapabilityCache.get(capabilityKey(this.baseUrl, normalizeOpenRouterModel(model)))?.supportsReasoning === true;
|
|
56
76
|
}
|
|
57
77
|
async fetchOpenRouter(path, init) {
|
|
58
78
|
try {
|
|
@@ -92,10 +112,11 @@ function normalizeOpenRouterModel(model) {
|
|
|
92
112
|
return trimmedModel;
|
|
93
113
|
}
|
|
94
114
|
async function readOpenRouterPricing() {
|
|
95
|
-
|
|
115
|
+
const baseUrl = process.env.PATCHPILOT_OPENROUTER_BASE_URL ?? defaultOpenRouterBaseUrl;
|
|
116
|
+
if (modelPricingCache && modelPricingCache.baseUrl === baseUrl && modelPricingCache.expiresAt > Date.now()) {
|
|
96
117
|
return modelPricingCache.rates;
|
|
97
118
|
}
|
|
98
|
-
const models = await fetchOpenRouterModels(
|
|
119
|
+
const models = await fetchOpenRouterModels(baseUrl).catch(() => []);
|
|
99
120
|
const rates = new Map();
|
|
100
121
|
for (const model of models) {
|
|
101
122
|
rates.set(model.id, {
|
|
@@ -106,6 +127,7 @@ async function readOpenRouterPricing() {
|
|
|
106
127
|
});
|
|
107
128
|
}
|
|
108
129
|
modelPricingCache = {
|
|
130
|
+
baseUrl,
|
|
109
131
|
expiresAt: Date.now() + modelPricingCacheTtlMs,
|
|
110
132
|
rates
|
|
111
133
|
};
|
|
@@ -124,6 +146,28 @@ async function fetchOpenRouterModels(baseUrl) {
|
|
|
124
146
|
}
|
|
125
147
|
return payload.data ?? [];
|
|
126
148
|
}
|
|
149
|
+
function readOpenRouterCapability(model) {
|
|
150
|
+
if (!Array.isArray(model.supported_parameters)) {
|
|
151
|
+
return {
|
|
152
|
+
supportsJson: null,
|
|
153
|
+
supportsReasoning: null
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
supportsJson: model.supported_parameters.includes("response_format"),
|
|
158
|
+
supportsReasoning: model.supported_parameters.includes("reasoning")
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function isAgentCompatibleOpenRouterModel(model) {
|
|
162
|
+
const capability = readOpenRouterCapability(model);
|
|
163
|
+
return capability.supportsJson !== false;
|
|
164
|
+
}
|
|
165
|
+
function capabilityKey(baseUrl, model) {
|
|
166
|
+
return `${baseUrl.replace(/\/$/, "")}:${normalizeOpenRouterModel(model)}`;
|
|
167
|
+
}
|
|
168
|
+
function cleanUndefined(value) {
|
|
169
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
|
|
170
|
+
}
|
|
127
171
|
async function toTelemetry(payload, durationMs, model) {
|
|
128
172
|
const promptTokens = payload.usage?.prompt_tokens ?? 0;
|
|
129
173
|
const responseTokens = payload.usage?.completion_tokens ?? 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/core/openrouter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/core/openrouter.ts"],"names":[],"mappings":"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"}
|
package/dist/core/workspace.js
CHANGED
|
@@ -61,11 +61,16 @@ const blockedPathNames = new Set([
|
|
|
61
61
|
".env.development",
|
|
62
62
|
".env.production",
|
|
63
63
|
".env.test",
|
|
64
|
+
".envrc",
|
|
64
65
|
".npmrc",
|
|
65
66
|
".pypirc",
|
|
66
67
|
".netrc",
|
|
68
|
+
"credentials.json",
|
|
69
|
+
"secrets.json",
|
|
67
70
|
"id_rsa",
|
|
68
71
|
"id_ed25519",
|
|
72
|
+
"id_ecdsa",
|
|
73
|
+
"id_dsa",
|
|
69
74
|
"known_hosts"
|
|
70
75
|
]);
|
|
71
76
|
export const toolSpecs = {
|
|
@@ -574,10 +579,12 @@ export class WorkspaceTools {
|
|
|
574
579
|
if (!scripts[normalizedScript]) {
|
|
575
580
|
return denied(`package script not found: ${normalizedScript}`, "run_script");
|
|
576
581
|
}
|
|
582
|
+
const scriptCommand = scripts[normalizedScript];
|
|
577
583
|
if (!this.allowShell) {
|
|
578
584
|
const approval = await this.requestApproval("run_script", "shell", {
|
|
579
|
-
script: normalizedScript
|
|
580
|
-
|
|
585
|
+
script: normalizedScript,
|
|
586
|
+
command: scriptCommand
|
|
587
|
+
}, previewPackageScript(normalizedScript, scriptCommand));
|
|
581
588
|
if (approval.decision === "deny") {
|
|
582
589
|
return denied("run_script denied by permission policy.", "run_script", approval);
|
|
583
590
|
}
|
|
@@ -589,7 +596,7 @@ export class WorkspaceTools {
|
|
|
589
596
|
content: clip(output.output, 20_000),
|
|
590
597
|
tool: "run_script",
|
|
591
598
|
category: toolSpecs.run_script.category,
|
|
592
|
-
preview:
|
|
599
|
+
preview: previewPackageScript(normalizedScript, scriptCommand)
|
|
593
600
|
};
|
|
594
601
|
}
|
|
595
602
|
async runTests() {
|
|
@@ -839,7 +846,7 @@ async function findNearestExistingParent(absolutePath) {
|
|
|
839
846
|
function runCommand(command, cwd, timeoutMs, signal) {
|
|
840
847
|
const isWindows = platform() === "win32";
|
|
841
848
|
const shellExecutable = isWindows ? "powershell.exe" : "bash";
|
|
842
|
-
const shellArgs = isWindows ? ["-NoProfile", "-Command", command] : ["-lc", command];
|
|
849
|
+
const shellArgs = isWindows ? ["-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", command] : ["-lc", command];
|
|
843
850
|
return new Promise((resolve) => {
|
|
844
851
|
const child = spawn(shellExecutable, shellArgs, {
|
|
845
852
|
cwd,
|
|
@@ -927,7 +934,16 @@ function isSensitivePath(value) {
|
|
|
927
934
|
return normalizedPath
|
|
928
935
|
.split("/")
|
|
929
936
|
.filter(Boolean)
|
|
930
|
-
.some((part) =>
|
|
937
|
+
.some((part) => {
|
|
938
|
+
const normalizedPart = part.toLowerCase();
|
|
939
|
+
return (blockedPathNames.has(normalizedPart) ||
|
|
940
|
+
normalizedPart.endsWith(".pem") ||
|
|
941
|
+
normalizedPart.endsWith(".key") ||
|
|
942
|
+
normalizedPart.endsWith(".p12") ||
|
|
943
|
+
normalizedPart.endsWith(".pfx") ||
|
|
944
|
+
normalizedPart.startsWith("secrets.") ||
|
|
945
|
+
normalizedPart.includes("credentials"));
|
|
946
|
+
});
|
|
931
947
|
}
|
|
932
948
|
function denied(message, tool, approval) {
|
|
933
949
|
return {
|
|
@@ -1092,6 +1108,11 @@ function validateShellCommand(command) {
|
|
|
1092
1108
|
}
|
|
1093
1109
|
return null;
|
|
1094
1110
|
}
|
|
1111
|
+
function previewPackageScript(name, command) {
|
|
1112
|
+
const risk = validateShellCommand(command);
|
|
1113
|
+
const prefix = risk ? `Risky package script (${risk})` : "Run package script";
|
|
1114
|
+
return `${prefix}: npm run ${name} -> ${clip(command, 220)}`;
|
|
1115
|
+
}
|
|
1095
1116
|
function stripQuotes(value) {
|
|
1096
1117
|
return value.replace(/^['"]|['"]$/g, "");
|
|
1097
1118
|
}
|