@blockrun/franklin 3.6.14 → 3.6.15

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.
@@ -72,22 +72,12 @@ export async function startCommand(options) {
72
72
  }
73
73
  printBanner(version);
74
74
  const workDir = process.cwd();
75
- // Show session info immediately, fetch balance in background
76
- // Model is shown in the live status bar no static line needed.
77
- console.log(chalk.dim(` Wallet: ${walletAddress || 'not set'}`));
78
- console.log(chalk.dim(` Dir: ${workDir}`));
79
- // First-run tip: show if no config file exists yet
80
- if (!configModel && !options.model) {
81
- console.log(chalk.dim(`\n Tip: /model to switch models · /compact to save tokens · /help for all commands`));
82
- }
83
- // Welcome message — show things Hermes/OpenClaw can't do.
84
- // Only on first run or when no model is configured (new user indicator).
85
- // After the user's first session, the tip fades and they go straight to the prompt.
86
- console.log('');
87
- console.log(chalk.dim(' Try something only Franklin can do:'));
88
- console.log(chalk.dim(' ') + chalk.hex('#FFD700')('"what\'s BTC looking like today?"') + chalk.dim(' ← live market data'));
89
- console.log(chalk.dim(' ') + chalk.hex('#60A5FA')('"generate a logo for my startup"') + chalk.dim(' ← AI image gen'));
90
- console.log(chalk.dim(' Code with 55+ models. No API keys. Pay per use.'));
75
+ // Session info — aligned, minimal. Model + balance live in the input bar below.
76
+ const short = (s) => s.length > 14 ? s.slice(0, 6) + '...' + s.slice(-4) : s;
77
+ console.log(chalk.dim(' Wallet: ') + (walletAddress ? short(walletAddress) : chalk.yellow('not set')));
78
+ console.log(chalk.dim(' Dir: ') + workDir);
79
+ console.log(chalk.dim(' Dashboard: ') + chalk.cyan('franklin panel') + chalk.dim(' http://localhost:3100'));
80
+ console.log(chalk.dim(' Help: ') + chalk.cyan('/help'));
91
81
  console.log('');
92
82
  // Balance fetcher — used at startup and after each turn
93
83
  const fetchBalance = async () => {
@@ -8,11 +8,29 @@ let registeredApiUrl = '';
8
8
  let registeredChain = 'base';
9
9
  let registeredParentModel = '';
10
10
  let registeredCapabilities = [];
11
+ // Heuristic: which model IDs are free?
12
+ function isFreeModel(m) {
13
+ return m.startsWith('nvidia/') || m === 'blockrun/free' || m === '';
14
+ }
11
15
  async function execute(input, ctx) {
12
16
  const { prompt, description, model } = input;
13
17
  if (!prompt) {
14
18
  return { output: 'Error: prompt is required', isError: true };
15
19
  }
20
+ // Resolve which model the sub-agent will actually run on
21
+ const subModel = model || registeredParentModel || 'nvidia/nemotron-ultra-253b';
22
+ // Cost gate: if parent is free but sub-agent wants paid, ask user first.
23
+ // Prevents silent charges when the agent decides to spawn a more capable sub-agent.
24
+ if (isFreeModel(registeredParentModel) && !isFreeModel(subModel) && ctx.onAskUser) {
25
+ const shortLabel = subModel.split('/').pop() || subModel;
26
+ const answer = await ctx.onAskUser(`Sub-agent wants to use ${shortLabel} (paid). Approve?`, ['y', 'n']);
27
+ if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
28
+ return {
29
+ output: `Sub-agent skipped — user declined paid model (${shortLabel}). Retry with a free model like nemotron.`,
30
+ isError: true,
31
+ };
32
+ }
33
+ }
16
34
  const client = new ModelClient({
17
35
  apiUrl: registeredApiUrl,
18
36
  chain: registeredChain,
@@ -55,9 +73,7 @@ async function execute(input, ctx) {
55
73
  }
56
74
  turn++;
57
75
  const { content: parts } = await client.complete({
58
- // Inherit parent model by default. If parent is on a free model, subagent stays free.
59
- // User can explicitly pass `model` to override.
60
- model: model || registeredParentModel || 'nvidia/nemotron-ultra-253b',
76
+ model: subModel,
61
77
  messages: history,
62
78
  system: systemPrompt,
63
79
  tools: toolDefs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/franklin",
3
- "version": "3.6.14",
3
+ "version": "3.6.15",
4
4
  "description": "Franklin — The AI agent with a wallet. Spends USDC autonomously to get real work done. Pay per action, no subscriptions.",
5
5
  "type": "module",
6
6
  "exports": {