@kaleidorg/mind 0.5.1 → 0.6.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/dist/autonomy/index.d.ts +21 -0
- package/dist/autonomy/index.d.ts.map +1 -0
- package/dist/autonomy/index.js +16 -0
- package/dist/autonomy/index.js.map +1 -0
- package/dist/autonomy/prompt.d.ts +21 -0
- package/dist/autonomy/prompt.d.ts.map +1 -0
- package/dist/autonomy/prompt.js +37 -0
- package/dist/autonomy/prompt.js.map +1 -0
- package/dist/autonomy/risk.d.ts +53 -0
- package/dist/autonomy/risk.d.ts.map +1 -0
- package/dist/autonomy/risk.js +74 -0
- package/dist/autonomy/risk.js.map +1 -0
- package/dist/autonomy/run-state.d.ts +39 -0
- package/dist/autonomy/run-state.d.ts.map +1 -0
- package/dist/autonomy/run-state.js +118 -0
- package/dist/autonomy/run-state.js.map +1 -0
- package/dist/autonomy/scheduler.d.ts +18 -0
- package/dist/autonomy/scheduler.d.ts.map +1 -0
- package/dist/autonomy/scheduler.js +113 -0
- package/dist/autonomy/scheduler.js.map +1 -0
- package/dist/autonomy/task-store.d.ts +44 -0
- package/dist/autonomy/task-store.d.ts.map +1 -0
- package/dist/autonomy/task-store.js +139 -0
- package/dist/autonomy/task-store.js.map +1 -0
- package/dist/autonomy/types.d.ts +164 -0
- package/dist/autonomy/types.d.ts.map +1 -0
- package/dist/autonomy/types.js +20 -0
- package/dist/autonomy/types.js.map +1 -0
- package/dist/bitrefill/contract.d.ts +60 -0
- package/dist/bitrefill/contract.d.ts.map +1 -0
- package/dist/bitrefill/contract.js +119 -0
- package/dist/bitrefill/contract.js.map +1 -0
- package/dist/context/compress.d.ts +65 -0
- package/dist/context/compress.d.ts.map +1 -0
- package/dist/context/compress.js +181 -0
- package/dist/context/compress.js.map +1 -0
- package/dist/engine.d.ts +20 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +23 -4
- package/dist/engine.js.map +1 -1
- package/dist/evidence.d.ts +62 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +47 -0
- package/dist/evidence.js.map +1 -0
- package/dist/flashnet/contract.d.ts +56 -0
- package/dist/flashnet/contract.d.ts.map +1 -0
- package/dist/flashnet/contract.js +100 -0
- package/dist/flashnet/contract.js.map +1 -0
- package/dist/funnel.d.ts +11 -0
- package/dist/funnel.d.ts.map +1 -1
- package/dist/funnel.js +62 -7
- package/dist/funnel.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/kaleidoswap/contract.js +1 -1
- package/dist/kaleidoswap/contract.js.map +1 -1
- package/dist/knowledge/bitcoin-copilot.d.ts.map +1 -1
- package/dist/knowledge/bitcoin-copilot.js +85 -2
- package/dist/knowledge/bitcoin-copilot.js.map +1 -1
- package/dist/providers/types.d.ts +17 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/qvac/index.d.ts +1 -1
- package/dist/qvac/index.d.ts.map +1 -1
- package/dist/qvac/index.js.map +1 -1
- package/dist/qvac/parse.d.ts +18 -0
- package/dist/qvac/parse.d.ts.map +1 -1
- package/dist/qvac/parse.js +1 -0
- package/dist/qvac/parse.js.map +1 -1
- package/dist/qvac/provider.d.ts +16 -0
- package/dist/qvac/provider.d.ts.map +1 -1
- package/dist/qvac/provider.js +40 -1
- package/dist/qvac/provider.js.map +1 -1
- package/dist/qvac/stream.d.ts +22 -0
- package/dist/qvac/stream.d.ts.map +1 -1
- package/dist/qvac/stream.js +33 -1
- package/dist/qvac/stream.js.map +1 -1
- package/dist/recipe/buy-asset-channel.d.ts +1 -1
- package/dist/recipe/buy-asset-channel.d.ts.map +1 -1
- package/dist/recipe/buy-asset-channel.js +4 -3
- package/dist/recipe/buy-asset-channel.js.map +1 -1
- package/dist/recipe/flashnet-swap.d.ts +35 -0
- package/dist/recipe/flashnet-swap.d.ts.map +1 -0
- package/dist/recipe/flashnet-swap.js +239 -0
- package/dist/recipe/flashnet-swap.js.map +1 -0
- package/dist/recipe/kaleidoswap-atomic.d.ts +1 -1
- package/dist/recipe/kaleidoswap-atomic.d.ts.map +1 -1
- package/dist/recipe/kaleidoswap-atomic.js +42 -20
- package/dist/recipe/kaleidoswap-atomic.js.map +1 -1
- package/dist/recipe/kaleidoswap-channel-order.d.ts.map +1 -1
- package/dist/recipe/kaleidoswap-channel-order.js +31 -10
- package/dist/recipe/kaleidoswap-channel-order.js.map +1 -1
- package/dist/recipe/kaleidoswap-price.d.ts.map +1 -1
- package/dist/recipe/kaleidoswap-price.js +7 -1
- package/dist/recipe/kaleidoswap-price.js.map +1 -1
- package/dist/recipe/runner.d.ts.map +1 -1
- package/dist/recipe/runner.js +43 -3
- package/dist/recipe/runner.js.map +1 -1
- package/dist/recipe/swap.d.ts.map +1 -1
- package/dist/recipe/swap.js +14 -1
- package/dist/recipe/swap.js.map +1 -1
- package/dist/tools/mcp.d.ts +19 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mcp.js +51 -9
- package/dist/tools/mcp.js.map +1 -1
- package/dist/wallet/confirm.d.ts.map +1 -1
- package/dist/wallet/confirm.js +1 -0
- package/dist/wallet/confirm.js.map +1 -1
- package/dist/wallet/contract.d.ts.map +1 -1
- package/dist/wallet/contract.js +20 -4
- package/dist/wallet/contract.js.map +1 -1
- package/package.json +5 -4
- package/skills/bitrefill/SKILL.md +152 -52
- package/skills/channel-manager/SKILL.md +59 -0
- package/skills/dca/SKILL.md +48 -0
- package/skills/flashnet-swaps/SKILL.md +158 -0
- package/skills/kaleido-lsps/SKILL.md +34 -17
- package/skills/kaleido-trading/SKILL.md +37 -13
- package/skills/liquidity-optimizer/SKILL.md +91 -0
- package/skills/merchant-finder/SKILL.md +2 -2
- package/skills/portfolio-manager/SKILL.md +67 -0
- package/skills/rgb-lightning-node/SKILL.md +38 -11
- package/skills/spark-wallet/SKILL.md +235 -0
- package/skills/wallet-assistant/SKILL.md +2 -2
- package/src/autonomy/autonomy.test.ts +348 -0
- package/src/autonomy/index.ts +50 -0
- package/src/autonomy/prompt.ts +48 -0
- package/src/autonomy/risk.ts +139 -0
- package/src/autonomy/run-state.ts +144 -0
- package/src/autonomy/scheduler.ts +120 -0
- package/src/autonomy/task-store.ts +167 -0
- package/src/autonomy/types.ts +186 -0
- package/src/bitrefill/contract.test.ts +89 -0
- package/src/bitrefill/contract.ts +190 -0
- package/src/context/compress.test.ts +120 -0
- package/src/context/compress.ts +230 -0
- package/src/engine.test.ts +34 -0
- package/src/engine.ts +35 -4
- package/src/evidence.test.ts +80 -0
- package/src/evidence.ts +114 -0
- package/src/flashnet/contract.test.ts +101 -0
- package/src/flashnet/contract.ts +164 -0
- package/src/funnel.mind.test.ts +390 -0
- package/src/funnel.ts +73 -8
- package/src/index.ts +92 -1
- package/src/kaleidoswap/contract.ts +1 -1
- package/src/knowledge/bitcoin-copilot.ts +96 -2
- package/src/providers/types.ts +18 -0
- package/src/qvac/index.ts +1 -0
- package/src/qvac/parse.ts +20 -0
- package/src/qvac/provider.test.ts +17 -0
- package/src/qvac/provider.ts +62 -2
- package/src/qvac/stream.test.ts +36 -0
- package/src/qvac/stream.ts +54 -1
- package/src/recipe/buy-asset-channel.test.ts +5 -0
- package/src/recipe/buy-asset-channel.ts +6 -3
- package/src/recipe/flashnet-swap.test.ts +114 -0
- package/src/recipe/flashnet-swap.ts +266 -0
- package/src/recipe/kaleidoswap-atomic.test.ts +24 -3
- package/src/recipe/kaleidoswap-atomic.ts +39 -20
- package/src/recipe/kaleidoswap-channel-order.test.ts +38 -0
- package/src/recipe/kaleidoswap-channel-order.ts +27 -9
- package/src/recipe/kaleidoswap-price.ts +7 -1
- package/src/recipe/recipe.test.ts +21 -0
- package/src/recipe/runner.ts +46 -3
- package/src/recipe/swap.ts +16 -1
- package/src/tools/mcp.live.test.ts +116 -0
- package/src/tools/mcp.parse.test.ts +37 -0
- package/src/tools/mcp.ts +55 -9
- package/src/wallet/confirm.test.ts +8 -0
- package/src/wallet/confirm.ts +1 -0
- package/src/wallet/contract.test.ts +10 -0
- package/src/wallet/contract.ts +26 -4
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-output compression — the "fit more into a tiny window" part.
|
|
3
|
+
*
|
|
4
|
+
* Tool results are the single biggest, most repetitive thing the engine pushes
|
|
5
|
+
* into a small on-device model's context. A merchant search returns 40 near
|
|
6
|
+
* identical rows; a tx history returns hundreds; a swap quote nests config the
|
|
7
|
+
* model never reads. Every round, the *raw* `JSON.stringify(result)` is fed back
|
|
8
|
+
* into history — so on a 2k-window 0.6B model the conversation drowns in JSON
|
|
9
|
+
* the model didn't need, crowding out the system prompt, the skill, and the
|
|
10
|
+
* actual question.
|
|
11
|
+
*
|
|
12
|
+
* `compressToolResult` is a structural crusher (the idea behind Headroom's
|
|
13
|
+
* SmartCrusher/ToolCrusher, reimplemented natively — no dependency, no network,
|
|
14
|
+
* no proxy, so it stays on-device and private). It walks the JSON and:
|
|
15
|
+
*
|
|
16
|
+
* • dedupes identical array items, then keeps the first/last few and replaces
|
|
17
|
+
* the middle with an honest `{ "__elided__": N }` marker,
|
|
18
|
+
* • caps nesting depth (deep config → a one-line summary),
|
|
19
|
+
* • truncates long *prose* strings (logs, descriptions),
|
|
20
|
+
*
|
|
21
|
+
* and never regresses: if crushing doesn't actually save tokens, the original
|
|
22
|
+
* is returned untouched.
|
|
23
|
+
*
|
|
24
|
+
* SAFETY: it never touches numbers, never elides whole objects, never truncates
|
|
25
|
+
* whitespace-free strings (addresses, BOLT11 invoices, txids, pubkeys), and
|
|
26
|
+
* never touches a value under a money/identity key (see DEFAULT_PRESERVE_KEYS).
|
|
27
|
+
* Amounts and recipients reach the model intact — the confirm readback is built
|
|
28
|
+
* deterministically from the resolved call anyway, but this keeps the model's
|
|
29
|
+
* own view honest too. Small results (below `minTokens`) are passed through
|
|
30
|
+
* verbatim so nothing changes for the common case.
|
|
31
|
+
*/
|
|
32
|
+
import { estimateTokens } from './budget.js';
|
|
33
|
+
/** Keys whose values are never elided or truncated — amounts, ids, recipients. */
|
|
34
|
+
export const DEFAULT_PRESERVE_KEYS = [
|
|
35
|
+
'amount',
|
|
36
|
+
'amount_sat',
|
|
37
|
+
'amount_sats',
|
|
38
|
+
'amount_msat',
|
|
39
|
+
'sat',
|
|
40
|
+
'sats',
|
|
41
|
+
'msat',
|
|
42
|
+
'value',
|
|
43
|
+
'fee',
|
|
44
|
+
'fee_sat',
|
|
45
|
+
'fee_sats',
|
|
46
|
+
'total',
|
|
47
|
+
'total_sats',
|
|
48
|
+
'balance',
|
|
49
|
+
'balance_sat',
|
|
50
|
+
'address',
|
|
51
|
+
'invoice',
|
|
52
|
+
'bolt11',
|
|
53
|
+
'payment_request',
|
|
54
|
+
'payment_hash',
|
|
55
|
+
'preimage',
|
|
56
|
+
'txid',
|
|
57
|
+
'tx_id',
|
|
58
|
+
'pubkey',
|
|
59
|
+
'node_id',
|
|
60
|
+
'recipient',
|
|
61
|
+
'destination',
|
|
62
|
+
'asset_id',
|
|
63
|
+
'contract_id',
|
|
64
|
+
'rate',
|
|
65
|
+
'price',
|
|
66
|
+
'price_usd',
|
|
67
|
+
];
|
|
68
|
+
/** A string with no whitespace is treated as an identifier (address/invoice/hash) and never truncated. */
|
|
69
|
+
function isIdentifierLike(s) {
|
|
70
|
+
return !/\s/.test(s);
|
|
71
|
+
}
|
|
72
|
+
function serialize(value) {
|
|
73
|
+
return typeof value === 'string' ? value : safeStringify(value);
|
|
74
|
+
}
|
|
75
|
+
function safeStringify(value) {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.stringify(value) ?? String(value);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return String(value);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Crush a tool result for inclusion in model context. Returns the original,
|
|
85
|
+
* verbatim, when it's small or when crushing wouldn't save tokens.
|
|
86
|
+
*/
|
|
87
|
+
export function compressToolResult(value, opts = {}) {
|
|
88
|
+
const cfg = {
|
|
89
|
+
minTokens: opts.minTokens ?? 200,
|
|
90
|
+
maxArrayItems: Math.max(2, opts.maxArrayItems ?? 8),
|
|
91
|
+
maxDepth: Math.max(1, opts.maxDepth ?? 6),
|
|
92
|
+
maxStringLength: opts.maxStringLength ?? 600,
|
|
93
|
+
dedupe: opts.dedupe ?? true,
|
|
94
|
+
preserve: new Set((opts.preserveKeys ?? DEFAULT_PRESERVE_KEYS).map((k) => k.toLowerCase())),
|
|
95
|
+
};
|
|
96
|
+
const original = serialize(value);
|
|
97
|
+
const originalTokens = estimateTokens(original);
|
|
98
|
+
// Below the floor, never touch it — correctness over savings for small results.
|
|
99
|
+
if (originalTokens < cfg.minTokens) {
|
|
100
|
+
return { content: original, originalTokens, compressedTokens: originalTokens, elided: 0, changed: false };
|
|
101
|
+
}
|
|
102
|
+
let elided = 0;
|
|
103
|
+
const crushed = crush(value, cfg, 0, false, () => {
|
|
104
|
+
elided += 1;
|
|
105
|
+
});
|
|
106
|
+
const content = serialize(crushed);
|
|
107
|
+
const compressedTokens = estimateTokens(content);
|
|
108
|
+
// Never regress: if crushing didn't actually shrink it, keep the original.
|
|
109
|
+
if (compressedTokens >= originalTokens) {
|
|
110
|
+
return { content: original, originalTokens, compressedTokens: originalTokens, elided: 0, changed: false };
|
|
111
|
+
}
|
|
112
|
+
return { content, originalTokens, compressedTokens, elided, changed: true };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Recursively crush a JSON-ish value.
|
|
116
|
+
*
|
|
117
|
+
* @param preserved when true, the value sits under a preserve key — kept verbatim.
|
|
118
|
+
* @param onElide called once per array item dropped (for stats).
|
|
119
|
+
*/
|
|
120
|
+
function crush(value, cfg, depth, preserved, onElide) {
|
|
121
|
+
if (value === null || value === undefined)
|
|
122
|
+
return value;
|
|
123
|
+
if (typeof value === 'string') {
|
|
124
|
+
if (preserved || isIdentifierLike(value))
|
|
125
|
+
return value;
|
|
126
|
+
if (cfg.maxStringLength > 0 && value.length > cfg.maxStringLength) {
|
|
127
|
+
const omitted = value.length - cfg.maxStringLength;
|
|
128
|
+
return `${value.slice(0, cfg.maxStringLength)}… (+${omitted} chars)`;
|
|
129
|
+
}
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
if (typeof value !== 'object')
|
|
133
|
+
return value; // number, boolean — never touched
|
|
134
|
+
// Beyond max depth, collapse to a one-line shape summary instead of the subtree.
|
|
135
|
+
if (depth >= cfg.maxDepth) {
|
|
136
|
+
if (Array.isArray(value))
|
|
137
|
+
return `[array: ${value.length} items]`;
|
|
138
|
+
return `[object: ${Object.keys(value).length} keys]`;
|
|
139
|
+
}
|
|
140
|
+
if (Array.isArray(value)) {
|
|
141
|
+
let items = value;
|
|
142
|
+
if (cfg.dedupe && items.length > cfg.maxArrayItems) {
|
|
143
|
+
const seen = new Set();
|
|
144
|
+
const unique = [];
|
|
145
|
+
for (const item of items) {
|
|
146
|
+
const key = safeStringify(item);
|
|
147
|
+
if (seen.has(key))
|
|
148
|
+
continue;
|
|
149
|
+
seen.add(key);
|
|
150
|
+
unique.push(item);
|
|
151
|
+
}
|
|
152
|
+
items = unique;
|
|
153
|
+
}
|
|
154
|
+
if (items.length <= cfg.maxArrayItems) {
|
|
155
|
+
return items.map((v) => crush(v, cfg, depth + 1, preserved, onElide));
|
|
156
|
+
}
|
|
157
|
+
// Keep the front and a little of the tail (Headroom's "anchors"); elide the
|
|
158
|
+
// middle with an honest marker so the model knows data was omitted and can
|
|
159
|
+
// ask a more specific question / call a narrower tool.
|
|
160
|
+
const keepFirst = Math.max(1, Math.ceil(cfg.maxArrayItems * 0.6));
|
|
161
|
+
const keepLast = Math.max(0, cfg.maxArrayItems - keepFirst);
|
|
162
|
+
const head = items.slice(0, keepFirst);
|
|
163
|
+
const tail = keepLast > 0 ? items.slice(items.length - keepLast) : [];
|
|
164
|
+
const droppedCount = items.length - head.length - tail.length;
|
|
165
|
+
for (let i = 0; i < droppedCount; i++)
|
|
166
|
+
onElide();
|
|
167
|
+
const out = head.map((v) => crush(v, cfg, depth + 1, preserved, onElide));
|
|
168
|
+
out.push({ __elided__: droppedCount, note: 'items omitted to fit context' });
|
|
169
|
+
for (const v of tail)
|
|
170
|
+
out.push(crush(v, cfg, depth + 1, preserved, onElide));
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
const obj = value;
|
|
174
|
+
const result = {};
|
|
175
|
+
for (const [key, v] of Object.entries(obj)) {
|
|
176
|
+
const keep = preserved || cfg.preserve.has(key.toLowerCase());
|
|
177
|
+
result[key] = crush(v, cfg, depth + 1, keep, onElide);
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=compress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../src/context/compress.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { ConfirmDecision, Message, ToolResult } from './types.js';
|
|
17
17
|
import type { LLMProvider } from './providers/types.js';
|
|
18
|
+
import type { InferenceMetrics } from './providers/types.js';
|
|
18
19
|
import type { ToolRegistry } from './tools/registry.js';
|
|
20
|
+
import { type ToolCrushOptions } from './context/compress.js';
|
|
19
21
|
export interface EngineOptions {
|
|
20
22
|
provider: LLMProvider;
|
|
21
23
|
tools: ToolRegistry;
|
|
@@ -23,6 +25,15 @@ export interface EngineOptions {
|
|
|
23
25
|
defaultSystem?: string;
|
|
24
26
|
/** Max reasoning↔tool rounds before forcing a stop. Default 5. */
|
|
25
27
|
defaultMaxTurns?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Crush verbose tool results before they're fed back into history, so a
|
|
30
|
+
* tiny on-device model's context window isn't drowned in repetitive JSON
|
|
31
|
+
* (merchant lists, tx history, nested quotes). `true` uses safe defaults;
|
|
32
|
+
* pass options to tune. Off by default — small results are never touched and
|
|
33
|
+
* amounts/addresses/invoices are always preserved (see compressToolResult).
|
|
34
|
+
* The `onToolResult` callback and `toolCalls` still carry the raw result.
|
|
35
|
+
*/
|
|
36
|
+
compressToolOutput?: boolean | ToolCrushOptions;
|
|
26
37
|
}
|
|
27
38
|
export interface AgenticOptions {
|
|
28
39
|
maxTurns?: number;
|
|
@@ -65,15 +76,24 @@ export interface AgenticResult {
|
|
|
65
76
|
messages: Message[];
|
|
66
77
|
/** Wall-clock duration of the whole agentic run, ms. */
|
|
67
78
|
latencyMs: number;
|
|
79
|
+
/** One receipt per model call in this agentic run. */
|
|
80
|
+
inference: InferenceMetrics[];
|
|
68
81
|
}
|
|
69
82
|
export declare class Engine {
|
|
70
83
|
private readonly provider;
|
|
71
84
|
private readonly registry;
|
|
72
85
|
private readonly defaultSystem?;
|
|
73
86
|
private readonly defaultMaxTurns;
|
|
87
|
+
private readonly compressOpts?;
|
|
74
88
|
constructor(opts: EngineOptions);
|
|
75
89
|
runAgentic(messages: Message[], opts?: AgenticOptions): Promise<AgenticResult>;
|
|
76
90
|
cancel(requestId: string): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Serialize a tool result for history, optionally crushing verbose JSON so
|
|
93
|
+
* it doesn't swamp a small context window. The raw result is unchanged for
|
|
94
|
+
* callbacks/logs — only the model-facing history copy is compressed.
|
|
95
|
+
*/
|
|
96
|
+
private toHistoryContent;
|
|
77
97
|
private safeExecute;
|
|
78
98
|
}
|
|
79
99
|
//# sourceMappingURL=engine.d.ts.map
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -13,16 +13,23 @@
|
|
|
13
13
|
* wherever the ToolSource lives (on the phone for the wallet), even when
|
|
14
14
|
* inference is delegated to a remote provider.
|
|
15
15
|
*/
|
|
16
|
+
import { compressToolResult } from './context/compress.js';
|
|
16
17
|
export class Engine {
|
|
17
18
|
provider;
|
|
18
19
|
registry;
|
|
19
20
|
defaultSystem;
|
|
20
21
|
defaultMaxTurns;
|
|
22
|
+
compressOpts;
|
|
21
23
|
constructor(opts) {
|
|
22
24
|
this.provider = opts.provider;
|
|
23
25
|
this.registry = opts.tools;
|
|
24
26
|
this.defaultSystem = opts.defaultSystem;
|
|
25
27
|
this.defaultMaxTurns = opts.defaultMaxTurns ?? 5;
|
|
28
|
+
this.compressOpts = opts.compressToolOutput
|
|
29
|
+
? opts.compressToolOutput === true
|
|
30
|
+
? {}
|
|
31
|
+
: opts.compressToolOutput
|
|
32
|
+
: undefined;
|
|
26
33
|
}
|
|
27
34
|
async runAgentic(messages, opts = {}) {
|
|
28
35
|
const maxTurns = opts.maxTurns ?? this.defaultMaxTurns;
|
|
@@ -39,6 +46,7 @@ export class Engine {
|
|
|
39
46
|
let lastRequestId;
|
|
40
47
|
let finalText = '';
|
|
41
48
|
let turns = 0;
|
|
49
|
+
const inference = [];
|
|
42
50
|
for (let turn = 1; turn <= maxTurns; turn++) {
|
|
43
51
|
turns = turn;
|
|
44
52
|
if (opts.signal?.aborted)
|
|
@@ -51,6 +59,8 @@ export class Engine {
|
|
|
51
59
|
signal: opts.signal,
|
|
52
60
|
});
|
|
53
61
|
lastRequestId = out.requestId;
|
|
62
|
+
if (out.inference)
|
|
63
|
+
inference.push(out.inference);
|
|
54
64
|
if (out.requestId)
|
|
55
65
|
opts.onStart?.(out.requestId, turn);
|
|
56
66
|
finalText = (out.text || '').trim();
|
|
@@ -79,10 +89,7 @@ export class Engine {
|
|
|
79
89
|
}
|
|
80
90
|
executed.push({ name: call.name, arguments: call.arguments, result });
|
|
81
91
|
opts.onToolResult?.({ name: call.name, arguments: call.arguments, result }, turn);
|
|
82
|
-
history.push({
|
|
83
|
-
role: 'tool',
|
|
84
|
-
content: typeof result === 'string' ? result : JSON.stringify(result),
|
|
85
|
-
});
|
|
92
|
+
history.push({ role: 'tool', content: this.toHistoryContent(result) });
|
|
86
93
|
}
|
|
87
94
|
if (turn === maxTurns && !finalText) {
|
|
88
95
|
finalText = 'I had to stop after several steps — please try a more specific request.';
|
|
@@ -99,11 +106,23 @@ export class Engine {
|
|
|
99
106
|
requestId: lastRequestId,
|
|
100
107
|
messages: history,
|
|
101
108
|
latencyMs: Date.now() - startedAt,
|
|
109
|
+
inference,
|
|
102
110
|
};
|
|
103
111
|
}
|
|
104
112
|
async cancel(requestId) {
|
|
105
113
|
await this.provider.cancel?.(requestId);
|
|
106
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Serialize a tool result for history, optionally crushing verbose JSON so
|
|
117
|
+
* it doesn't swamp a small context window. The raw result is unchanged for
|
|
118
|
+
* callbacks/logs — only the model-facing history copy is compressed.
|
|
119
|
+
*/
|
|
120
|
+
toHistoryContent(result) {
|
|
121
|
+
if (!this.compressOpts) {
|
|
122
|
+
return typeof result === 'string' ? result : JSON.stringify(result);
|
|
123
|
+
}
|
|
124
|
+
return compressToolResult(result, this.compressOpts).content;
|
|
125
|
+
}
|
|
107
126
|
async safeExecute(name, args) {
|
|
108
127
|
try {
|
|
109
128
|
return await this.registry.execute(name, args);
|
package/dist/engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hackathon evidence JSONL.
|
|
3
|
+
*
|
|
4
|
+
* This is deliberately transport-neutral: Node writes it to disk, React Native
|
|
5
|
+
* writes it to the app documents directory, and tests keep it in memory.
|
|
6
|
+
*/
|
|
7
|
+
import type { InferenceMetrics } from './providers/types.js';
|
|
8
|
+
export declare const EVIDENCE_SCHEMA: "kaleidomind.evidence.v1";
|
|
9
|
+
export type EvidenceSurface = 'desktop' | 'mobile' | 'cli' | 'test';
|
|
10
|
+
export type EvidenceEventType = 'model_load' | 'model_unload' | 'inference' | 'tool_call' | 'tool_result' | 'confirmation' | 'error';
|
|
11
|
+
export interface EvidenceEvent {
|
|
12
|
+
schema: typeof EVIDENCE_SCHEMA;
|
|
13
|
+
event: EvidenceEventType;
|
|
14
|
+
ts: string;
|
|
15
|
+
runId: string;
|
|
16
|
+
surface: EvidenceSurface;
|
|
17
|
+
model?: {
|
|
18
|
+
name: string;
|
|
19
|
+
version?: string;
|
|
20
|
+
source?: 'local' | 'delegated';
|
|
21
|
+
};
|
|
22
|
+
hardware?: {
|
|
23
|
+
device: string;
|
|
24
|
+
os?: string;
|
|
25
|
+
memoryGb?: number;
|
|
26
|
+
};
|
|
27
|
+
prompt?: string;
|
|
28
|
+
response?: string;
|
|
29
|
+
inference?: InferenceMetrics | InferenceMetrics[];
|
|
30
|
+
tool?: {
|
|
31
|
+
name: string;
|
|
32
|
+
arguments?: Record<string, unknown>;
|
|
33
|
+
result?: unknown;
|
|
34
|
+
};
|
|
35
|
+
confirmation?: {
|
|
36
|
+
tool: string;
|
|
37
|
+
approved: boolean;
|
|
38
|
+
reason?: string;
|
|
39
|
+
};
|
|
40
|
+
error?: {
|
|
41
|
+
name: string;
|
|
42
|
+
message: string;
|
|
43
|
+
};
|
|
44
|
+
meta?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
export type EvidenceInput = Omit<EvidenceEvent, 'schema' | 'ts'>;
|
|
47
|
+
export interface EvidenceIO {
|
|
48
|
+
appendLine(line: string): Promise<void>;
|
|
49
|
+
now(): Date;
|
|
50
|
+
}
|
|
51
|
+
export interface EvidenceRecorderOptions {
|
|
52
|
+
io: EvidenceIO;
|
|
53
|
+
sanitize?: (event: EvidenceEvent) => EvidenceEvent;
|
|
54
|
+
}
|
|
55
|
+
export declare class EvidenceRecorder {
|
|
56
|
+
private readonly opts;
|
|
57
|
+
constructor(opts: EvidenceRecorderOptions);
|
|
58
|
+
record(input: EvidenceInput): Promise<EvidenceEvent>;
|
|
59
|
+
}
|
|
60
|
+
/** Mask wallet secrets while preserving prompts, model output and benchmark value. */
|
|
61
|
+
export declare function sanitizeEvidenceEvent(event: EvidenceEvent): EvidenceEvent;
|
|
62
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,eAAO,MAAM,eAAe,EAAG,yBAAkC,CAAC;AAElE,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AACpE,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,cAAc,GACd,WAAW,GACX,WAAW,GACX,aAAa,GACb,cAAc,GACd,OAAO,CAAC;AAEZ,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,eAAe,CAAC;IAC/B,KAAK,EAAE,iBAAiB,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,MAAM,EAAE,MAAM,CAAC;QACf,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,gBAAgB,GAAG,gBAAgB,EAAE,CAAC;IAClD,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,OAAO,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,GAAG,IAAI,IAAI,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,UAAU,CAAC;IACf,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,aAAa,CAAC;CACpD;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,uBAAuB;IAEpD,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAU3D;AAkBD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAazE"}
|
package/dist/evidence.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const EVIDENCE_SCHEMA = 'kaleidomind.evidence.v1';
|
|
2
|
+
export class EvidenceRecorder {
|
|
3
|
+
opts;
|
|
4
|
+
constructor(opts) {
|
|
5
|
+
this.opts = opts;
|
|
6
|
+
}
|
|
7
|
+
async record(input) {
|
|
8
|
+
let event = {
|
|
9
|
+
...input,
|
|
10
|
+
schema: EVIDENCE_SCHEMA,
|
|
11
|
+
ts: this.opts.io.now().toISOString(),
|
|
12
|
+
};
|
|
13
|
+
event = (this.opts.sanitize ?? sanitizeEvidenceEvent)(event);
|
|
14
|
+
await this.opts.io.appendLine(JSON.stringify(event));
|
|
15
|
+
return event;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const SENSITIVE_KEYS = new Set([
|
|
19
|
+
'address',
|
|
20
|
+
'invoice',
|
|
21
|
+
'bolt11',
|
|
22
|
+
'seed',
|
|
23
|
+
'mnemonic',
|
|
24
|
+
'private_key',
|
|
25
|
+
'privateKey',
|
|
26
|
+
'access_token',
|
|
27
|
+
'accessToken',
|
|
28
|
+
'preimage',
|
|
29
|
+
]);
|
|
30
|
+
const PAYMENT_TOKEN = /\b(?:ln(?:bc|tb|bcrt)[0-9a-z]{20,}|(?:bc1|tb1|bcrt1)[0-9a-z]{20,})\b/gi;
|
|
31
|
+
/** Mask wallet secrets while preserving prompts, model output and benchmark value. */
|
|
32
|
+
export function sanitizeEvidenceEvent(event) {
|
|
33
|
+
const walk = (value, key) => {
|
|
34
|
+
if (key && SENSITIVE_KEYS.has(key))
|
|
35
|
+
return '[redacted]';
|
|
36
|
+
if (typeof value === 'string')
|
|
37
|
+
return value.replace(PAYMENT_TOKEN, '[payment-data-redacted]');
|
|
38
|
+
if (Array.isArray(value))
|
|
39
|
+
return value.map((item) => walk(item));
|
|
40
|
+
if (value && typeof value === 'object') {
|
|
41
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, walk(v, k)]));
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
return walk(event);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,eAAe,GAAG,yBAAkC,CAAC;AA4DlE,MAAM,OAAO,gBAAgB;IACE;IAA7B,YAA6B,IAA6B;QAA7B,SAAI,GAAJ,IAAI,CAAyB;IAAG,CAAC;IAE9D,KAAK,CAAC,MAAM,CAAC,KAAoB;QAC/B,IAAI,KAAK,GAAkB;YACzB,GAAG,KAAK;YACR,MAAM,EAAE,eAAe;YACvB,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;QACF,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,qBAAqB,CAAC,CAAC,KAAK,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,SAAS;IACT,SAAS;IACT,QAAQ;IACR,MAAM;IACN,UAAU;IACV,aAAa;IACb,YAAY;IACZ,cAAc;IACd,aAAa;IACb,UAAU;CACX,CAAC,CAAC;AAEH,MAAM,aAAa,GACjB,wEAAwE,CAAC;AAE3E,sFAAsF;AACtF,MAAM,UAAU,qBAAqB,CAAC,KAAoB;IACxD,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,GAAY,EAAW,EAAE;QACrD,IAAI,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,YAAY,CAAC;QACxD,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QAC9F,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACjE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAClF,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAkB,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Flashnet tool contract — AMM swaps on Spark.
|
|
3
|
+
*
|
|
4
|
+
* Flashnet is a Spark-native AMM (constant-product + V3 concentrated-liquidity
|
|
5
|
+
* pools). The agent surface is small and intent-aligned:
|
|
6
|
+
*
|
|
7
|
+
* flashnet_list_pools — discover pools by asset pair (read)
|
|
8
|
+
* flashnet_get_pool — pool details + reserves (read)
|
|
9
|
+
* flashnet_simulate_swap — quote a swap, no funds move (read)
|
|
10
|
+
* flashnet_execute_swap — SPEND, confirmation-gated (the swap itself)
|
|
11
|
+
* flashnet_get_balance — Spark wallet balance (BTC + tokens) as the
|
|
12
|
+
* AMM client sees it
|
|
13
|
+
*
|
|
14
|
+
* The model picks a pool, simulates to see the rate/output, optionally shows
|
|
15
|
+
* the user the quote, and then executes. The host's `FlashnetClient` (built
|
|
16
|
+
* over a `SparkWallet`) does the actual signing.
|
|
17
|
+
*
|
|
18
|
+
* Asset addresses on Flashnet:
|
|
19
|
+
* - BTC is a constant pubkey: `BTC_ASSET_PUBKEY` per network.
|
|
20
|
+
* - Tokens are Spark Bech32m token identifiers (or hex; the client coerces).
|
|
21
|
+
*
|
|
22
|
+
* Pure data — no deps, RN-safe.
|
|
23
|
+
*/
|
|
24
|
+
import type { ToolDef } from '../types.js';
|
|
25
|
+
import { InProcessToolSource } from '../tools/in-process.js';
|
|
26
|
+
export interface FlashnetToolDef extends ToolDef {
|
|
27
|
+
/** Moves funds → confirmation-gated. */
|
|
28
|
+
spend?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Canonical Flashnet tools. */
|
|
31
|
+
export declare const FLASHNET_TOOLS: FlashnetToolDef[];
|
|
32
|
+
/** All Flashnet tool names that move funds (confirmation-gated). */
|
|
33
|
+
export declare const FLASHNET_SPEND_TOOLS: Set<string>;
|
|
34
|
+
export declare function isFlashnetSpendTool(name: string): boolean;
|
|
35
|
+
export declare function getFlashnetTool(name: string): FlashnetToolDef | undefined;
|
|
36
|
+
/** A handler bound to one Flashnet tool. */
|
|
37
|
+
export type FlashnetHandler = (args: Record<string, unknown>) => Promise<unknown>;
|
|
38
|
+
export interface BindFlashnetOptions {
|
|
39
|
+
/** Skip tools without a handler instead of throwing (default false). */
|
|
40
|
+
allowMissing?: boolean;
|
|
41
|
+
/** ToolSource id for the registry (default 'flashnet'). */
|
|
42
|
+
id?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Bind Flashnet contract tools to in-process handlers → an InProcessToolSource.
|
|
46
|
+
*
|
|
47
|
+
* const source = bindFlashnetTools({
|
|
48
|
+
* flashnet_list_pools: async (a) => client.listPools(a),
|
|
49
|
+
* flashnet_get_pool: async ({ pool_id }) => client.getPoolDetails(pool_id),
|
|
50
|
+
* flashnet_simulate_swap: async (a) => client.simulateSwap(a),
|
|
51
|
+
* flashnet_execute_swap: async (a) => client.executeSwap(a),
|
|
52
|
+
* flashnet_get_balance: async () => client.getBalance(),
|
|
53
|
+
* });
|
|
54
|
+
*/
|
|
55
|
+
export declare function bindFlashnetTools(handlers: Record<string, FlashnetHandler>, opts?: BindFlashnetOptions): InProcessToolSource;
|
|
56
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/flashnet/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG7D,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,wCAAwC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAuBD,gCAAgC;AAChC,eAAO,MAAM,cAAc,EAAE,eAAe,EAoD3C,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAE5C,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEzE;AAED,4CAA4C;AAC5C,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAElF,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,EACzC,IAAI,GAAE,mBAAwB,GAC7B,mBAAmB,CAiBrB"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical Flashnet tool contract — AMM swaps on Spark.
|
|
3
|
+
*
|
|
4
|
+
* Flashnet is a Spark-native AMM (constant-product + V3 concentrated-liquidity
|
|
5
|
+
* pools). The agent surface is small and intent-aligned:
|
|
6
|
+
*
|
|
7
|
+
* flashnet_list_pools — discover pools by asset pair (read)
|
|
8
|
+
* flashnet_get_pool — pool details + reserves (read)
|
|
9
|
+
* flashnet_simulate_swap — quote a swap, no funds move (read)
|
|
10
|
+
* flashnet_execute_swap — SPEND, confirmation-gated (the swap itself)
|
|
11
|
+
* flashnet_get_balance — Spark wallet balance (BTC + tokens) as the
|
|
12
|
+
* AMM client sees it
|
|
13
|
+
*
|
|
14
|
+
* The model picks a pool, simulates to see the rate/output, optionally shows
|
|
15
|
+
* the user the quote, and then executes. The host's `FlashnetClient` (built
|
|
16
|
+
* over a `SparkWallet`) does the actual signing.
|
|
17
|
+
*
|
|
18
|
+
* Asset addresses on Flashnet:
|
|
19
|
+
* - BTC is a constant pubkey: `BTC_ASSET_PUBKEY` per network.
|
|
20
|
+
* - Tokens are Spark Bech32m token identifiers (or hex; the client coerces).
|
|
21
|
+
*
|
|
22
|
+
* Pure data — no deps, RN-safe.
|
|
23
|
+
*/
|
|
24
|
+
import { InProcessToolSource } from '../tools/in-process.js';
|
|
25
|
+
function t(name, description, properties = {}, required = [], spend = false) {
|
|
26
|
+
return {
|
|
27
|
+
name,
|
|
28
|
+
description,
|
|
29
|
+
spend,
|
|
30
|
+
requiresConfirmation: spend,
|
|
31
|
+
parameters: { type: 'object', properties, required },
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Canonical Flashnet tools. */
|
|
35
|
+
export const FLASHNET_TOOLS = [
|
|
36
|
+
t('flashnet_list_pools', "List Flashnet AMM pools. Filter by asset pair to find a venue for a swap (e.g. asset_a=BTC, asset_b=<USDB address> → pools that swap between them). Returns pools sorted by TVL by default. Use this BEFORE simulate_swap to pick a `pool_id`.", {
|
|
37
|
+
asset_a: { type: 'string', description: 'OPTIONAL — first asset address (BTC pubkey or Spark token id). Filters pools.' },
|
|
38
|
+
asset_b: { type: 'string', description: 'OPTIONAL — second asset address. Filters pools containing both assets.' },
|
|
39
|
+
sort: { type: 'string', description: 'OPTIONAL — sort order. Default TVL_DESC.', enum: ['TVL_DESC', 'TVL_ASC', 'VOLUME24H_DESC', 'VOLUME24H_ASC', 'CREATED_AT_DESC', 'CREATED_AT_ASC'] },
|
|
40
|
+
limit: { type: 'number', description: 'OPTIONAL — max pools (1–50, default 10).' },
|
|
41
|
+
}),
|
|
42
|
+
t('flashnet_get_pool', "Get a single pool's details — reserves, fees, current price, TVL. Use after flashnet_list_pools when the user wants to inspect a pool before swapping.", {
|
|
43
|
+
pool_id: { type: 'string', description: 'Pool id (LP pubkey) from flashnet_list_pools.' },
|
|
44
|
+
}, ['pool_id']),
|
|
45
|
+
t('flashnet_simulate_swap', "Simulate a swap WITHOUT executing — returns `amount_out`, `execution_price`, `price_impact_pct`, `fee_paid`. Read-only. Use this to quote the user before they confirm. The `amount_in` is in smallest units of `asset_in` (sats for BTC, smallest unit of the token).", {
|
|
46
|
+
pool_id: { type: 'string', description: 'Pool id from flashnet_list_pools.' },
|
|
47
|
+
asset_in_address: { type: 'string', description: 'Address of the asset the user is selling (BTC pubkey or Spark token id).' },
|
|
48
|
+
asset_out_address: { type: 'string', description: 'Address of the asset the user is buying.' },
|
|
49
|
+
amount_in: { type: 'string', description: 'Amount to swap, in smallest units of asset_in. Strings (BigInt-safe). e.g. "100000" for 100k sats.' },
|
|
50
|
+
}, ['pool_id', 'asset_in_address', 'asset_out_address', 'amount_in']),
|
|
51
|
+
t('flashnet_execute_swap', "SPEND: confirmation-gated. Execute a swap quoted by flashnet_simulate_swap. `min_amount_out` and `max_slippage_bps` cap the worst-case fill (basis points: 100 = 1%, 50 = 0.5%). Returns the swap request id and the amount actually received.", {
|
|
52
|
+
pool_id: { type: 'string', description: 'Pool id from flashnet_list_pools.' },
|
|
53
|
+
asset_in_address: { type: 'string' },
|
|
54
|
+
asset_out_address: { type: 'string' },
|
|
55
|
+
amount_in: { type: 'string', description: 'Amount to swap, smallest units.' },
|
|
56
|
+
min_amount_out: { type: 'string', description: 'Minimum acceptable output, smallest units. Calculate from simulate_swap.amount_out × (1 − max_slippage_bps/10000) and pass that — never trust the simulated value as-is.' },
|
|
57
|
+
max_slippage_bps: { type: 'number', description: 'Maximum slippage in basis points (default 50 = 0.5%). 100 = 1%, 500 = 5%.' },
|
|
58
|
+
}, ['pool_id', 'asset_in_address', 'asset_out_address', 'amount_in', 'min_amount_out'],
|
|
59
|
+
/* spend */ true),
|
|
60
|
+
t('flashnet_get_balance', "Get the Spark wallet's BTC + token balances as the Flashnet client sees them. Useful to verify the user has enough of asset_in before quoting or executing a swap. Returns `{ btc_sats, tokens: [{ address, balance, symbol?, decimals? }] }`."),
|
|
61
|
+
];
|
|
62
|
+
/** All Flashnet tool names that move funds (confirmation-gated). */
|
|
63
|
+
export const FLASHNET_SPEND_TOOLS = new Set(FLASHNET_TOOLS.filter((t) => t.spend).map((t) => t.name));
|
|
64
|
+
export function isFlashnetSpendTool(name) {
|
|
65
|
+
return FLASHNET_SPEND_TOOLS.has(name);
|
|
66
|
+
}
|
|
67
|
+
export function getFlashnetTool(name) {
|
|
68
|
+
return FLASHNET_TOOLS.find((t) => t.name === name);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Bind Flashnet contract tools to in-process handlers → an InProcessToolSource.
|
|
72
|
+
*
|
|
73
|
+
* const source = bindFlashnetTools({
|
|
74
|
+
* flashnet_list_pools: async (a) => client.listPools(a),
|
|
75
|
+
* flashnet_get_pool: async ({ pool_id }) => client.getPoolDetails(pool_id),
|
|
76
|
+
* flashnet_simulate_swap: async (a) => client.simulateSwap(a),
|
|
77
|
+
* flashnet_execute_swap: async (a) => client.executeSwap(a),
|
|
78
|
+
* flashnet_get_balance: async () => client.getBalance(),
|
|
79
|
+
* });
|
|
80
|
+
*/
|
|
81
|
+
export function bindFlashnetTools(handlers, opts = {}) {
|
|
82
|
+
const bound = [];
|
|
83
|
+
for (const def of FLASHNET_TOOLS) {
|
|
84
|
+
const handler = handlers[def.name];
|
|
85
|
+
if (!handler) {
|
|
86
|
+
if (opts.allowMissing)
|
|
87
|
+
continue;
|
|
88
|
+
throw new Error(`bindFlashnetTools: no handler for "${def.name}"`);
|
|
89
|
+
}
|
|
90
|
+
bound.push({
|
|
91
|
+
name: def.name,
|
|
92
|
+
description: def.description,
|
|
93
|
+
parameters: def.parameters,
|
|
94
|
+
requiresConfirmation: def.requiresConfirmation,
|
|
95
|
+
handler,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return new InProcessToolSource(opts.id ?? 'flashnet', bound);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/flashnet/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAa7D,SAAS,CAAC,CACR,IAAY,EACZ,WAAmB,EACnB,aAAoB,EAAE,EACtB,WAAqB,EAAE,EACvB,KAAK,GAAG,KAAK;IAEb,OAAO;QACL,IAAI;QACJ,WAAW;QACX,KAAK;QACL,oBAAoB,EAAE,KAAK;QAC3B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE;KACrD,CAAC;AACJ,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAsB;IAC/C,CAAC,CACC,qBAAqB,EACrB,gPAAgP,EAChP;QACE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+EAA+E,EAAE;QACzH,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wEAAwE,EAAE;QAClH,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE,IAAI,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,EAAE;QACxL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;KACnF,CACF;IAED,CAAC,CACC,mBAAmB,EACnB,wJAAwJ,EACxJ;QACE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+CAA+C,EAAE;KAC1F,EACD,CAAC,SAAS,CAAC,CACZ;IAED,CAAC,CACC,wBAAwB,EACxB,wQAAwQ,EACxQ;QACE,OAAO,EAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;QACvF,gBAAgB,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0EAA0E,EAAE;QAC9H,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0CAA0C,EAAE;QAC9F,SAAS,EAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oGAAoG,EAAE;KACzJ,EACD,CAAC,SAAS,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,CAAC,CAClE;IAED,CAAC,CACC,uBAAuB,EACvB,gPAAgP,EAChP;QACE,OAAO,EAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;QACvF,gBAAgB,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,SAAS,EAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;QACrF,cAAc,EAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0KAA0K,EAAE;QAC9N,gBAAgB,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2EAA2E,EAAE;KAChI,EACD,CAAC,SAAS,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAAE,gBAAgB,CAAC;IACnF,WAAW,CAAC,IAAI,CACjB;IAED,CAAC,CACC,sBAAsB,EACtB,gPAAgP,CACjP;CACF,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAgB,IAAI,GAAG,CACtD,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACzD,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACrD,CAAC;AAYD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAyC,EACzC,OAA4B,EAAE;IAE9B,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,YAAY;gBAAE,SAAS;YAChC,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;QACrE,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;YAC9C,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IACD,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,IAAI,UAAU,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC"}
|