@blockrun/runcode 2.2.5 → 2.2.7
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/llm.d.ts +2 -0
- package/dist/agent/llm.js +7 -2
- package/dist/agent/loop.js +3 -1
- package/dist/agent/optimize.js +4 -1
- package/dist/config.js +1 -1
- package/dist/index.js +1 -1
- package/dist/proxy/server.js +20 -9
- package/dist/tools/grep.js +6 -2
- package/dist/tools/webfetch.js +2 -0
- package/package.json +1 -1
package/dist/agent/llm.d.ts
CHANGED
|
@@ -34,6 +34,8 @@ export declare class ModelClient {
|
|
|
34
34
|
private walletAddress;
|
|
35
35
|
private cachedBaseWallet;
|
|
36
36
|
private cachedSolanaWallet;
|
|
37
|
+
private walletCacheTime;
|
|
38
|
+
private static WALLET_CACHE_TTL;
|
|
37
39
|
constructor(opts: LLMClientOptions);
|
|
38
40
|
/**
|
|
39
41
|
* Stream a completion from the BlockRun API.
|
package/dist/agent/llm.js
CHANGED
|
@@ -13,6 +13,8 @@ export class ModelClient {
|
|
|
13
13
|
walletAddress = '';
|
|
14
14
|
cachedBaseWallet = null;
|
|
15
15
|
cachedSolanaWallet = null;
|
|
16
|
+
walletCacheTime = 0;
|
|
17
|
+
static WALLET_CACHE_TTL = 30 * 60 * 1000; // 30 min TTL
|
|
16
18
|
constructor(opts) {
|
|
17
19
|
this.apiUrl = opts.apiUrl;
|
|
18
20
|
this.chain = opts.chain;
|
|
@@ -219,8 +221,10 @@ export class ModelClient {
|
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
223
|
async signBasePayment(response) {
|
|
222
|
-
|
|
224
|
+
// Refresh wallet cache after TTL to pick up balance/key changes
|
|
225
|
+
if (!this.cachedBaseWallet || (Date.now() - this.walletCacheTime > ModelClient.WALLET_CACHE_TTL)) {
|
|
223
226
|
const w = getOrCreateWallet();
|
|
227
|
+
this.walletCacheTime = Date.now();
|
|
224
228
|
this.cachedBaseWallet = { privateKey: w.privateKey, address: w.address };
|
|
225
229
|
}
|
|
226
230
|
const wallet = this.cachedBaseWallet;
|
|
@@ -240,8 +244,9 @@ export class ModelClient {
|
|
|
240
244
|
return { 'PAYMENT-SIGNATURE': payload };
|
|
241
245
|
}
|
|
242
246
|
async signSolanaPayment(response) {
|
|
243
|
-
if (!this.cachedSolanaWallet) {
|
|
247
|
+
if (!this.cachedSolanaWallet || (Date.now() - this.walletCacheTime > ModelClient.WALLET_CACHE_TTL)) {
|
|
244
248
|
const w = await getOrCreateSolanaWallet();
|
|
249
|
+
this.walletCacheTime = Date.now();
|
|
245
250
|
this.cachedSolanaWallet = { privateKey: w.privateKey, address: w.address };
|
|
246
251
|
}
|
|
247
252
|
const wallet = this.cachedSolanaWallet;
|
package/dist/agent/loop.js
CHANGED
|
@@ -238,7 +238,7 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
238
238
|
let loopCount = 0;
|
|
239
239
|
let recoveryAttempts = 0;
|
|
240
240
|
let maxTokensOverride;
|
|
241
|
-
|
|
241
|
+
let lastActivity = Date.now();
|
|
242
242
|
// Agent loop for this user message
|
|
243
243
|
while (loopCount < maxTurns) {
|
|
244
244
|
loopCount++;
|
|
@@ -418,6 +418,8 @@ export async function interactiveSession(config, getUserInput, onEvent, onAbortR
|
|
|
418
418
|
for (const [inv, result] of results) {
|
|
419
419
|
onEvent({ kind: 'capability_done', id: inv.id, result });
|
|
420
420
|
}
|
|
421
|
+
// Refresh activity timestamp after tool execution
|
|
422
|
+
lastActivity = Date.now();
|
|
421
423
|
// Append outcomes
|
|
422
424
|
const outcomeContent = results.map(([inv, result]) => ({
|
|
423
425
|
type: 'tool_result',
|
package/dist/agent/optimize.js
CHANGED
|
@@ -129,7 +129,10 @@ export function timeBasedCleanup(history, lastActivityTimestamp) {
|
|
|
129
129
|
if (!lastActivityTimestamp) {
|
|
130
130
|
return { history, cleaned: false };
|
|
131
131
|
}
|
|
132
|
-
const
|
|
132
|
+
const gapMs = Date.now() - lastActivityTimestamp;
|
|
133
|
+
if (gapMs < 0)
|
|
134
|
+
return { history, cleaned: false }; // Clock skew protection
|
|
135
|
+
const gapMinutes = gapMs / 60_000;
|
|
133
136
|
if (gapMinutes < IDLE_GAP_THRESHOLD_MINUTES) {
|
|
134
137
|
return { history, cleaned: false };
|
|
135
138
|
}
|
package/dist/config.js
CHANGED
|
@@ -3,7 +3,7 @@ import os from 'node:os';
|
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
let _version = '
|
|
6
|
+
let _version = '2.0.0';
|
|
7
7
|
try {
|
|
8
8
|
const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf-8'));
|
|
9
9
|
_version = pkg.version || _version;
|
package/dist/index.js
CHANGED
|
@@ -109,7 +109,7 @@ if (firstArg === 'solana' || firstArg === 'base') {
|
|
|
109
109
|
}
|
|
110
110
|
await startCommand(startOpts);
|
|
111
111
|
}
|
|
112
|
-
else if (!firstArg || (firstArg.startsWith('-') &&
|
|
112
|
+
else if (!firstArg || (firstArg.startsWith('-') && !['-h', '--help', '-V', '--version'].includes(firstArg))) {
|
|
113
113
|
// No subcommand or only flags — treat as 'start' with flags
|
|
114
114
|
const startOpts = { version };
|
|
115
115
|
for (let i = 0; i < args.length; i++) {
|
package/dist/proxy/server.js
CHANGED
|
@@ -394,16 +394,27 @@ export function createProxy(options) {
|
|
|
394
394
|
if (done) {
|
|
395
395
|
// Record stats from streaming response
|
|
396
396
|
if (isStreaming && fullResponse) {
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
397
|
+
// Extract token usage from SSE stream by parsing message_delta events
|
|
398
|
+
let outputTokens = 0;
|
|
399
|
+
let inputTokens = 0;
|
|
400
|
+
// Find all data: lines and parse JSON to extract usage
|
|
401
|
+
for (const line of fullResponse.split('\n')) {
|
|
402
|
+
if (!line.startsWith('data: '))
|
|
403
|
+
continue;
|
|
404
|
+
const json = line.slice(6).trim();
|
|
405
|
+
if (json === '[DONE]')
|
|
406
|
+
continue;
|
|
407
|
+
try {
|
|
408
|
+
const parsed = JSON.parse(json);
|
|
409
|
+
if (parsed.usage?.output_tokens)
|
|
410
|
+
outputTokens = parsed.usage.output_tokens;
|
|
411
|
+
if (parsed.usage?.input_tokens)
|
|
412
|
+
inputTokens = parsed.usage.input_tokens;
|
|
413
|
+
}
|
|
414
|
+
catch { /* skip malformed */ }
|
|
415
|
+
}
|
|
416
|
+
if (outputTokens > 0) {
|
|
403
417
|
trackOutputTokens(finalModel, outputTokens);
|
|
404
|
-
const inputTokens = inputMatch
|
|
405
|
-
? parseInt(inputMatch[1], 10)
|
|
406
|
-
: 0;
|
|
407
418
|
const latencyMs = Date.now() - requestStartTime;
|
|
408
419
|
const cost = estimateCost(finalModel, inputTokens, outputTokens);
|
|
409
420
|
recordUsage(finalModel, inputTokens, outputTokens, cost, latencyMs, usedFallback);
|
package/dist/tools/grep.js
CHANGED
|
@@ -105,8 +105,12 @@ function runNativeGrep(opts, searchPath, mode, limit) {
|
|
|
105
105
|
break;
|
|
106
106
|
}
|
|
107
107
|
if (opts.glob) {
|
|
108
|
-
// Native grep doesn't support
|
|
109
|
-
|
|
108
|
+
// Native grep --include doesn't support ** or path separators
|
|
109
|
+
// Extract file extension pattern for best compatibility
|
|
110
|
+
const nativeGlob = opts.glob
|
|
111
|
+
.replace(/^\*\*\//, '') // Strip leading **/
|
|
112
|
+
.replace(/^.*\//, '') // Strip path prefix (src/ etc.)
|
|
113
|
+
.replace(/\*\*/, '*'); // Convert ** to * for flat matching
|
|
110
114
|
args.push(`--include=${nativeGlob}`);
|
|
111
115
|
}
|
|
112
116
|
args.push('--exclude-dir=node_modules', '--exclude-dir=.git', '--exclude-dir=dist');
|
package/dist/tools/webfetch.js
CHANGED
|
@@ -97,6 +97,8 @@ function stripHtml(html) {
|
|
|
97
97
|
.replace(/<footer[^>]*>[\s\S]*?<\/footer>/gi, '')
|
|
98
98
|
.replace(/<aside[^>]*>[\s\S]*?<\/aside>/gi, '')
|
|
99
99
|
.replace(/<noscript[^>]*>[\s\S]*?<\/noscript>/gi, '')
|
|
100
|
+
.replace(/<svg[^>]*>[\s\S]*?<\/svg>/gi, '')
|
|
101
|
+
.replace(/<form[^>]*>[\s\S]*?<\/form>/gi, '')
|
|
100
102
|
// Convert block elements to newlines for readability
|
|
101
103
|
.replace(/<\/?(p|div|h[1-6]|li|br|tr)[^>]*>/gi, '\n')
|
|
102
104
|
// Strip remaining tags
|