@blockrun/franklin 3.0.0

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.
Files changed (138) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +256 -0
  3. package/dist/agent/commands.d.ts +27 -0
  4. package/dist/agent/commands.js +659 -0
  5. package/dist/agent/compact.d.ts +31 -0
  6. package/dist/agent/compact.js +366 -0
  7. package/dist/agent/context.d.ts +11 -0
  8. package/dist/agent/context.js +184 -0
  9. package/dist/agent/error-classifier.d.ts +10 -0
  10. package/dist/agent/error-classifier.js +61 -0
  11. package/dist/agent/llm.d.ts +63 -0
  12. package/dist/agent/llm.js +448 -0
  13. package/dist/agent/loop.d.ts +12 -0
  14. package/dist/agent/loop.js +346 -0
  15. package/dist/agent/optimize.d.ts +53 -0
  16. package/dist/agent/optimize.js +262 -0
  17. package/dist/agent/permissions.d.ts +39 -0
  18. package/dist/agent/permissions.js +226 -0
  19. package/dist/agent/reduce.d.ts +49 -0
  20. package/dist/agent/reduce.js +317 -0
  21. package/dist/agent/streaming-executor.d.ts +36 -0
  22. package/dist/agent/streaming-executor.js +149 -0
  23. package/dist/agent/tokens.d.ts +53 -0
  24. package/dist/agent/tokens.js +185 -0
  25. package/dist/agent/types.d.ts +125 -0
  26. package/dist/agent/types.js +5 -0
  27. package/dist/banner.d.ts +1 -0
  28. package/dist/banner.js +27 -0
  29. package/dist/commands/balance.d.ts +1 -0
  30. package/dist/commands/balance.js +40 -0
  31. package/dist/commands/config.d.ts +14 -0
  32. package/dist/commands/config.js +107 -0
  33. package/dist/commands/daemon.d.ts +3 -0
  34. package/dist/commands/daemon.js +117 -0
  35. package/dist/commands/history.d.ts +5 -0
  36. package/dist/commands/history.js +31 -0
  37. package/dist/commands/init.d.ts +3 -0
  38. package/dist/commands/init.js +92 -0
  39. package/dist/commands/logs.d.ts +5 -0
  40. package/dist/commands/logs.js +89 -0
  41. package/dist/commands/models.d.ts +1 -0
  42. package/dist/commands/models.js +56 -0
  43. package/dist/commands/plugin.d.ts +14 -0
  44. package/dist/commands/plugin.js +176 -0
  45. package/dist/commands/proxy.d.ts +13 -0
  46. package/dist/commands/proxy.js +106 -0
  47. package/dist/commands/setup.d.ts +1 -0
  48. package/dist/commands/setup.js +49 -0
  49. package/dist/commands/start.d.ts +8 -0
  50. package/dist/commands/start.js +292 -0
  51. package/dist/commands/stats.d.ts +10 -0
  52. package/dist/commands/stats.js +94 -0
  53. package/dist/commands/uninit.d.ts +1 -0
  54. package/dist/commands/uninit.js +63 -0
  55. package/dist/config.d.ts +9 -0
  56. package/dist/config.js +41 -0
  57. package/dist/index.d.ts +2 -0
  58. package/dist/index.js +179 -0
  59. package/dist/mcp/client.d.ts +44 -0
  60. package/dist/mcp/client.js +147 -0
  61. package/dist/mcp/config.d.ts +20 -0
  62. package/dist/mcp/config.js +138 -0
  63. package/dist/plugin-sdk/channel.d.ts +100 -0
  64. package/dist/plugin-sdk/channel.js +10 -0
  65. package/dist/plugin-sdk/index.d.ts +14 -0
  66. package/dist/plugin-sdk/index.js +9 -0
  67. package/dist/plugin-sdk/plugin.d.ts +87 -0
  68. package/dist/plugin-sdk/plugin.js +7 -0
  69. package/dist/plugin-sdk/search.d.ts +13 -0
  70. package/dist/plugin-sdk/search.js +4 -0
  71. package/dist/plugin-sdk/tracker.d.ts +27 -0
  72. package/dist/plugin-sdk/tracker.js +5 -0
  73. package/dist/plugin-sdk/workflow.d.ts +126 -0
  74. package/dist/plugin-sdk/workflow.js +11 -0
  75. package/dist/plugins/registry.d.ts +33 -0
  76. package/dist/plugins/registry.js +155 -0
  77. package/dist/plugins/runner.d.ts +21 -0
  78. package/dist/plugins/runner.js +453 -0
  79. package/dist/plugins-bundled/social/index.d.ts +10 -0
  80. package/dist/plugins-bundled/social/index.js +363 -0
  81. package/dist/plugins-bundled/social/plugin.json +14 -0
  82. package/dist/plugins-bundled/social/prompts.d.ts +19 -0
  83. package/dist/plugins-bundled/social/prompts.js +67 -0
  84. package/dist/plugins-bundled/social/types.d.ts +58 -0
  85. package/dist/plugins-bundled/social/types.js +16 -0
  86. package/dist/pricing.d.ts +21 -0
  87. package/dist/pricing.js +91 -0
  88. package/dist/proxy/fallback.d.ts +38 -0
  89. package/dist/proxy/fallback.js +144 -0
  90. package/dist/proxy/server.d.ts +18 -0
  91. package/dist/proxy/server.js +576 -0
  92. package/dist/proxy/sse-translator.d.ts +29 -0
  93. package/dist/proxy/sse-translator.js +270 -0
  94. package/dist/router/index.d.ts +22 -0
  95. package/dist/router/index.js +269 -0
  96. package/dist/session/search.d.ts +33 -0
  97. package/dist/session/search.js +229 -0
  98. package/dist/session/storage.d.ts +48 -0
  99. package/dist/session/storage.js +173 -0
  100. package/dist/stats/insights.d.ts +55 -0
  101. package/dist/stats/insights.js +195 -0
  102. package/dist/stats/tracker.d.ts +54 -0
  103. package/dist/stats/tracker.js +165 -0
  104. package/dist/tools/askuser.d.ts +6 -0
  105. package/dist/tools/askuser.js +76 -0
  106. package/dist/tools/bash.d.ts +5 -0
  107. package/dist/tools/bash.js +336 -0
  108. package/dist/tools/edit.d.ts +5 -0
  109. package/dist/tools/edit.js +148 -0
  110. package/dist/tools/glob.d.ts +5 -0
  111. package/dist/tools/glob.js +158 -0
  112. package/dist/tools/grep.d.ts +5 -0
  113. package/dist/tools/grep.js +194 -0
  114. package/dist/tools/imagegen.d.ts +6 -0
  115. package/dist/tools/imagegen.js +172 -0
  116. package/dist/tools/index.d.ts +17 -0
  117. package/dist/tools/index.js +30 -0
  118. package/dist/tools/read.d.ts +11 -0
  119. package/dist/tools/read.js +90 -0
  120. package/dist/tools/subagent.d.ts +5 -0
  121. package/dist/tools/subagent.js +116 -0
  122. package/dist/tools/task.d.ts +5 -0
  123. package/dist/tools/task.js +91 -0
  124. package/dist/tools/webfetch.d.ts +5 -0
  125. package/dist/tools/webfetch.js +166 -0
  126. package/dist/tools/websearch.d.ts +5 -0
  127. package/dist/tools/websearch.js +103 -0
  128. package/dist/tools/write.d.ts +5 -0
  129. package/dist/tools/write.js +114 -0
  130. package/dist/ui/app.d.ts +26 -0
  131. package/dist/ui/app.js +545 -0
  132. package/dist/ui/model-picker.d.ts +14 -0
  133. package/dist/ui/model-picker.js +161 -0
  134. package/dist/ui/terminal.d.ts +35 -0
  135. package/dist/ui/terminal.js +337 -0
  136. package/dist/wallet/manager.d.ts +10 -0
  137. package/dist/wallet/manager.js +23 -0
  138. package/package.json +79 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Fallback chain for runcode
