@blockrun/franklin 3.8.44 → 3.9.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.
- package/README.md +3 -2
- package/dist/agent/commands.d.ts +5 -0
- package/dist/agent/commands.js +28 -0
- package/dist/agent/compact.js +1 -1
- package/dist/agent/context.js +1 -0
- package/dist/agent/llm.js +4 -4
- package/dist/agent/loop.js +40 -13
- package/dist/agent/verification.js +2 -2
- package/dist/commands/balance-retry.d.ts +15 -0
- package/dist/commands/balance-retry.js +20 -0
- package/dist/commands/skills.d.ts +8 -0
- package/dist/commands/skills.js +93 -0
- package/dist/commands/social.js +1 -1
- package/dist/commands/start.js +17 -13
- package/dist/commands/telegram.js +1 -1
- package/dist/index.js +9 -0
- package/dist/learnings/extractor.js +3 -3
- package/dist/plugin-sdk/workflow.js +2 -2
- package/dist/pricing.js +1 -1
- package/dist/proxy/fallback.js +1 -1
- package/dist/proxy/server.js +10 -10
- package/dist/router/index.js +8 -8
- package/dist/skills/bootstrap.d.ts +27 -0
- package/dist/skills/bootstrap.js +40 -0
- package/dist/skills/invoke.d.ts +23 -0
- package/dist/skills/invoke.js +38 -0
- package/dist/skills/loader.d.ts +21 -0
- package/dist/skills/loader.js +149 -0
- package/dist/skills/registry.d.ts +26 -0
- package/dist/skills/registry.js +54 -0
- package/dist/skills/types.d.ts +47 -0
- package/dist/skills/types.js +8 -0
- package/dist/skills-bundled/budget-grill/SKILL.md +24 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/moa.js +4 -4
- package/dist/tools/subagent.js +3 -3
- package/dist/tools/tool-categories.js +3 -0
- package/dist/tools/wallet.d.ts +23 -0
- package/dist/tools/wallet.js +63 -0
- package/dist/ui/app.js +3 -3
- package/dist/ui/model-picker.js +13 -17
- package/package.json +4 -3
package/dist/ui/app.js
CHANGED
|
@@ -37,7 +37,7 @@ function useTerminalSize() {
|
|
|
37
37
|
}, [stdout]);
|
|
38
38
|
return size;
|
|
39
39
|
}
|
|
40
|
-
function InputBox({ input, setInput, onSubmit, model, balance, sessionCost, queued, queuedCount, focused, busy, contextPct, vimMode, onVimModeChange }) {
|
|
40
|
+
function InputBox({ input, setInput, onSubmit, model, balance, chain, walletTail, sessionCost, queued, queuedCount, focused, busy, contextPct, vimMode, onVimModeChange }) {
|
|
41
41
|
const { cols } = useTerminalSize();
|
|
42
42
|
// Avoid drawing right up to the terminal edge. Several terminals auto-wrap
|
|
43
43
|
// a full-width border glyph onto the next row, which leaves "ghost" top
|
|
@@ -48,7 +48,7 @@ function InputBox({ input, setInput, onSubmit, model, balance, sessionCost, queu
|
|
|
48
48
|
? `⏎ ${queuedCount ?? 1} queued: ${queued.slice(0, 40)}`
|
|
49
49
|
: 'Working...')
|
|
50
50
|
: 'Type a message...';
|
|
51
|
-
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { borderStyle: "round", borderDimColor: true, paddingX: 1, width: boxWidth, children: [busy && !input ? _jsxs(Text, { color: "yellow", children: [_jsx(Spinner, { type: "dots" }), " "] }) : null, _jsx(Box, { flexGrow: 1, children: vimMode ? (_jsx(VimInput, { value: input, onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, focus: focused !== false, showMode: true, onModeChange: onVimModeChange })) : (_jsx(TextInput, { value: input, onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, focus: focused !== false })) })] }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { dimColor: true, children: [busy ? _jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }) : null, busy ? ' ' : '', shortModelName(model), " \u00B7 ", balance, sessionCost > 0.00001 ? _jsxs(Text, { color: "yellow", children: [" -$", sessionCost.toFixed(4)] }) : '', contextPct !== undefined && contextPct > 0 ? (() => {
|
|
51
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { borderStyle: "round", borderDimColor: true, paddingX: 1, width: boxWidth, children: [busy && !input ? _jsxs(Text, { color: "yellow", children: [_jsx(Spinner, { type: "dots" }), " "] }) : null, _jsx(Box, { flexGrow: 1, children: vimMode ? (_jsx(VimInput, { value: input, onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, focus: focused !== false, showMode: true, onModeChange: onVimModeChange })) : (_jsx(TextInput, { value: input, onChange: setInput, onSubmit: onSubmit, placeholder: placeholder, focus: focused !== false })) })] }), _jsx(Box, { marginLeft: 1, children: _jsxs(Text, { dimColor: true, children: [busy ? _jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }) : null, busy ? ' ' : '', shortModelName(model), " \u00B7 ", balance, chain ? _jsxs(Text, { children: [" \u00B7 ", _jsx(Text, { color: "magenta", children: chain }), walletTail ? _jsxs(Text, { dimColor: true, children: [":", walletTail] }) : ''] }) : '', sessionCost > 0.00001 ? _jsxs(Text, { color: "yellow", children: [" -$", sessionCost.toFixed(4)] }) : '', contextPct !== undefined && contextPct > 0 ? (() => {
|
|
52
52
|
// Visual context bar: ▓▓▓▓▓▓░░░░ 75%
|
|
53
53
|
const filled = Math.round(contextPct / 10);
|
|
54
54
|
const empty = 10 - filled;
|
|
@@ -774,7 +774,7 @@ function RunCodeApp({ initialModel, workDir, walletAddress, walletBalance, chain
|
|
|
774
774
|
const isHighlight = m.highlight === true;
|
|
775
775
|
return (_jsxs(Box, { marginLeft: 2, children: [_jsxs(Text, { inverse: isSelected, color: isSelected ? 'cyan' : isHighlight ? 'yellow' : undefined, bold: isSelected || isHighlight, children: [' ', m.label.padEnd(26), ' '] }), _jsxs(Text, { dimColor: true, children: [" ", m.shortcut.padEnd(14)] }), _jsx(Text, { color: m.price === 'FREE' ? 'green' : isHighlight ? 'yellow' : undefined, dimColor: !isHighlight && m.price !== 'FREE', children: m.price }), isCurrent && _jsx(Text, { color: "green", children: " \u2190" })] }, m.id));
|
|
776
776
|
})] }, cat.category))), _jsx(Box, { marginTop: 1, marginLeft: 2, children: _jsx(Text, { dimColor: true, children: "Your conversation stays above \u2014 picking a model keeps all history intact." }) })] }));
|
|
777
|
-
})(), !inPicker && (_jsx(InputBox, { input: (permissionRequest || askUserRequest) ? '' : input, setInput: (permissionRequest || askUserRequest) ? () => { } : setInput, onSubmit: (permissionRequest || askUserRequest) ? () => { } : handleSubmit, model: currentModel, balance: liveBalance, sessionCost: totalCost, queued: queuedInputs[0] || undefined, queuedCount: queuedInputs.length, focused: !permissionRequest && !askUserRequest, busy: !askUserRequest && (waiting || thinking || tools.size > 0), contextPct: contextPct, vimMode: vimEnabled, onVimModeChange: setCurrentVimMode }))] }));
|
|
777
|
+
})(), !inPicker && (_jsx(InputBox, { input: (permissionRequest || askUserRequest) ? '' : input, setInput: (permissionRequest || askUserRequest) ? () => { } : setInput, onSubmit: (permissionRequest || askUserRequest) ? () => { } : handleSubmit, model: currentModel, balance: liveBalance, chain: chain, walletTail: walletAddress && walletAddress.length >= 4 && !walletAddress.startsWith('not set') ? walletAddress.slice(-4) : undefined, sessionCost: totalCost, queued: queuedInputs[0] || undefined, queuedCount: queuedInputs.length, focused: !permissionRequest && !askUserRequest, busy: !askUserRequest && (waiting || thinking || tools.size > 0), contextPct: contextPct, vimMode: vimEnabled, onVimModeChange: setCurrentVimMode }))] }));
|
|
778
778
|
}
|
|
779
779
|
export function launchInkUI(opts) {
|
|
780
780
|
let resolveInput = null;
|
package/dist/ui/model-picker.js
CHANGED
|
@@ -54,20 +54,22 @@ export const MODEL_SHORTCUTS = {
|
|
|
54
54
|
// DeepSeek
|
|
55
55
|
deepseek: 'deepseek/deepseek-chat',
|
|
56
56
|
r1: 'deepseek/deepseek-reasoner',
|
|
57
|
-
// Free (BlockRun gateway free tier — refreshed 2026-04)
|
|
58
|
-
free: 'nvidia/
|
|
59
|
-
glm4: 'nvidia/
|
|
60
|
-
'deepseek-free': 'nvidia/
|
|
57
|
+
// Free (agent-tested BlockRun gateway free tier — refreshed 2026-04)
|
|
58
|
+
free: 'nvidia/qwen3-coder-480b',
|
|
59
|
+
glm4: 'nvidia/qwen3-coder-480b',
|
|
60
|
+
'deepseek-free': 'nvidia/qwen3-coder-480b',
|
|
61
61
|
'qwen-coder': 'nvidia/qwen3-coder-480b',
|
|
62
|
-
'qwen-think': 'nvidia/qwen3-
|
|
62
|
+
'qwen-think': 'nvidia/qwen3-coder-480b',
|
|
63
63
|
maverick: 'nvidia/llama-4-maverick',
|
|
64
|
-
'gpt-oss': 'nvidia/
|
|
65
|
-
'gpt-oss-small': 'nvidia/
|
|
66
|
-
'mistral-small': 'nvidia/
|
|
67
|
-
// Backward-compatibility aliases for models the gateway retired
|
|
64
|
+
'gpt-oss': 'nvidia/qwen3-coder-480b',
|
|
65
|
+
'gpt-oss-small': 'nvidia/qwen3-coder-480b',
|
|
66
|
+
'mistral-small': 'nvidia/llama-4-maverick',
|
|
67
|
+
// Backward-compatibility aliases for models the gateway retired or exposes
|
|
68
|
+
// unreliably on /v1/messages. Map to agent-tested free models so shortcuts
|
|
69
|
+
// keep working without silent paid fallback or empty tool-use turns.
|
|
68
70
|
// Map to the closest current free model so old session records + user
|
|
69
71
|
// muscle memory keep working.
|
|
70
|
-
nemotron: 'nvidia/
|
|
72
|
+
nemotron: 'nvidia/qwen3-coder-480b',
|
|
71
73
|
devstral: 'nvidia/qwen3-coder-480b',
|
|
72
74
|
// Others
|
|
73
75
|
minimax: 'minimax/minimax-m2.7',
|
|
@@ -154,14 +156,8 @@ export const PICKER_CATEGORIES = [
|
|
|
154
156
|
{
|
|
155
157
|
category: '🆓 Free (no USDC needed)',
|
|
156
158
|
models: [
|
|
157
|
-
{ id: 'nvidia/
|
|
158
|
-
{ id: 'nvidia/qwen3-next-80b-a3b-thinking', shortcut: 'qwen-think', label: 'Qwen3-Next 80B Thinking', price: 'FREE' },
|
|
159
|
-
{ id: 'nvidia/qwen3-coder-480b', shortcut: 'qwen-coder', label: 'Qwen3 Coder 480B', price: 'FREE' },
|
|
159
|
+
{ id: 'nvidia/qwen3-coder-480b', shortcut: 'free', label: 'Qwen3 Coder 480B', price: 'FREE' },
|
|
160
160
|
{ id: 'nvidia/llama-4-maverick', shortcut: 'maverick', label: 'Llama 4 Maverick', price: 'FREE' },
|
|
161
|
-
{ id: 'nvidia/deepseek-v3.2', shortcut: 'deepseek-free', label: 'DeepSeek V3.2', price: 'FREE' },
|
|
162
|
-
{ id: 'nvidia/gpt-oss-120b', shortcut: 'gpt-oss', label: 'GPT-OSS 120B', price: 'FREE' },
|
|
163
|
-
{ id: 'nvidia/gpt-oss-20b', shortcut: 'gpt-oss-small', label: 'GPT-OSS 20B', price: 'FREE' },
|
|
164
|
-
{ id: 'nvidia/mistral-small-4-119b', shortcut: 'mistral-small', label: 'Mistral Small 4 119B', price: 'FREE' },
|
|
165
161
|
],
|
|
166
162
|
},
|
|
167
163
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockrun/franklin",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.1",
|
|
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": {
|
|
@@ -31,10 +31,11 @@
|
|
|
31
31
|
"build": "tsc && node scripts/copy-plugin-assets.mjs",
|
|
32
32
|
"dev": "tsc --watch",
|
|
33
33
|
"start": "node dist/index.js",
|
|
34
|
-
"test": "npm run build && node --test --test-reporter=spec test/local.mjs",
|
|
34
|
+
"test": "npm run build && node --test --test-reporter=spec test/local.mjs test/skills.local.mjs",
|
|
35
35
|
"test:e2e": "npm run build && node --test --test-reporter=spec test/e2e.mjs",
|
|
36
|
+
"test:free-models": "npm run build && node --test --test-reporter=spec test/free-model-matrix.mjs",
|
|
36
37
|
"test:all": "npm run test && npm run test:e2e",
|
|
37
|
-
"test:watch": "node --test --watch test/local.mjs",
|
|
38
|
+
"test:watch": "node --test --watch test/local.mjs test/skills.local.mjs",
|
|
38
39
|
"test:e2e:watch": "node --test --watch test/e2e.mjs"
|
|
39
40
|
},
|
|
40
41
|
"keywords": [
|