@blockrun/franklin 3.21.8 → 3.22.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.
- package/README.md +12 -0
- package/dist/agent/context.js +5 -3
- package/dist/content/image-pricing.d.ts +7 -1
- package/dist/content/image-pricing.js +40 -17
- package/dist/content/record-image.d.ts +1 -1
- package/dist/content/record-image.js +2 -2
- package/dist/tools/blockrun.js +13 -4
- package/dist/tools/imagegen.d.ts +22 -3
- package/dist/tools/imagegen.js +252 -88
- package/dist/tools/index.js +5 -1
- package/dist/tools/realface.d.ts +29 -0
- package/dist/tools/realface.js +263 -0
- package/dist/tools/surf.d.ts +22 -0
- package/dist/tools/surf.js +281 -0
- package/dist/tools/tool-categories.js +7 -0
- package/dist/tools/videogen.js +44 -1
- package/dist/tools/voice.d.ts +1 -0
- package/dist/tools/voice.js +40 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -487,6 +487,18 @@ Same wallet. Same tools. From your phone.
|
|
|
487
487
|
|
|
488
488
|
---
|
|
489
489
|
|
|
490
|
+
## Contributors
|
|
491
|
+
|
|
492
|
+
External contributors whose work has shipped into Franklin:
|
|
493
|
+
|
|
494
|
+
- [**@KillerQueen-Z**](https://github.com/KillerQueen-Z) — typed Phone & Voice tools (#58), permissions classifier + internal VoiceStatus polling (#59), inline-paste threshold (#60), voicemail controls (#61), PredictionMarket / Predexon v2 schema realignment + agent-loop retry guard (#62)
|
|
495
|
+
- [**@BeneficialVast1048**](https://github.com/BeneficialVast1048) — VoiceCall `interruption_threshold` + `model` controls (#66)
|
|
496
|
+
- [**@TateLyman**](https://github.com/TateLyman) — test path-with-spaces fix (#57)
|
|
497
|
+
|
|
498
|
+
PRs welcome — see the Development section below for the local loop.
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
490
502
|
## Development
|
|
491
503
|
|
|
492
504
|
```bash
|
package/dist/agent/context.js
CHANGED
|
@@ -305,8 +305,10 @@ On-chain affiliate (20 bps in sell-token, force-set server-side) flows to BlockR
|
|
|
305
305
|
- US/CA destinations only. Marketing/sales calls require prior express consent (TCPA).
|
|
306
306
|
|
|
307
307
|
**Surf — crypto data + chat (x402-paid)** via the generic \`BlockRun\` capability. ~55 curated endpoints. Tier-1 $0.001, Tier-2 $0.005, Tier-3 / chat $0.02.
|
|
308
|
-
- \`/v1/surf/
|
|
309
|
-
- \`/v1/surf/market
|
|
308
|
+
- \`/v1/surf/market/ranking\` — token rankings (market cap, volume, change). **This is the token-ranking endpoint — there is no \`market/token-ranking\` or \`market/concept-ranking\`.**
|
|
309
|
+
- \`/v1/surf/market/fear-greed\` — Fear & Greed index. \`market/futures\` — futures overview. \`market/price\` (needs \`symbol\`) — price history. \`market/etf\` (needs \`symbol\`) — spot ETF flows. \`market/options\` (needs \`symbol\`) — options skew/IV.
|
|
310
|
+
- \`/v1/surf/market/{liquidation/chart,liquidation/order,onchain-indicator,price-indicator}\` — liquidations, on-chain indicators (NUPL/SOPR/MVRV), technical indicators (RSI/MACD/BBANDS). Tier-2 $0.005.
|
|
311
|
+
- \`/v1/surf/exchange/{price,perp,markets,depth,klines,funding-history}\` — CEX ticker, perps, pairs catalog, depth, klines, funding.
|
|
310
312
|
- \`/v1/surf/news/{feed,detail}\` — AI-curated crypto news.
|
|
311
313
|
- \`/v1/surf/onchain/{bridge,yield,gas-price,tx,schema,query,sql}\` — bridge/yield rankings, gas, tx detail, **raw SQL against 80+ indexed chain tables (Tier-3, $0.02)**, structured chain query, schema introspection.
|
|
312
314
|
- \`/v1/surf/token/{tokenomics,dex-trades,holders,transfers}\` — token analytics.
|
|
@@ -315,7 +317,7 @@ On-chain affiliate (20 bps in sell-token, force-set server-side) flows to BlockR
|
|
|
315
317
|
- \`/v1/surf/fund/{detail,portfolio,ranking}\` — VC fund profiles, portfolios, ranking.
|
|
316
318
|
- \`/v1/surf/project/{detail,defi/metrics,defi/ranking}\` — project profiles + DeFi protocol metrics.
|
|
317
319
|
|
|
318
|
-
|
|
320
|
+
**Endpoint discovery**: if you are unsure of the exact Surf path, do NOT guess blindly — any wrong \`/v1/surf/...\` path returns a 404 whose body lists every valid endpoint under \`available\`. Read that list and retry with a real path. The bundled skills (\`/surf-market\`, \`/surf-chain\`, \`/surf-social\`) also document which endpoint to pick for which question and the cost trade-off. Skipped (use the dedicated tools instead): \`/v1/surf/prediction-market/*\` (use \`PredictionMarket\`), \`/v1/surf/search/*\` (use \`ExaSearch\`), \`/v1/surf/web/*\` (use \`BrowserX\`). The Surf chat surface (\`/v1/surf/chat/completions\`, surf-1.5) is **not currently exposed** by the BlockRun gateway — removed from the registry pending an upstream redesign around per-token billing. Do not attempt to call it; use the data endpoints above for crypto context, or any of the standard LLMs on \`/v1/chat/completions\` for general chat.
|
|
319
321
|
|
|
320
322
|
**Generic gateway primitive**: \`BlockRun({ path, method, params, body })\` is a single capability that signs x402 and forwards to ANY path under \`/api\`. Use it for Surf endpoints (above) and any future BlockRun partner that doesn't have a dedicated capability yet. Always specify the exact path; the primitive will not guess.
|
|
321
323
|
|
|
@@ -11,4 +11,10 @@
|
|
|
11
11
|
* gateway ever exposes the realized payment amount on the response, that
|
|
12
12
|
* should be preferred — fall back to this estimate when it's missing.
|
|
13
13
|
*/
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Estimate the USD cost of `n` images for a model + size. `n` defaults to 1.
|
|
16
|
+
* Unknown models return 0 rather than a guess — a free/custom model should not
|
|
17
|
+
* carry a phantom charge against the Content budget, and surprise overcharging
|
|
18
|
+
* from a wrong guess is worse than under-counting.
|
|
19
|
+
*/
|
|
20
|
+
export declare function estimateImageCostUsd(model: string, size: string, n?: number): number;
|
|
@@ -11,22 +11,45 @@
|
|
|
11
11
|
* gateway ever exposes the realized payment amount on the response, that
|
|
12
12
|
* should be preferred — fall back to this estimate when it's missing.
|
|
13
13
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Per-image base price by model + size. Mirrors the gateway's IMAGE_MODELS.sizes
|
|
16
|
+
* (blockrun src/lib/models.ts). These are base prices — the realized x402 charge
|
|
17
|
+
* adds a small markup — but they're close enough for budget tracking. Sizes not
|
|
18
|
+
* listed for a model fall back to that model's 1024x1024 tier.
|
|
19
|
+
*/
|
|
20
|
+
const PRICE_TABLE = {
|
|
21
|
+
'openai/dall-e-3': {
|
|
22
|
+
base: 0.04,
|
|
23
|
+
sizes: { '1024x1024': 0.04, '1792x1024': 0.08, '1024x1792': 0.08 },
|
|
24
|
+
},
|
|
25
|
+
'openai/gpt-image-1': {
|
|
26
|
+
base: 0.02,
|
|
27
|
+
sizes: { '1024x1024': 0.02, '1536x1024': 0.04, '1024x1536': 0.04 },
|
|
28
|
+
},
|
|
29
|
+
'openai/gpt-image-2': {
|
|
30
|
+
base: 0.06,
|
|
31
|
+
sizes: { '1024x1024': 0.06, '1536x1024': 0.12, '1024x1536': 0.12 },
|
|
32
|
+
},
|
|
33
|
+
'google/nano-banana': {
|
|
34
|
+
base: 0.05,
|
|
35
|
+
sizes: { '1024x1024': 0.05 },
|
|
36
|
+
},
|
|
37
|
+
'google/nano-banana-pro': {
|
|
38
|
+
base: 0.1,
|
|
39
|
+
sizes: { '1024x1024': 0.1, '2048x2048': 0.1, '4096x4096': 0.15 },
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Estimate the USD cost of `n` images for a model + size. `n` defaults to 1.
|
|
44
|
+
* Unknown models return 0 rather than a guess — a free/custom model should not
|
|
45
|
+
* carry a phantom charge against the Content budget, and surprise overcharging
|
|
46
|
+
* from a wrong guess is worse than under-counting.
|
|
47
|
+
*/
|
|
48
|
+
export function estimateImageCostUsd(model, size, n = 1) {
|
|
49
|
+
const entry = PRICE_TABLE[model.toLowerCase()];
|
|
50
|
+
if (!entry)
|
|
51
|
+
return 0;
|
|
16
52
|
const s = size.replace(/\s+/g, '');
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return 0.08;
|
|
20
|
-
// All other sizes fall back to the standard 1024x1024 tier.
|
|
21
|
-
return 0.04;
|
|
22
|
-
}
|
|
23
|
-
if (m === 'openai/gpt-image-1') {
|
|
24
|
-
// gpt-image-1 standard tier; larger sizes would tier up but Franklin
|
|
25
|
-
// sends 1024x1024 as default.
|
|
26
|
-
return 0.042;
|
|
27
|
-
}
|
|
28
|
-
// Unknown model: return 0 rather than a guess. A free/custom model should
|
|
29
|
-
// not have a phantom charge against the Content budget, and surprise
|
|
30
|
-
// overcharging from a wrong guess is worse than under-counting.
|
|
31
|
-
return 0;
|
|
53
|
+
const perImage = entry.sizes[s] ?? entry.base;
|
|
54
|
+
return perImage * Math.max(1, n);
|
|
32
55
|
}
|
|
@@ -34,7 +34,7 @@ export type RecordImageDecision = {
|
|
|
34
34
|
* estimated cost fits; `{ ok: false, reason }` when it doesn't or the
|
|
35
35
|
* content doesn't exist. Non-mutating.
|
|
36
36
|
*/
|
|
37
|
-
export declare function checkImageBudget(library: ContentLibrary, contentId: string, model: string, size: string): {
|
|
37
|
+
export declare function checkImageBudget(library: ContentLibrary, contentId: string, model: string, size: string, count?: number): {
|
|
38
38
|
ok: true;
|
|
39
39
|
} | {
|
|
40
40
|
ok: false;
|
|
@@ -20,12 +20,12 @@ import { estimateImageCostUsd } from './image-pricing.js';
|
|
|
20
20
|
* estimated cost fits; `{ ok: false, reason }` when it doesn't or the
|
|
21
21
|
* content doesn't exist. Non-mutating.
|
|
22
22
|
*/
|
|
23
|
-
export function checkImageBudget(library, contentId, model, size) {
|
|
23
|
+
export function checkImageBudget(library, contentId, model, size, count = 1) {
|
|
24
24
|
const content = library.get(contentId);
|
|
25
25
|
if (!content) {
|
|
26
26
|
return { ok: false, reason: `Content ${contentId} not found` };
|
|
27
27
|
}
|
|
28
|
-
const cost = estimateImageCostUsd(model, size);
|
|
28
|
+
const cost = estimateImageCostUsd(model, size, count);
|
|
29
29
|
if (content.spentUsd + cost > content.budgetUsd + 1e-9) {
|
|
30
30
|
return {
|
|
31
31
|
ok: false,
|
package/dist/tools/blockrun.js
CHANGED
|
@@ -237,12 +237,21 @@ export const blockrunCapability = {
|
|
|
237
237
|
}
|
|
238
238
|
catch { /* best-effort */ }
|
|
239
239
|
if (!result.ok) {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
: `HTTP ${result.status}`;
|
|
240
|
+
const b = result.body;
|
|
241
|
+
const detail = typeof b?.error === 'string' ? b.error : `HTTP ${result.status}`;
|
|
243
242
|
const fullOutput = result.raw || JSON.stringify(result.body, null, 2);
|
|
243
|
+
// Surface the gateway's self-correction hints into the model-visible
|
|
244
|
+
// output. On a wrong path the Surf route returns `available: [...all
|
|
245
|
+
// valid paths]` (and often a `message`); without this the model only
|
|
246
|
+
// saw "Not Found" and kept guessing until the tool-failure circuit
|
|
247
|
+
// breaker tripped. The list comes straight from the live registry, so
|
|
248
|
+
// it's always complete and in sync — no drift.
|
|
249
|
+
const hint = typeof b?.message === 'string' ? `\n${b.message}` : '';
|
|
250
|
+
const avail = Array.isArray(b?.available)
|
|
251
|
+
? `\nValid endpoints: ${b.available.filter((x) => typeof x === 'string').join(', ')}`
|
|
252
|
+
: '';
|
|
244
253
|
return {
|
|
245
|
-
output: `BlockRun ${method} ${path} failed: ${detail} (status ${result.status}). No charge if status is 4xx pre-payment
|
|
254
|
+
output: `BlockRun ${method} ${path} failed: ${detail} (status ${result.status}). No charge if status is 4xx pre-payment.${hint}${avail}`,
|
|
246
255
|
fullOutput,
|
|
247
256
|
isError: true,
|
|
248
257
|
};
|
package/dist/tools/imagegen.d.ts
CHANGED
|
@@ -5,11 +5,28 @@
|
|
|
5
5
|
import type { CapabilityHandler } from '../agent/types.js';
|
|
6
6
|
import type { ContentLibrary } from '../content/library.js';
|
|
7
7
|
/**
|
|
8
|
-
* Models that accept a reference image via /v1/images/image2image.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Models that accept a reference image via /v1/images/image2image. Mirrors the
|
|
9
|
+
* gateway's EDIT_SUPPORTED_MODELS (src/app/api/v1/images/image2image/route.ts):
|
|
10
|
+
* both OpenAI gpt-image-* and Google Nano Banana support image-to-image edits.
|
|
11
11
|
*/
|
|
12
12
|
export declare const EDIT_SUPPORTED_MODELS: Set<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Mask-based inpainting is OpenAI-only. Gemini (Nano Banana) does prompt-based
|
|
15
|
+
* edits with no mask concept. Mirrors the gateway's MASK_SUPPORTED_MODELS.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MASK_SUPPORTED_MODELS: Set<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Output-image count ceiling. The gateway has no hard max but price scales with
|
|
20
|
+
* n, so cap client-side to keep a typo from draining the wallet.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MAX_OUTPUT_IMAGES = 4;
|
|
23
|
+
/**
|
|
24
|
+
* Valid sizes per known image model, mirroring the gateway's IMAGE_MODELS.sizes
|
|
25
|
+
* (src/lib/models.ts). Used to fail cheaply before paying when a caller or the
|
|
26
|
+
* media router picks a size the model rejects. Models absent from this table
|
|
27
|
+
* (custom / future gateway models) skip validation and let the gateway decide.
|
|
28
|
+
*/
|
|
29
|
+
export declare const IMAGE_MODEL_SIZES: Record<string, string[]>;
|
|
13
30
|
export declare const REFERENCE_IMAGE_MAX_BYTES = 4000000;
|
|
14
31
|
/**
|
|
15
32
|
* Normalize a reference image into a base64 data URI for the gateway. The
|
|
@@ -24,6 +41,8 @@ export interface ImageGenDeps {
|
|
|
24
41
|
/** Invoked after successful content-linked generation; lets callers persist. */
|
|
25
42
|
onContentChange?: () => void | Promise<void>;
|
|
26
43
|
}
|
|
44
|
+
/** Insert a `-{idx}` suffix before the file extension: a.png → a-2.png. */
|
|
45
|
+
export declare function withIndexSuffix(p: string, idx: number): string;
|
|
27
46
|
/**
|
|
28
47
|
* Build the ImageGen capability. Passing `deps.library` enables the
|
|
29
48
|
* contentId flow: pre-flight budget check + post-generation asset
|