@blockrun/cc 0.6.2 → 0.7.1

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.
@@ -2,6 +2,7 @@ interface StartOptions {
2
2
  port?: string;
3
3
  model?: string;
4
4
  launch?: boolean;
5
+ debug?: boolean;
5
6
  }
6
7
  export declare function startCommand(options: StartOptions): Promise<void>;
7
8
  export {};
@@ -25,7 +25,7 @@ export async function startCommand(options) {
25
25
  console.log(`Model: ${chalk.green(model)}`);
26
26
  console.log(`Proxy: ${chalk.cyan(`http://localhost:${port}`)}`);
27
27
  console.log(`Backend: ${chalk.dim(apiUrl)}\n`);
28
- const server = createProxy({ port, apiUrl, chain: 'solana', modelOverride: model });
28
+ const server = createProxy({ port, apiUrl, chain: 'solana', modelOverride: model, debug: options.debug });
29
29
  launchServer(server, port, shouldLaunch, model);
30
30
  }
31
31
  else {
@@ -46,7 +46,7 @@ export async function startCommand(options) {
46
46
  console.log(`Model: ${chalk.green(model)}`);
47
47
  console.log(`Proxy: ${chalk.cyan(`http://localhost:${port}`)}`);
48
48
  console.log(`Backend: ${chalk.dim(apiUrl)}\n`);
49
- const server = createProxy({ port, apiUrl, chain: 'base', modelOverride: model });
49
+ const server = createProxy({ port, apiUrl, chain: 'base', modelOverride: model, debug: options.debug });
50
50
  launchServer(server, port, shouldLaunch, model);
51
51
  }
52
52
  }
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ program
21
21
  .option('-p, --port <port>', 'Proxy port', '8402')
22
22
  .option('-m, --model <model>', 'Default model (e.g. openai/gpt-5.4, anthropic/claude-sonnet-4.6)')
23
23
  .option('--no-launch', 'Start proxy only, do not launch Claude Code')
24
+ .option('--debug', 'Enable debug logging')
24
25
  .action(startCommand);
25
26
  program
26
27
  .command('models')
@@ -5,6 +5,7 @@ export interface ProxyOptions {
5
5
  apiUrl: string;
6
6
  chain?: Chain;
7
7
  modelOverride?: string;
8
+ debug?: boolean;
8
9
  }
9
10
  export declare function createProxy(options: ProxyOptions): http.Server;
10
11
  type RequestCategory = 'simple' | 'code' | 'default';
@@ -1,5 +1,11 @@
1
1
  import http from 'node:http';
2
2
  import { getOrCreateWallet, getOrCreateSolanaWallet, createPaymentPayload, createSolanaPaymentPayload, parsePaymentRequired, extractPaymentDetails, solanaKeyToBytes, SOLANA_NETWORK, } from '@blockrun/llm';
3
+ function debug(options, ...args) {
4
+ if (options.debug)
5
+ console.log('[brcc]', ...args);
6
+ }
7
+ const DEFAULT_MAX_TOKENS = 4096;
8
+ let lastOutputTokens = 0;
3
9
  export function createProxy(options) {
4
10
  const chain = options.chain || 'base';
5
11
  let baseWallet = null;
@@ -36,12 +42,17 @@ export function createProxy(options) {
36
42
  parsed.model = options.modelOverride;
37
43
  }
38
44
  if (parsed.max_tokens) {
45
+ const original = parsed.max_tokens;
39
46
  const model = (parsed.model || '').toLowerCase();
40
- if (model.includes('deepseek') || model.includes('haiku') || model.includes('gpt-oss')) {
41
- parsed.max_tokens = Math.min(parsed.max_tokens, 8192);
47
+ const modelCap = (model.includes('deepseek') || model.includes('haiku') || model.includes('gpt-oss')) ? 8192 : 16384;
48
+ if (lastOutputTokens > 0) {
49
+ parsed.max_tokens = Math.min(lastOutputTokens, modelCap);
42
50
  }
43
51
  else {
44
- parsed.max_tokens = Math.min(parsed.max_tokens, 16384);
52
+ parsed.max_tokens = Math.min(parsed.max_tokens, DEFAULT_MAX_TOKENS, modelCap);
53
+ }
54
+ if (original !== parsed.max_tokens) {
55
+ debug(options, `max_tokens: ${original} → ${parsed.max_tokens} (last output: ${lastOutputTokens || 'none'})`);
45
56
  }
46
57
  }
47
58
  body = JSON.stringify(parsed);
@@ -76,22 +87,44 @@ export function createProxy(options) {
76
87
  responseHeaders[k] = v;
77
88
  });
78
89
  res.writeHead(response.status, responseHeaders);
90
+ const isStreaming = responseHeaders['content-type']?.includes('text/event-stream');
79
91
  if (response.body) {
80
92
  const reader = response.body.getReader();
93
+ const decoder = new TextDecoder();
94
+ let lastChunkText = '';
81
95
  const pump = async () => {
82
96
  while (true) {
83
97
  const { done, value } = await reader.read();
84
98
  if (done) {
99
+ if (isStreaming && lastChunkText) {
100
+ const match = lastChunkText.match(/"output_tokens"\s*:\s*(\d+)/);
101
+ if (match) {
102
+ lastOutputTokens = parseInt(match[1], 10);
103
+ debug(options, `recorded output_tokens: ${lastOutputTokens} (stream)`);
104
+ }
105
+ }
85
106
  res.end();
86
107
  break;
87
108
  }
109
+ if (isStreaming) {
110
+ lastChunkText = decoder.decode(value, { stream: true });
111
+ }
88
112
  res.write(value);
89
113
  }
90
114
  };
91
115
  pump().catch(() => res.end());
92
116
  }
93
117
  else {
94
- res.end(await response.text());
118
+ const text = await response.text();
119
+ try {
120
+ const parsed = JSON.parse(text);
121
+ if (parsed.usage?.output_tokens) {
122
+ lastOutputTokens = parsed.usage.output_tokens;
123
+ debug(options, `recorded output_tokens: ${lastOutputTokens}`);
124
+ }
125
+ }
126
+ catch { /* not JSON */ }
127
+ res.end(text);
95
128
  }
96
129
  }
97
130
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/cc",
3
- "version": "0.6.2",
3
+ "version": "0.7.1",
4
4
  "description": "Run Claude Code with any model — no rate limits, no account locks, no phone verification. Pay per use with USDC.",
5
5
  "type": "module",
6
6
  "bin": {