@blockrun/franklin 3.6.13 → 3.6.14

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.
@@ -367,8 +367,14 @@ function formatCompactSummary(raw) {
367
367
  }
368
368
  /**
369
369
  * Pick a cheaper/faster model for compaction to save cost.
370
+ * If the primary model is free (NVIDIA), compaction also stays free
371
+ * so users don't get silent charges when their context fills up.
370
372
  */
371
373
  function pickCompactionModel(primaryModel) {
374
+ // Free parent → free compaction (no silent charge)
375
+ if (primaryModel.startsWith('nvidia/') || primaryModel === 'blockrun/free') {
376
+ return 'nvidia/nemotron-ultra-253b';
377
+ }
372
378
  // Use cheapest capable model for summarization to save cost
373
379
  // Tier down: opus/pro → sonnet, sonnet → haiku, everything else → flash (cheapest capable)
374
380
  if (primaryModel.includes('opus') || primaryModel.includes('pro')) {
@@ -380,7 +386,7 @@ function pickCompactionModel(primaryModel) {
380
386
  if (primaryModel.includes('haiku') || primaryModel.includes('mini') || primaryModel.includes('nano')) {
381
387
  return 'google/gemini-2.5-flash'; // Cheapest capable model
382
388
  }
383
- // Free/unknown models — use flash
389
+ // Unknown models — use flash
384
390
  return 'google/gemini-2.5-flash';
385
391
  }
386
392
  /**
@@ -142,10 +142,11 @@ export async function startCommand(options) {
142
142
  }
143
143
  }
144
144
  // Build capabilities (built-in + MCP + sub-agent + MoA)
145
- const subAgent = createSubAgentCapability(apiUrl, chain, allCapabilities);
145
+ // Pass parent model so sub-agents inherit it (no silent paid spawns from free parents)
146
+ const subAgent = createSubAgentCapability(apiUrl, chain, allCapabilities, model);
146
147
  // Register MoA tool config (needs API URL for parallel model queries)
147
148
  const { registerMoAConfig } = await import('../tools/moa.js');
148
- registerMoAConfig(apiUrl, chain);
149
+ registerMoAConfig(apiUrl, chain, model);
149
150
  const capabilities = [...allCapabilities, ...mcpTools, subAgent];
150
151
  // Validate tool descriptions (self-evolution: detect SearchX-style description bugs)
151
152
  if (options.debug) {
@@ -13,4 +13,4 @@
13
13
  import type { CapabilityHandler } from '../agent/types.js';
14
14
  export declare const moaCapability: CapabilityHandler;
15
15
  /** Register the API URL for MoA tool (called during agent setup). */
16
- export declare function registerMoAConfig(apiUrl: string, chain: 'base' | 'solana'): void;
16
+ export declare function registerMoAConfig(apiUrl: string, chain: 'base' | 'solana', parentModel?: string): void;
package/dist/tools/moa.js CHANGED
@@ -31,13 +31,18 @@ const REFERENCE_TIMEOUT_MS = 60_000;
31
31
  // These will be injected at registration time
32
32
  let registeredApiUrl = '';
33
33
  let registeredChain = 'base';
34
+ let registeredParentModel = '';
34
35
  async function execute(input, ctx) {
35
36
  const { prompt, models, aggregator, include_reasoning } = input;
36
37
  if (!prompt) {
37
38
  return { output: 'Error: prompt is required', isError: true };
38
39
  }
39
40
  const referenceModels = models || REFERENCE_MODELS;
40
- const aggregatorModel = aggregator || AGGREGATOR_MODEL;
41
+ // If parent agent is on a free model, default aggregator to a free model too
42
+ // so MoA doesn't silently charge the user. Explicit `aggregator` arg wins.
43
+ const parentIsFree = registeredParentModel.startsWith('nvidia/') ||
44
+ registeredParentModel === 'blockrun/free';
45
+ const aggregatorModel = aggregator || (parentIsFree ? 'nvidia/nemotron-ultra-253b' : AGGREGATOR_MODEL);
41
46
  const client = new ModelClient({
42
47
  apiUrl: registeredApiUrl,
43
48
  chain: registeredChain,
@@ -167,7 +172,9 @@ Parameters:
167
172
  concurrent: true,
168
173
  };
169
174
  /** Register the API URL for MoA tool (called during agent setup). */
170
- export function registerMoAConfig(apiUrl, chain) {
175
+ export function registerMoAConfig(apiUrl, chain, parentModel) {
171
176
  registeredApiUrl = apiUrl;
172
177
  registeredChain = chain;
178
+ if (parentModel)
179
+ registeredParentModel = parentModel;
173
180
  }
@@ -2,4 +2,4 @@
2
2
  * SubAgent capability — spawn a child agent for independent tasks.
3
3
  */
4
4
  import type { CapabilityHandler } from '../agent/types.js';
5
- export declare function createSubAgentCapability(apiUrl: string, chain: 'base' | 'solana', capabilities: CapabilityHandler[]): CapabilityHandler;
5
+ export declare function createSubAgentCapability(apiUrl: string, chain: 'base' | 'solana', capabilities: CapabilityHandler[], parentModel?: string): CapabilityHandler;
@@ -6,6 +6,7 @@ import { assembleInstructions } from '../agent/context.js';
6
6
  // These will be injected at registration time
7
7
  let registeredApiUrl = '';
8
8
  let registeredChain = 'base';
9
+ let registeredParentModel = '';
9
10
  let registeredCapabilities = [];
10
11
  async function execute(input, ctx) {
11
12
  const { prompt, description, model } = input;
@@ -54,7 +55,9 @@ async function execute(input, ctx) {
54
55
  }
55
56
  turn++;
56
57
  const { content: parts } = await client.complete({
57
- model: model || 'anthropic/claude-sonnet-4.6',
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',
58
61
  messages: history,
59
62
  system: systemPrompt,
60
63
  tools: toolDefs,
@@ -107,10 +110,12 @@ async function execute(input, ctx) {
107
110
  output: finalText || `[${label}] completed after ${turn} turn(s) with no text output.`,
108
111
  };
109
112
  }
110
- export function createSubAgentCapability(apiUrl, chain, capabilities) {
113
+ export function createSubAgentCapability(apiUrl, chain, capabilities, parentModel) {
111
114
  registeredApiUrl = apiUrl;
112
115
  registeredChain = chain;
113
116
  registeredCapabilities = capabilities;
117
+ if (parentModel)
118
+ registeredParentModel = parentModel;
114
119
  return {
115
120
  spec: {
116
121
  name: 'Agent',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/franklin",
3
- "version": "3.6.13",
3
+ "version": "3.6.14",
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": {