@blockrun/runcode 2.5.1 → 2.5.2
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/agent/commands.js +3 -1
- package/dist/agent/llm.js +8 -1
- package/dist/agent/loop.js +8 -5
- package/dist/agent/permissions.js +9 -2
- package/dist/commands/start.js +3 -1
- package/package.json +1 -1
package/dist/agent/commands.js
CHANGED
|
@@ -179,7 +179,9 @@ const DIRECT_COMMANDS = {
|
|
|
179
179
|
catch {
|
|
180
180
|
checks.push('⚠ ripgrep not found (using native grep fallback)');
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
const hasWallet = fs.existsSync(path.join(BLOCKRUN_DIR, 'wallet.json'))
|
|
183
|
+
|| fs.existsSync(path.join(BLOCKRUN_DIR, 'solana-wallet.json'));
|
|
184
|
+
checks.push(hasWallet ? '✓ wallet configured' : '⚠ no wallet — run: runcode setup');
|
|
183
185
|
checks.push(fs.existsSync(path.join(BLOCKRUN_DIR, 'runcode-config.json')) ? '✓ config file exists' : '⚠ no config — using defaults');
|
|
184
186
|
// Check MCP
|
|
185
187
|
const { listMcpServers } = await import('../mcp/client.js');
|
package/dist/agent/llm.js
CHANGED
|
@@ -64,9 +64,16 @@ export class ModelClient {
|
|
|
64
64
|
}
|
|
65
65
|
if (!response.ok) {
|
|
66
66
|
const errorBody = await response.text().catch(() => 'unknown error');
|
|
67
|
+
// Extract human-readable message from JSON error bodies ({"error":{"message":"..."}})
|
|
68
|
+
let message = errorBody;
|
|
69
|
+
try {
|
|
70
|
+
const parsed = JSON.parse(errorBody);
|
|
71
|
+
message = parsed?.error?.message || parsed?.message || errorBody;
|
|
72
|
+
}
|
|
73
|
+
catch { /* not JSON — use raw text */ }
|
|
67
74
|
yield {
|
|
68
75
|
kind: 'error',
|
|
69
|
-
payload: { status: response.status, message
|
|
76
|
+
payload: { status: response.status, message },
|
|
70
77
|
};
|
|
71
78
|
return;
|
|
72
79
|
}
|
package/dist/agent/loop.js
CHANGED
|
@@ -396,18 +396,21 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
396
396
|
onEvent({ kind: 'turn_done', reason: 'error', error: errMsg + suggestion });
|
|
397
397
|
break;
|
|
398
398
|
}
|
|
399
|
+
// When API doesn't return input tokens (some models return 0), estimate from history
|
|
400
|
+
const inputTokens = usage.inputTokens > 0
|
|
401
|
+
? usage.inputTokens
|
|
402
|
+
: estimateHistoryTokens(history);
|
|
399
403
|
// Anchor token tracking to actual API counts
|
|
400
|
-
updateActualTokens(
|
|
404
|
+
updateActualTokens(inputTokens, usage.outputTokens, history.length);
|
|
401
405
|
onEvent({
|
|
402
406
|
kind: 'usage',
|
|
403
|
-
inputTokens
|
|
407
|
+
inputTokens,
|
|
404
408
|
outputTokens: usage.outputTokens,
|
|
405
409
|
model: config.model,
|
|
406
410
|
});
|
|
407
411
|
// Record usage for stats tracking (runcode stats command)
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
recordUsage(config.model, usage.inputTokens, usage.outputTokens, costEstimate, 0);
|
|
412
|
+
const costEstimate = estimateCost(config.model, inputTokens, usage.outputTokens);
|
|
413
|
+
recordUsage(config.model, inputTokens, usage.outputTokens, costEstimate, 0);
|
|
411
414
|
// ── Max output tokens recovery ──
|
|
412
415
|
if (stopReason === 'max_tokens' && recoveryAttempts < 3) {
|
|
413
416
|
recoveryAttempts++;
|
|
@@ -177,10 +177,17 @@ export class PermissionManager {
|
|
|
177
177
|
}
|
|
178
178
|
// ─── Helpers ───────────────────────────────────────────────────────────────
|
|
179
179
|
function askQuestion(prompt) {
|
|
180
|
+
// Non-TTY (piped/scripted) input: cannot ask interactively — auto-allow.
|
|
181
|
+
// The caller (permissionMode logic in start.ts) already routes piped sessions
|
|
182
|
+
// to trust mode, so this path is rarely hit. Guard here for safety.
|
|
183
|
+
if (!process.stdin.isTTY) {
|
|
184
|
+
process.stderr.write(prompt + 'y (auto-approved: non-interactive mode)\n');
|
|
185
|
+
return Promise.resolve('y');
|
|
186
|
+
}
|
|
180
187
|
const rl = readline.createInterface({
|
|
181
188
|
input: process.stdin,
|
|
182
189
|
output: process.stderr,
|
|
183
|
-
terminal:
|
|
190
|
+
terminal: true,
|
|
184
191
|
});
|
|
185
192
|
return new Promise((resolve) => {
|
|
186
193
|
let answered = false;
|
|
@@ -191,7 +198,7 @@ function askQuestion(prompt) {
|
|
|
191
198
|
});
|
|
192
199
|
rl.on('close', () => {
|
|
193
200
|
if (!answered)
|
|
194
|
-
resolve('n'); // Default deny on EOF
|
|
201
|
+
resolve('n'); // Default deny on EOF for safety
|
|
195
202
|
});
|
|
196
203
|
});
|
|
197
204
|
}
|
package/dist/commands/start.js
CHANGED
|
@@ -123,7 +123,9 @@ export async function startCommand(options) {
|
|
|
123
123
|
capabilities,
|
|
124
124
|
maxTurns: 100,
|
|
125
125
|
workingDir: workDir,
|
|
126
|
-
|
|
126
|
+
// Non-TTY (piped) input = scripted mode → trust all tools automatically.
|
|
127
|
+
// Interactive TTY = default mode (prompts for Bash/Write/Edit).
|
|
128
|
+
permissionMode: (options.trust || !process.stdin.isTTY) ? 'trust' : 'default',
|
|
127
129
|
debug: options.debug,
|
|
128
130
|
};
|
|
129
131
|
// Use ink UI if TTY, fallback to basic readline for piped input
|