3
+ * Automatically switches to backup models when primary fails (429, 5xx, etc.)
4
+ */
5
+ export interface FallbackConfig {
6
+ /** Models to try in order of priority */
7
+ chain: string[];
8
+ /** HTTP status codes that trigger fallback */
9
+ retryOn: number[];
10
+ /** Maximum retries across all models */
11
+ maxRetries: number;
12
+ /** Delay between retries in ms */
13
+ retryDelayMs: number;
14
+ }
15
+ export declare const DEFAULT_FALLBACK_CONFIG: FallbackConfig;
16
+ export interface FallbackResult {
17
+ response: Response;
18
+ modelUsed: string;
19
+ /** The request body with the successful model substituted in */
20
+ bodyUsed: string;
21
+ fallbackUsed: boolean;
22
+ attemptsCount: number;
23
+ failedModels: string[];
24
+ }
25
+ /**
26
+ * Fetch with automatic fallback to backup models
27
+ */
28
+ export declare function fetchWithFallback(url: string, init: RequestInit, originalBody: string, config?: FallbackConfig, onFallback?: (model: string, statusCode: number, nextModel: string) => void): Promise<FallbackResult>;
29
+ /**
30
+ * Get the current model from fallback chain based on parsed request
31
+ */
32
+ export declare function getCurrentModelFromChain(requestedModel: string | undefined, config?: FallbackConfig): string;
33
+ /**
34
+ * Build fallback chain starting from a specific model.
35
+ * Filters out routing profiles (blockrun/auto etc.) since the backend
36
+ * doesn't recognize them — they must be resolved by the smart router first.
37
+ */
38
+ export declare function buildFallbackChain(startModel: string, config?: FallbackConfig): string[];
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Fallback chain for runcode
3
+ * Automatically switches to backup models when primary fails (429, 5xx, etc.)
4
+ */
5
+ import fs from 'node:fs';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+ const LOG_FILE = path.join(os.homedir(), '.blockrun', 'runcode-debug.log');
9
+ // eslint-disable-next-line no-control-regex
10
+ const ANSI_RE = /\x1B\[[0-9;]*[A-Za-z]|\x1B\][^\x07]*\x07|\x1B[()][A-B]|\r/g;
11
+ function appendLog(msg) {
12
+ try {
13
+ fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true });
14
+ fs.appendFileSync(LOG_FILE, `[${new Date().toISOString()}] ${msg.replace(ANSI_RE, '')}\n`);
15
+ }
16
+ catch { /* ignore */ }
17
+ }
18
+ export const DEFAULT_FALLBACK_CONFIG = {
19
+ chain: [
20
+ 'deepseek/deepseek-chat', // Direct fallback — cheap & reliable
21
+ 'google/gemini-2.5-flash', // Fast & capable
22
+ 'nvidia/nemotron-ultra-253b', // Free model as ultimate fallback
23
+ ],
24
+ retryOn: [429, 500, 502, 503, 504, 529],
25
+ maxRetries: 5,
26
+ retryDelayMs: 1000,
27
+ };
28
+ /**
29
+ * Sleep helper
30
+ */
31
+ function sleep(ms) {
32
+ return new Promise((resolve) => setTimeout(resolve, ms));
33
+ }
34
+ /**
35
+ * Replace model in request body
36
+ */
37
+ function replaceModelInBody(body, newModel) {
38
+ try {
39
+ const parsed = JSON.parse(body);
40
+ parsed.model = newModel;
41
+ return JSON.stringify(parsed);
42
+ }
43
+ catch {
44
+ return body;
45
+ }
46
+ }
47
+ /**
48
+ * Fetch with automatic fallback to backup models
49
+ */
50
+ export async function fetchWithFallback(url, init, originalBody, config = DEFAULT_FALLBACK_CONFIG, onFallback) {
51
+ const failedModels = [];
52
+ let attempts = 0;
53
+ const FALLBACK_TIMEOUT_MS = 60_000; // 60s per attempt
54
+ for (let i = 0; i < config.chain.length && attempts < config.maxRetries; i++) {
55
+ const model = config.chain[i];
56
+ const body = replaceModelInBody(originalBody, model);
57
+ try {
58
+ attempts++;
59
+ const controller = new AbortController();
60
+ const timeout = setTimeout(() => controller.abort(), FALLBACK_TIMEOUT_MS);
61
+ const response = await fetch(url, {
62
+ ...init,
63
+ body,
64
+ signal: controller.signal,
65
+ });
66
+ clearTimeout(timeout);
67
+ // Success or non-retryable error
68
+ if (!config.retryOn.includes(response.status)) {
69
+ return {
70
+ response,
71
+ modelUsed: model,
72
+ bodyUsed: body,
73
+ fallbackUsed: i > 0,
74
+ attemptsCount: attempts,
75
+ failedModels,
76
+ };
77
+ }
78
+ // Retryable error - log and try next
79
+ failedModels.push(model);
80
+ const nextModel = config.chain[i + 1];
81
+ if (nextModel && onFallback) {
82
+ onFallback(model, response.status, nextModel);
83
+ }
84
+ // Wait before trying next model (with exponential backoff for same model retries)
85
+ if (i < config.chain.length - 1) {
86
+ await sleep(config.retryDelayMs);
87
+ }
88
+ }
89
+ catch (err) {
90
+ // Network error - try next model
91
+ failedModels.push(model);
92
+ const nextModel = config.chain[i + 1];
93
+ if (nextModel && onFallback) {
94
+ const errMsg = err instanceof Error ? err.message : 'Network error';
95
+ onFallback(model, 0, nextModel);
96
+ appendLog(`[runcode] [fallback] ${model} network error: ${errMsg}`);
97
+ }
98
+ if (i < config.chain.length - 1) {
99
+ await sleep(config.retryDelayMs);
100
+ }
101
+ }
102
+ }
103
+ // All models failed - throw error
104
+ throw new Error(`All models in fallback chain failed: ${failedModels.join(', ')}`);
105
+ }
106
+ /**
107
+ * Get the current model from fallback chain based on parsed request
108
+ */
109
+ export function getCurrentModelFromChain(requestedModel, config = DEFAULT_FALLBACK_CONFIG) {
110
+ // If model is explicitly set and in chain, start from there
111
+ if (requestedModel) {
112
+ const index = config.chain.indexOf(requestedModel);
113
+ if (index >= 0) {
114
+ return requestedModel;
115
+ }
116
+ // Model not in chain, use as-is (user specified custom model)
117
+ return requestedModel;
118
+ }
119
+ // Default to first model in chain
120
+ return config.chain[0];
121
+ }
122
+ /** Routing profiles that must never be sent to the backend directly */
123
+ const ROUTING_PROFILES = new Set([
124
+ 'blockrun/auto', 'blockrun/eco', 'blockrun/premium', 'blockrun/free',
125
+ ]);
126
+ /**
127
+ * Build fallback chain starting from a specific model.
128
+ * Filters out routing profiles (blockrun/auto etc.) since the backend
129
+ * doesn't recognize them — they must be resolved by the smart router first.
130
+ */
131
+ export function buildFallbackChain(startModel, config = DEFAULT_FALLBACK_CONFIG) {
132
+ // Never include routing profiles in the chain — they'd cause 400s
133
+ const safeChain = config.chain.filter(m => !ROUTING_PROFILES.has(m));
134
+ const index = safeChain.indexOf(startModel);
135
+ if (index >= 0) {
136
+ return safeChain.slice(index);
137
+ }
138
+ // If startModel is a routing profile, skip it and just use the safe chain
139
+ if (ROUTING_PROFILES.has(startModel)) {
140
+ return safeChain;
141
+ }
142
+ // Model not in default chain - prepend it
143
+ return [startModel, ...safeChain];
144
+ }
@@ -0,0 +1,18 @@
1
+ import http from 'node:http';
2
+ import type { Chain } from '../config.js';
3
+ export interface ProxyOptions {
4
+ port: number;
5
+ apiUrl: string;
6
+ chain?: Chain;
7
+ modelOverride?: string;
8
+ debug?: boolean;
9
+ fallbackEnabled?: boolean;
10
+ }
11
+ export declare function createProxy(options: ProxyOptions): http.Server;
12
+ type RequestCategory = 'simple' | 'code' | 'default';
13
+ interface ClassifiedRequest {
14
+ category: RequestCategory;
15
+ suggestedModel?: string;
16
+ }
17
+ export declare function classifyRequest(body: string): ClassifiedRequest;
18
+ export {};