@blockrun/franklin 3.11.0 → 3.12.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/dist/agent/context.js
CHANGED
|
@@ -205,6 +205,13 @@ You run on the BlockRun AI Gateway. When the user asks you to "test the BlockRun
|
|
|
205
205
|
- \`GET /v1/models\` — full model catalog (id, owner, context window, pricing).
|
|
206
206
|
- \`GET /v1/health/overview\` · \`/v1/health/regions\` · \`/v1/health/chain\` · \`/v1/health/models\` — gateway status.
|
|
207
207
|
|
|
208
|
+
**Trading & DeFi (mixed methods, x402-paid; new in v3.12.0)**
|
|
209
|
+
- \`GET /v1/jupiter/quote?inputMint=...&outputMint=...&amount=...&slippageBps=50\` — Solana DEX-aggregator price quote across every DEX Jupiter knows. \$0.001/call.
|
|
210
|
+
- \`POST /v1/jupiter/swap\` — body \`{ userPublicKey, quoteResponse }\`. Returns a base64-encoded **unsigned** Solana transaction. Caller signs locally; gateway never custodies keys. \$0.001/call.
|
|
211
|
+
- \`GET /v1/defillama/protocols\` · \`/v1/defillama/protocol/{slug}\` · \`/v1/defillama/chains\` · \`/v1/defillama/yields\` — TVL / yield-pool data, Apache-2.0 source. \$0.005/call.
|
|
212
|
+
- \`GET /v1/defillama/prices/{coins}\` — token price lookup (coingecko:bitcoin, ethereum:0x..., solana:mint, comma-separated). \$0.001/call.
|
|
213
|
+
- \`POST /v1/solana/rpc\` — JSON-RPC passthrough to public mainnet-beta (getAccountInfo, getTokenSupply, sendTransaction, etc.). \$0.0005 per call (per element of a batch). Use this instead of running your own RPC infra.
|
|
214
|
+
|
|
208
215
|
**Sandbox (POST, x402-paid)**
|
|
209
216
|
- \`/v1/modal/{...path}\` — Modal GPU sandbox passthrough (create/exec/etc.).
|
|
210
217
|
- \`/v1/pm/{...path}\` — prediction-market data passthrough.
|
package/dist/skills/loader.js
CHANGED
|
@@ -43,6 +43,9 @@ export function parseSkill(content) {
|
|
|
43
43
|
if (typeof fields['cost-receipt'] === 'boolean') {
|
|
44
44
|
skill.costReceipt = fields['cost-receipt'];
|
|
45
45
|
}
|
|
46
|
+
if (Array.isArray(fields.triggers)) {
|
|
47
|
+
skill.triggers = fields.triggers.filter((t) => typeof t === 'string');
|
|
48
|
+
}
|
|
46
49
|
return { skill, warnings };
|
|
47
50
|
}
|
|
48
51
|
function extractFrontmatter(content) {
|
|
@@ -57,6 +60,7 @@ function extractFrontmatter(content) {
|
|
|
57
60
|
const body = rest.slice(closeIdx + 1 + FRONTMATTER_FENCE.length + 1);
|
|
58
61
|
return { frontmatter, body };
|
|
59
62
|
}
|
|
63
|
+
const LIST_ITEM_RE = /^\s+-\s+(.+)$/;
|
|
60
64
|
function parseFrontmatter(text) {
|
|
61
65
|
const fields = {};
|
|
62
66
|
const warnings = [];
|
|
@@ -65,6 +69,9 @@ function parseFrontmatter(text) {
|
|
|
65
69
|
const line = lines[i];
|
|
66
70
|
if (line.trim() === '' || line.trim().startsWith('#'))
|
|
67
71
|
continue;
|
|
72
|
+
// YAML list continuation: skip — handled by the key-line that opened it.
|
|
73
|
+
if (LIST_ITEM_RE.test(line))
|
|
74
|
+
continue;
|
|
68
75
|
const colon = line.indexOf(':');
|
|
69
76
|
if (colon < 0) {
|
|
70
77
|
return { error: `frontmatter line ${i + 1} is not key: value — got "${line}"` };
|
|
@@ -74,6 +81,30 @@ function parseFrontmatter(text) {
|
|
|
74
81
|
if (key.length === 0) {
|
|
75
82
|
return { error: `frontmatter line ${i + 1} has empty key` };
|
|
76
83
|
}
|
|
84
|
+
// Empty value followed by indented `- item` lines = YAML list.
|
|
85
|
+
if (rawValue === '') {
|
|
86
|
+
const items = [];
|
|
87
|
+
let j = i + 1;
|
|
88
|
+
while (j < lines.length) {
|
|
89
|
+
const next = lines[j];
|
|
90
|
+
if (next.trim() === '') {
|
|
91
|
+
j++;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const m = LIST_ITEM_RE.exec(next);
|
|
95
|
+
if (!m)
|
|
96
|
+
break;
|
|
97
|
+
items.push(parseScalarString(m[1].trim()));
|
|
98
|
+
j++;
|
|
99
|
+
}
|
|
100
|
+
if (items.length > 0) {
|
|
101
|
+
fields[key] = items;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// No list followed; treat as empty string.
|
|
105
|
+
fields[key] = '';
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
77
108
|
fields[key] = parseScalar(rawValue);
|
|
78
109
|
}
|
|
79
110
|
return { fields, warnings };
|
|
@@ -140,7 +171,10 @@ function parseScalar(raw) {
|
|
|
140
171
|
return Number.parseInt(raw, 10);
|
|
141
172
|
if (/^-?\d+\.\d+$/.test(raw))
|
|
142
173
|
return Number.parseFloat(raw);
|
|
143
|
-
|
|
174
|
+
return parseScalarString(raw);
|
|
175
|
+
}
|
|
176
|
+
/** Strip surrounding quotes from a string-shaped value, leaving everything else as-is. */
|
|
177
|
+
function parseScalarString(raw) {
|
|
144
178
|
if ((raw.startsWith('"') && raw.endsWith('"') && raw.length >= 2) ||
|
|
145
179
|
(raw.startsWith("'") && raw.endsWith("'") && raw.length >= 2)) {
|
|
146
180
|
return raw.slice(1, -1);
|
package/dist/skills/types.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface ParsedSkill {
|
|
|
21
21
|
budgetCapUsd?: number;
|
|
22
22
|
/** Franklin extension: append a paid-call receipt under the agent reply. */
|
|
23
23
|
costReceipt?: boolean;
|
|
24
|
+
/** Trigger phrases that should auto-invoke this skill when matched. */
|
|
25
|
+
triggers?: string[];
|
|
24
26
|
}
|
|
25
27
|
export type ParseResult = {
|
|
26
28
|
skill: ParsedSkill;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: budget-grill
|
|
3
3
|
description: Wallet-aware grilling — interview me about a plan one question at a time, with each branch of the decision tree framed as a USDC cost impact
|
|
4
|
+
triggers:
|
|
5
|
+
- "grill my plan"
|
|
6
|
+
- "interview my plan"
|
|
7
|
+
- "budget review"
|
|
8
|
+
- "cost analysis"
|
|
9
|
+
- "wallet drain"
|
|
10
|
+
- "spending review"
|
|
11
|
+
- "cost impact"
|
|
12
|
+
- "plan review"
|
|
13
|
+
- "challenge my idea"
|
|
14
|
+
- "stress test plan"
|
|
4
15
|
argument-hint: <plan or topic to grill on>
|
|
5
16
|
cost-receipt: true
|
|
6
17
|
---
|
package/package.json
CHANGED