@kaleidorg/mind 0.2.0 → 0.4.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 (130) hide show
  1. package/dist/capabilities.d.ts +4 -0
  2. package/dist/capabilities.d.ts.map +1 -1
  3. package/dist/capabilities.js +7 -0
  4. package/dist/capabilities.js.map +1 -1
  5. package/dist/engine.d.ts +9 -0
  6. package/dist/engine.d.ts.map +1 -1
  7. package/dist/engine.js +1 -0
  8. package/dist/engine.js.map +1 -1
  9. package/dist/funnel.d.ts +6 -0
  10. package/dist/funnel.d.ts.map +1 -1
  11. package/dist/funnel.js +26 -6
  12. package/dist/funnel.js.map +1 -1
  13. package/dist/index.d.ts +9 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +8 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/kaleidoswap/contract.d.ts +72 -0
  18. package/dist/kaleidoswap/contract.d.ts.map +1 -0
  19. package/dist/kaleidoswap/contract.js +125 -0
  20. package/dist/kaleidoswap/contract.js.map +1 -0
  21. package/dist/knowledge/btc-map.d.ts +87 -0
  22. package/dist/knowledge/btc-map.d.ts.map +1 -0
  23. package/dist/knowledge/btc-map.js +365 -0
  24. package/dist/knowledge/btc-map.js.map +1 -0
  25. package/dist/lsps1/contract.d.ts +55 -0
  26. package/dist/lsps1/contract.d.ts.map +1 -0
  27. package/dist/lsps1/contract.js +91 -0
  28. package/dist/lsps1/contract.js.map +1 -0
  29. package/dist/memory/store.d.ts +7 -1
  30. package/dist/memory/store.d.ts.map +1 -1
  31. package/dist/memory/store.js +43 -3
  32. package/dist/memory/store.js.map +1 -1
  33. package/dist/memory/types.d.ts +12 -0
  34. package/dist/memory/types.d.ts.map +1 -1
  35. package/dist/qvac/assistant.d.ts +73 -0
  36. package/dist/qvac/assistant.d.ts.map +1 -0
  37. package/dist/qvac/assistant.js +97 -0
  38. package/dist/qvac/assistant.js.map +1 -0
  39. package/dist/qvac/config.d.ts +64 -0
  40. package/dist/qvac/config.d.ts.map +1 -0
  41. package/dist/qvac/config.js +71 -0
  42. package/dist/qvac/config.js.map +1 -0
  43. package/dist/qvac/delegate.d.ts +48 -0
  44. package/dist/qvac/delegate.d.ts.map +1 -0
  45. package/dist/qvac/delegate.js +51 -0
  46. package/dist/qvac/delegate.js.map +1 -0
  47. package/dist/qvac/index.d.ts +19 -0
  48. package/dist/qvac/index.d.ts.map +1 -0
  49. package/dist/qvac/index.js +19 -0
  50. package/dist/qvac/index.js.map +1 -0
  51. package/dist/qvac/parse.d.ts +44 -0
  52. package/dist/qvac/parse.d.ts.map +1 -0
  53. package/dist/qvac/parse.js +28 -0
  54. package/dist/qvac/parse.js.map +1 -0
  55. package/dist/qvac/provider.d.ts +49 -0
  56. package/dist/qvac/provider.d.ts.map +1 -0
  57. package/dist/qvac/provider.js +68 -0
  58. package/dist/qvac/provider.js.map +1 -0
  59. package/dist/qvac/stream.d.ts +37 -0
  60. package/dist/qvac/stream.d.ts.map +1 -0
  61. package/dist/qvac/stream.js +29 -0
  62. package/dist/qvac/stream.js.map +1 -0
  63. package/dist/qvac/text.d.ts +19 -0
  64. package/dist/qvac/text.d.ts.map +1 -0
  65. package/dist/qvac/text.js +56 -0
  66. package/dist/qvac/text.js.map +1 -0
  67. package/dist/qvac/voice.d.ts +69 -0
  68. package/dist/qvac/voice.d.ts.map +1 -0
  69. package/dist/qvac/voice.js +51 -0
  70. package/dist/qvac/voice.js.map +1 -0
  71. package/dist/recipe/kaleidoswap-atomic.d.ts +27 -0
  72. package/dist/recipe/kaleidoswap-atomic.d.ts.map +1 -0
  73. package/dist/recipe/kaleidoswap-atomic.js +111 -0
  74. package/dist/recipe/kaleidoswap-atomic.js.map +1 -0
  75. package/dist/recipe/runner.d.ts.map +1 -1
  76. package/dist/recipe/runner.js +13 -1
  77. package/dist/recipe/runner.js.map +1 -1
  78. package/dist/skills/registry.d.ts.map +1 -1
  79. package/dist/skills/registry.js +20 -2
  80. package/dist/skills/registry.js.map +1 -1
  81. package/dist/wallet/confirm.d.ts +12 -0
  82. package/dist/wallet/confirm.d.ts.map +1 -0
  83. package/dist/wallet/confirm.js +67 -0
  84. package/dist/wallet/confirm.js.map +1 -0
  85. package/package.json +16 -1
  86. package/skills/README.md +6 -1
  87. package/skills/kaleido-lsps/SKILL.md +56 -0
  88. package/skills/kaleido-trading/SKILL.md +85 -18
  89. package/skills/merchant-finder/SKILL.md +87 -0
  90. package/skills/paid-data/SKILL.md +12 -0
  91. package/skills/wallet-assistant/SKILL.md +38 -0
  92. package/src/capabilities.ts +12 -0
  93. package/src/context/context.test.ts +6 -2
  94. package/src/engine.ts +6 -0
  95. package/src/funnel.ts +32 -7
  96. package/src/index.ts +43 -0
  97. package/src/kaleidoswap/contract.test.ts +147 -0
  98. package/src/kaleidoswap/contract.ts +212 -0
  99. package/src/knowledge/btc-map.test.ts +188 -0
  100. package/src/knowledge/btc-map.ts +446 -0
  101. package/src/lsps1/contract.test.ts +81 -0
  102. package/src/lsps1/contract.ts +132 -0
  103. package/src/memory/memory.test.ts +55 -0
  104. package/src/memory/store.ts +49 -4
  105. package/src/memory/types.ts +13 -0
  106. package/src/qvac/assistant.test.ts +132 -0
  107. package/src/qvac/assistant.ts +146 -0
  108. package/src/qvac/config.test.ts +44 -0
  109. package/src/qvac/config.ts +76 -0
  110. package/src/qvac/delegate.test.ts +68 -0
  111. package/src/qvac/delegate.ts +71 -0
  112. package/src/qvac/index.ts +72 -0
  113. package/src/qvac/parse.test.ts +52 -0
  114. package/src/qvac/parse.ts +57 -0
  115. package/src/qvac/provider.test.ts +107 -0
  116. package/src/qvac/provider.ts +124 -0
  117. package/src/qvac/stream.test.ts +79 -0
  118. package/src/qvac/stream.ts +56 -0
  119. package/src/qvac/text.test.ts +70 -0
  120. package/src/qvac/text.ts +60 -0
  121. package/src/qvac/voice.test.ts +151 -0
  122. package/src/qvac/voice.ts +122 -0
  123. package/src/recipe/kaleidoswap-atomic.test.ts +138 -0
  124. package/src/recipe/kaleidoswap-atomic.ts +117 -0
  125. package/src/recipe/runner.ts +13 -1
  126. package/src/skills/registry.ts +21 -2
  127. package/src/skills/skills.test.ts +42 -0
  128. package/src/wallet/confirm.test.ts +57 -0
  129. package/src/wallet/confirm.ts +74 -0
  130. package/skills/kaleido-wallet/SKILL.md +0 -28
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvE,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAuB1D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,KAAK,CAkCjF;AASD,kFAAkF;AAClF,eAAO,MAAM,eAAe,EAAE,aAuB7B,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,MAAM,GAAE,KAAK,EAAO,EAAE,QAAQ,GAAE,aAA+B;IAK3E,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKvB,uEAAuE;IACvE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAIlE,yEAAyE;IACzE,UAAU,IAAI,KAAK,CAAC,cAAc,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAMvD,yEAAyE;IACzE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAUnE,IAAI,IAAI,KAAK,EAAE;IAIf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIpC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAInC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;CAwBxF"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEvE,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAuB1D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,KAAK,CAkCjF;AA0BD,kFAAkF;AAClF,eAAO,MAAM,eAAe,EAAE,aAyB7B,CAAC;AAEF,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,MAAM,GAAE,KAAK,EAAO,EAAE,QAAQ,GAAE,aAA+B;IAK3E,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAKvB,uEAAuE;IACvE,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI;IAIlE,yEAAyE;IACzE,UAAU,IAAI,KAAK,CAAC,cAAc,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAMvD,yEAAyE;IACzE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAUnE,IAAI,IAAI,KAAK,EAAE;IAIf,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIpC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAInC;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;CAwBxF"}
@@ -68,6 +68,22 @@ const STOPWORDS = new Set([
68
68
  'have', 'has', 'are', 'was', 'can', 'will', 'please', 'today', 'now', 'get',
69
69
  'show', 'tell', 'how', 'much', 'many', 'about', 'into', 'over',
70
70
  ]);
71
+ /** Escape a string for safe inclusion in a regex. */
72
+ function reEscape(s) {
73
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
74
+ }
75
+ /**
76
+ * Match a trigger phrase in the query with WORD BOUNDARIES — so the
77
+ * `usd` trigger on a wallet skill doesn't fire on `usdt`/`usdc`, and
78
+ * `cafe` doesn't fire on `cafeteria`. Multi-word triggers ("near me")
79
+ * still work because spaces are already word boundaries.
80
+ */
81
+ function triggerMatches(query, trigger) {
82
+ const t = trigger.toLowerCase().trim();
83
+ if (!t)
84
+ return false;
85
+ return new RegExp(`\\b${reEscape(t)}\\b`).test(query);
86
+ }
71
87
  /** Default selector: score by meaningful keyword overlap; triggers weigh most. */
72
88
  export const keywordSelector = {
73
89
  select(query, skills) {
@@ -82,9 +98,11 @@ export const keywordSelector = {
82
98
  for (const w of hayWords)
83
99
  if (words.has(w))
84
100
  score += 1;
85
- // Strong boost for an explicit trigger appearing in the query.
101
+ // Strong boost for an explicit trigger appearing in the query — at a
102
+ // word boundary, so short triggers (`usd`, `eur`, `cafe`) don't leak
103
+ // into longer words (`usdt`, `europe`, `cafeteria`).
86
104
  for (const t of skill.triggers ?? [])
87
- if (q.includes(t.toLowerCase()))
105
+ if (triggerMatches(q, t))
88
106
  score += 3;
89
107
  if (score > bestScore) {
90
108
  bestScore = score;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/skills/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Confirm-sheet readback — a deterministic, voice-first summary of a spend that
3
+ * the host speaks before executing it ("Send 4,800 sats to bob over Spark.
4
+ * Confirm?"). Built from the resolved tool call, not the model: zero inference,
5
+ * identical on every surface, and impossible for the model to phrase around.
6
+ */
7
+ /** A spoken confirmation ending in "Confirm?", or null for non-spend tools. */
8
+ export declare function confirmReadback(call: {
9
+ name: string;
10
+ arguments: Record<string, unknown>;
11
+ }): string | null;
12
+ //# sourceMappingURL=confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/wallet/confirm.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyCH,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CA0BzG"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Confirm-sheet readback — a deterministic, voice-first summary of a spend that
3
+ * the host speaks before executing it ("Send 4,800 sats to bob over Spark.
4
+ * Confirm?"). Built from the resolved tool call, not the model: zero inference,
5
+ * identical on every surface, and impossible for the model to phrase around.
6
+ */
7
+ import { getWalletTool } from './contract.js';
8
+ const LAYER_LABEL = {
9
+ spark: 'Spark',
10
+ rln: 'RLN',
11
+ arkade: 'Arkade',
12
+ liquid: 'Liquid',
13
+ };
14
+ /** Group an integer with thousands separators, locale-independently (test-stable). */
15
+ function fmtNum(n) {
16
+ if (!Number.isFinite(n))
17
+ return String(n);
18
+ const neg = n < 0;
19
+ const [int, frac] = Math.abs(n).toString().split('.');
20
+ const grouped = int.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
21
+ return (neg ? '-' : '') + (frac ? `${grouped}.${frac}` : grouped);
22
+ }
23
+ /** Looks like an address/invoice/lnurl (vs a human contact name). */
24
+ function isRef(s) {
25
+ return /^(ln(bc|tb|bcrt)|bc1|tb1|lq1|lnurl)/i.test(s) || (s.length > 20 && !/\s/.test(s));
26
+ }
27
+ /** Shorten an address/invoice for speech; leave contact names intact. */
28
+ function shortRef(s) {
29
+ const v = s.trim();
30
+ return isRef(v) ? `${v.slice(0, 6)}…${v.slice(-4)}` : v;
31
+ }
32
+ /** " over Spark" suffix for the call's layer (explicit arg wins, else the tool's). */
33
+ function over(name, args) {
34
+ const layer = typeof args.layer === 'string' ? args.layer : getWalletTool(name)?.layer;
35
+ const label = layer ? LAYER_LABEL[layer] : undefined;
36
+ return label ? ` over ${label}` : '';
37
+ }
38
+ const sats = (v) => `${fmtNum(Number(v))} sats`;
39
+ const asset = (amount, ticker) => `${fmtNum(Number(amount))} ${String(ticker)}`;
40
+ /** A spoken confirmation ending in "Confirm?", or null for non-spend tools. */
41
+ export function confirmReadback(call) {
42
+ const { name, arguments: a } = call;
43
+ const to = (k = 'to') => shortRef(String(a[k] ?? ''));
44
+ const ask = (s) => `${s}. Confirm?`;
45
+ switch (name) {
46
+ case 'send_payment': {
47
+ const amt = a.amount_sats != null ? sats(a.amount_sats)
48
+ : a.asset != null && a.amount != null ? asset(a.amount, a.asset)
49
+ : undefined;
50
+ return ask(amt ? `Send ${amt} to ${to()}${over(name, a)}` : `Send a payment to ${to()}${over(name, a)}`);
51
+ }
52
+ case 'spark_send':
53
+ case 'arkade_send':
54
+ return ask(`Send ${sats(a.amount_sats)} to ${to()}${over(name, a)}`);
55
+ case 'rln_send_asset':
56
+ case 'liquid_send':
57
+ return ask(`Send ${asset(a.amount, a.asset)} to ${to()}${over(name, a)}`);
58
+ case 'rln_pay_invoice':
59
+ return ask(`Pay Lightning invoice ${shortRef(String(a.invoice ?? ''))}${over(name, a)}`);
60
+ case 'execute_swap':
61
+ return ask(`Swap ${fmtNum(Number(a.amount))} ${String(a.from_asset)} for ${String(a.to_asset)}`);
62
+ default:
63
+ // Unknown but spend-flagged tool → a generic, still-honest readback.
64
+ return getWalletTool(name)?.spend ? ask(`Confirm ${name.replace(/_/g, ' ')}`) : null;
65
+ }
66
+ }
67
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/wallet/confirm.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaleidorg/mind",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Local-first reasoning + function-calling engine for KaleidoSwap. QVAC-powered.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -34,6 +34,11 @@
34
34
  "types": "./dist/logger.d.ts",
35
35
  "import": "./dist/logger.js",
36
36
  "default": "./dist/logger.js"
37
+ },
38
+ "./qvac": {
39
+ "types": "./dist/qvac/index.d.ts",
40
+ "import": "./dist/qvac/index.js",
41
+ "default": "./dist/qvac/index.js"
37
42
  }
38
43
  },
39
44
  "files": [
@@ -51,7 +56,17 @@
51
56
  "lint": "eslint src",
52
57
  "bundle-skills": "node scripts/bundle-skills.mjs"
53
58
  },
59
+ "peerDependencies": {
60
+ "@qvac/sdk": ">=0.12.2"
61
+ },
62
+ "peerDependenciesMeta": {
63
+ "@qvac/sdk": {
64
+ "optional": true
65
+ }
66
+ },
54
67
  "devDependencies": {
68
+ "@qvac/sdk": "^0.13.1",
69
+ "@types/node": "^20.0.0",
55
70
  "vitest": "^1.6.0"
56
71
  }
57
72
  }
package/skills/README.md CHANGED
@@ -70,5 +70,10 @@ Then per query: `const skill = registry.select(query)` →
70
70
  `https://api.bitrefill.com/mcp` (needs `BITREFILL_API_KEY` — anonymous = 401).
71
71
  Source: https://github.com/bitrefill/agents (MIT). Update with
72
72
  `npx skills add bitrefill/agents` or re-vendor the folder.
73
- - **kaleido-wallet/** — balances, receive, pay, channels over `kaleido-mcp`.
73
+ - **wallet-assistant/** — everyday wallet tasks (balance, receive, send, pay,
74
+ price, fiat→sats, resolve a contact). Resolves to host-bound `wallet/contract.ts`
75
+ tools (in-process WDK on mobile, MCP on desktop).
76
+ - **merchant-finder/** — find Bitcoin-accepting merchants via BTC Map. Live
77
+ data when the host injects a fetch + location; bundled offline list otherwise.
78
+ - **paid-data/** — fetch L402-paywalled resources via `fetch_paid_resource`.
74
79
  - **kaleido-trading/** — prices, quotes, atomic swaps, LSP channels.
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: kaleido-lsps
3
+ description: "Buy inbound Lightning channel capacity from a Lightning Service Provider (LSPS1). Quote, estimate fees, and create a channel order. Triggers when the user wants inbound liquidity, can't receive a payment, needs a channel, or asks about LSP fees."
4
+ tools: lsp_get_info, lsp_get_network_info, lsp_estimate_fees, lsp_create_order, lsp_get_order
5
+ triggers: inbound, liquidity, channel order, lsp, lsps1, receive limit, can't receive, open channel
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.1.0"
9
+ ---
10
+
11
+ # Lightning channel orders (LSPS1)
12
+
13
+ Buy inbound Lightning channel capacity from a Lightning Service Provider when
14
+ the user can't receive a payment (no inbound liquidity) or wants a bigger
15
+ receive limit. The host binds these to whichever LSP it talks to — the
16
+ KaleidoSwap maker by default, but the contract is LSP-agnostic (`lsp_*`).
17
+
18
+ ## Critical rules
19
+
20
+ You have **no knowledge of LSP fees, channel sizes, or order status**. Every
21
+ number, capacity, fee, or order id in your reply MUST come from a tool result
22
+ returned in the CURRENT turn. Never quote a fee from memory. Never claim an
23
+ order completed without calling `lsp_get_order`. Never reuse a number from a
24
+ previous turn.
25
+
26
+ **Calling the tool IS the answer.** Don't write "the LSP info is fetched with
27
+ `lsp_get_info`" — call it.
28
+
29
+ If a tool needs a required argument the user didn't give (e.g. an `order_id`
30
+ when polling), ASK. Don't loop the same failing call.
31
+
32
+ ## Flow
33
+
34
+ 1. **Check the LSP first.** Call `lsp_get_info` once per session to learn the
35
+ min/max channel size and the fee structure. Use those numbers to validate
36
+ the user's request (e.g. "200k sats" against `min_channel_sat`).
37
+ 2. **Estimate before ordering.** Call `lsp_estimate_fees` with the desired
38
+ `lsp_balance_sat`. Surface the total cost explicitly — never hide it.
39
+ 3. **Show + confirm.** State: inbound capacity requested, total fee, expiry
40
+ (if applicable), and the LSP node URI from `lsp_get_network_info` (so the
41
+ user knows the counterparty). The next step is spend-gated.
42
+ 4. **Create the order.** Call `lsp_create_order` with the same parameters.
43
+ The host pauses for explicit confirmation. Returns an `order_id` and a
44
+ Lightning invoice the user must pay to lock the order.
45
+ 5. **Track it.** Poll `lsp_get_order` until the channel opens (status
46
+ `completed`) or fails. Report the outcome plainly.
47
+
48
+ ## Rules
49
+
50
+ - **Re-estimate when parameters change.** Don't reuse an estimate across
51
+ different channel sizes or expiries.
52
+ - **Never invent capacity / fees / pubkeys.** Tool results are the truth.
53
+ - **Lightning over on-chain for ordering.** LSPS1 orders are paid by
54
+ Lightning invoice; if Lightning isn't available, say so and stop.
55
+ - **A channel order is not the same as a payment.** Make this explicit when
56
+ the user confuses them.
@@ -1,31 +1,98 @@
1
1
  ---
2
2
  name: kaleido-trading
3
- description: "Trade and manage a portfolio on KaleidoSwap: get live prices and market data, quote and place atomic swaps between BTC and RGB assets (USDT, XAUT), acquire inbound liquidity from the LSP, and check positions. Triggers when the user wants a price, a quote, to swap or trade assets, to rebalance a portfolio, or to acquire a Lightning channel from the LSP."
4
- tools: get_price, get_market_data, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_place_order, kaleidoswap_get_order_status, kaleidoswap_get_position, kaleidoswap_lsp_get_info, kaleidoswap_lsp_create_order
5
- triggers: price, quote, swap, trade, rebalance, portfolio, market, slippage, liquidity, channel order
3
+ description: "Trade on KaleidoSwap quote and execute swaps between BTC and RGB assets (USDT, XAUT). Get assets and pairs, pull an executable quote, place a market order, or track an atomic swap end-to-end. Triggers when the user wants a price, a quote, to swap or trade assets, or to rebalance between BTC and stablecoins."
4
+ tools: get_price, fiat_to_sats, kaleidoswap_get_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_get_nodeinfo, kaleidoswap_place_order, kaleidoswap_get_order_status, kaleidoswap_get_order_history
5
+ triggers: quote, swap, trade, rebalance, slippage, pair, pairs, usdt, xaut, kaleidoswap, rfq
6
6
  metadata:
7
7
  author: kaleidoswap
8
- version: "0.1.0"
9
- surface: "kaleido-mcp (KaleidoSwap maker + market data)"
8
+ version: "0.3.0"
10
9
  ---
11
10
 
12
11
  # KaleidoSwap trading
13
12
 
14
- Quote, swap, and manage a portfolio through the KaleidoSwap maker and market
15
- data MCP tools.
13
+ Quote and execute swaps on the KaleidoSwap maker. The model picks tools by
14
+ name; the host binds them through whichever transport it runs over (WDK on
15
+ mobile, HTTP/MCP/CLI on desktop).
16
+
17
+ ## Critical rules — these override everything else
18
+
19
+ You have **no knowledge** of any price, quote, fee, pair, or order. Every
20
+ number, pair, or quote id in your reply MUST come from a tool result returned
21
+ in the CURRENT turn:
22
+
23
+ - "What's the BTC price?" → call `get_price` and state the number it returns.
24
+ - "What pairs are listed?" → call `kaleidoswap_get_pairs` and list them.
25
+ - "Quote 100k sats to USDT" → call `kaleidoswap_get_quote(BTC, USDT, 100000)`,
26
+ then state the receive amount + fees from the result.
27
+
28
+ **Calling the tool IS the answer.** Never write "the pairs are listed using
29
+ kaleidoswap_get_pairs" or "the function returns the quote" — just call it.
30
+
31
+ **Never reuse a number across turns.** If the user asks a new question, the
32
+ previous turn's quote, price, or fee is irrelevant — fetch fresh.
33
+
34
+ **Never invent a quote.** Without a `quote_id` and `receive_amount` returned
35
+ this turn, you do not have a quote. Say so and re-quote.
36
+
37
+ ## Asset codes (canonical)
38
+
39
+ Only these codes are accepted:
40
+
41
+ - `BTC` (Bitcoin, amounts always in satoshis)
42
+ - `USDT` (Tether) — **not** `USD`, **not** `tether`
43
+ - `XAUT` (Tether Gold) — **not** `XAU`, **not** `gold`
44
+
45
+ When the user types `USD` they almost always mean `USDT` — confirm before
46
+ quoting. Same for `gold` → `XAUT`. Don't silently substitute.
47
+
48
+ ## Tools
49
+
50
+ ### `kaleidoswap_get_pairs` — no args
51
+ Use when the user asks "what can I trade", "list pairs", "what's available",
52
+ or before quoting an unfamiliar pair.
53
+
54
+ ### `kaleidoswap_get_quote` — REQUIRES `amount`
55
+ Required args: `from_asset` AND `to_asset` AND `amount`. The maker rejects
56
+ calls missing any of these.
57
+
58
+ **If the user didn't give an amount, ASK for it. Do not call the tool with
59
+ from/to alone.**
60
+
61
+ Examples:
62
+ - "Quote 100k sats to USDT" → `{from_asset: "BTC", to_asset: "USDT", amount: 100000}`
63
+ - "What's the USDT/BTC rate?" → ask: "How many USDT do you want to swap?"
64
+ (no amount → no quote possible).
65
+ - "Buy 50 USDT of BTC" → `{from_asset: "USDT", to_asset: "BTC", amount: 50}`
66
+ (USDT is what's being spent).
67
+
68
+ ### `kaleidoswap_place_order(quote_id)` 🔒 spend
69
+ Only after `kaleidoswap_get_quote` returned a `quote_id` THIS turn, and only
70
+ when the user has explicitly approved the amount + direction.
71
+
72
+ ### `kaleidoswap_get_order_status(order_id)`
73
+ Poll after placing an order. Report status plainly — pending, settling,
74
+ completed, failed.
16
75
 
17
76
  ## Flow
18
77
 
19
- 1. **Price first.** Use `get_price` / `get_market_data` for context and
20
- `kaleidoswap_get_quote` for an executable price before proposing a trade.
21
- 2. **Confirm the trade.** Show pair, direction, amount in, expected amount out,
22
- and fees. Wait for explicit approval before `kaleidoswap_place_order`.
23
- 3. **Track it.** After placing, poll `kaleidoswap_get_order_status` until the
24
- swap settles, then report the result and the new `kaleidoswap_get_position`.
25
- 4. **Need inbound liquidity?** If a swap can't route for lack of a channel, use
26
- `kaleidoswap_lsp_get_info` then `kaleidoswap_lsp_create_order` to buy one.
78
+ 1. **Pick a pair** — skip when obvious (`BTC/USDT`, `BTC/XAUT`).
79
+ 2. **Quote** `kaleidoswap_get_quote`. REQUIRES amount.
80
+ 3. **Show + confirm** surface pair, direction, amount in, expected out,
81
+ fees, slippage. **Never hide cost** a small model must not abbreviate
82
+ fees out of the message.
83
+ 4. **Place** spend-gated by the engine. The host pauses for the user.
84
+ 5. **Track** poll `kaleidoswap_get_order_status` until it terminates.
85
+
86
+ ## Don'ts
27
87
 
28
- ## Rules
88
+ - Don't invent prices, quotes, quote_ids, or order_ids.
89
+ - Don't reuse a number from a previous turn.
90
+ - Don't describe how a tool works — call it.
91
+ - Don't call `kaleidoswap_get_quote` with from/to only — ask for the amount.
92
+ - Don't accept `XAU` as `XAUT` or `USD` as `USDT` silently — confirm.
93
+ - Don't retry the same failing tool call in a loop. If a call fails, read the
94
+ error and either ask the user, fix the args, or stop.
29
95
 
30
- - Never trade on a stale quote re-quote if the user hesitates.
31
- - Surface slippage and fees explicitly; small local models must not hide cost.
96
+ For the atomic-swap flow (trust-minimised cross-asset swap that the maker
97
+ can't settle from balance), use the `kaleido-trading` atomic recipe the
98
+ agentic chain is not safe to plan on a 0.6B model.
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: merchant-finder
3
+ description: "Find Bitcoin-accepting merchants near the user using live BTC Map data and the device's real location. Triggers when the user asks where to spend Bitcoin, for a shop, store, restaurant, cafe, bar, or ATM that accepts Bitcoin, or for merchants nearby."
4
+ tools: find_merchant_locations, get_merchant_info
5
+ triggers: merchant, merchants, shop, shops, store, stores, restaurant, restaurants, cafe, cafes, bar, bars, atm, atms, accept, accepts, accepting, nearby, near me, around, place, places, spend, find, pizza, food, coffee, bitcoin map, btcmap
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.2.0"
9
+ homepage: "https://btcmap.org"
10
+ ---
11
+
12
+ # Merchant finder
13
+
14
+ Discover places that accept Bitcoin payments — cafés, restaurants, bars, shops,
15
+ and ATMs. Live BTC Map data when the host injects a fetcher + location;
16
+ otherwise a small offline list keeps the skill answerable.
17
+
18
+ ## Critical rule — never answer from memory
19
+
20
+ You have **no knowledge of any merchant**. Every place, name, address and
21
+ distance in your reply MUST come from a `find_merchant_locations` result
22
+ returned in the CURRENT turn. **Call `find_merchant_locations` for every
23
+ place question**, even if a similar question was answered earlier — do NOT
24
+ reuse or adapt a previous answer. Never invent a merchant.
25
+
26
+ ## How to call the tools
27
+
28
+ 1. **Start with `find_merchant_locations`.** Pass ONLY the fields the user
29
+ actually named — do not invent constraints:
30
+
31
+ - `query` — a specific thing the user named (e.g. `"tapas"`, `"coffee"`,
32
+ `"pizza"`). Omit when they only said "near me" or only named a place.
33
+
34
+ - `category` — must be EXACTLY one of: `restaurant`, `cafe`, `bar`, `shop`,
35
+ `grocery`, `lodging`, `atm`. **Anything else is invalid — leave it empty.**
36
+ The words "merchant", "merchants", "place", "places", "store", "stores"
37
+ are NOT categories — they're the generic noun for what you're searching
38
+ for, so they belong in `query` at best, never in `category`.
39
+
40
+ - `near_address` — a city, neighbourhood, or address (e.g. `"Milan"`,
41
+ `"Bitcoin Beach, El Salvador"`). Use this any time the user names a
42
+ location instead of "near me".
43
+
44
+ - `radius_km` — **omit unless the user names a specific number.** The
45
+ default (5 km) is a sensible search radius for a city. Don't pick a
46
+ small radius (1, 2, 3) yourself — city-wide searches need 5+.
47
+
48
+ - `limit` — 1–20, default 10. Omit unless the user names a count.
49
+
50
+ Examples (positive):
51
+ - "where can I spend btc near me" → `find_merchant_locations({})`
52
+ - "find merchants in Milan" → `find_merchant_locations({ near_address: "Milan" })`
53
+ ↑ no `category` — "merchants" is NOT a category.
54
+ - "cafes in Lisbon" → `find_merchant_locations({ category: "cafe", near_address: "Lisbon" })`
55
+ - "pizza places in Switzerland that take bitcoin" →
56
+ `find_merchant_locations({ query: "pizza", near_address: "Switzerland" })`
57
+ ↑ "places" is NOT a category — pizza goes in `query`.
58
+ - "lightning bars in NYC, within 2 km" →
59
+ `find_merchant_locations({ category: "bar", near_address: "New York", radius_km: 2 })`
60
+ ↑ user explicitly said "2 km" → set radius_km.
61
+
62
+ Examples (anti — do NOT do these):
63
+ - ❌ `category: "merchant"` (not a category)
64
+ - ❌ `category: "place"` (not a category)
65
+ - ❌ `radius_km: 2` when the user didn't say "2 km" — you're picking a
66
+ too-small radius and the result will be empty.
67
+
68
+ 2. **Present the results.** Each row carries:
69
+ - `name`, `category`, `address`
70
+ - `distance_m` when present — show in metres or km
71
+ - `accepts_bitcoin` / `accepts_lightning` — relevant because Lightning is
72
+ fastest for small payments
73
+ - `phone`, `website`, `opening_hours` when present — surface if asked
74
+
75
+ 3. **Use `get_merchant_info` only when** the user asks for more detail on one
76
+ specific result. Pass `merchant_id` (preferred) or `merchant_name`.
77
+
78
+ ## Reply style
79
+
80
+ - Be concise. One line per merchant works:
81
+ `Name — category, address (X m away, accepts: lightning, onchain)`.
82
+ - If the result `source` is `offline`, say so plainly — it means the live
83
+ BTC Map fetch wasn't available, so the list is limited.
84
+ - If `find_merchant_locations` returns zero merchants, say so — don't invent
85
+ places. Suggest widening `radius_km` or trying `near_address`.
86
+ - When the user says "near me" and `precise_location` is false, mention which
87
+ fallback location was used so they know it's not their actual GPS.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: paid-data
3
+ description: Fetch premium or paywalled data that requires a small Lightning (L402) payment — paid feeds, gated APIs, unlockable resources. Triggers when the user wants premium, paid, or unlockable data behind an L402 paywall.
4
+ tools: fetch_paid_resource
5
+ triggers: premium, paid, l402, feed, subscription, unlock, paywall
6
+ ---
7
+
8
+ # Paid data
9
+
10
+ Fetch L402-paywalled resources, paying small Lightning invoices automatically
11
+ with `fetch_paid_resource`. Small amounts pay without prompting (capped);
12
+ anything larger is declined. Tell the user what was paid and what was returned.
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: wallet-assistant
3
+ description: Everyday wallet tasks on this phone — check the BTC/asset balance, create an invoice to receive, send a payment, look up a contact, get the BTC price, or convert a fiat amount to sats. Triggers when the user asks about their balance, wants to receive or send money, pay an invoice, or pay a contact.
4
+ tools: get_balances, get_price, fiat_to_sats, resolve_contact, send_payment, rln_pay_invoice, rln_create_ln_invoice, spark_create_invoice
5
+ triggers: balance, pay, send, receive, address, invoice, transactions, contact, funds, money, price, sats, eur, gbp
6
+ ---
7
+
8
+ # Wallet assistant
9
+
10
+ You operate the user's on-device multi-L2 Bitcoin wallet. ALWAYS use a tool to
11
+ get real data — NEVER invent a balance, address, amount, price, or result.
12
+
13
+ ## Critical rules
14
+
15
+ You have no knowledge of balances, prices, addresses, or invoices. Every value
16
+ in your reply MUST come from a tool result returned in the CURRENT turn — do
17
+ not reuse a number from a previous turn.
18
+
19
+ When a tool returns multiple fields, **report all the load-bearing ones**:
20
+ - `get_balances` may return `{confirmed, pending, total}` — when `pending`
21
+ is non-zero, report BOTH. `confirmed` is spendable; `pending` is settling
22
+ and is NOT spendable yet. The user needs to know the difference.
23
+ - `fiat_to_sats` returns `{sats}` plus a `note` when the currency was an
24
+ approximation — surface the note.
25
+
26
+ ## Rules
27
+
28
+ - Balance / "how much do I have" → call `get_balances`, then state the number.
29
+ - Receive / "an invoice for N sats" → call `rln_create_ln_invoice` (or
30
+ `spark_create_invoice`) with the amount.
31
+ - Price → `get_price`. "How many sats is 3 EUR" → `fiat_to_sats`.
32
+ - Pay a Lightning invoice → `rln_pay_invoice`.
33
+ - Send to a person/amount → first `resolve_contact` (and `fiat_to_sats` if the
34
+ amount is in fiat), then `send_payment` with the amount in sats and the
35
+ recipient. State the amount and destination; the app asks the user to confirm
36
+ before it sends.
37
+
38
+ Keep replies short, but never drop a balance component or a fee.
@@ -25,6 +25,10 @@ export interface MindCapabilities {
25
25
  memory: boolean;
26
26
  /** Semantic recall for memory (needs embeddings). */
27
27
  semanticMemory: boolean;
28
+ /** Embedding-only dedup of near-duplicate memories (zero inference — mobile-safe). */
29
+ dedupeMemory: boolean;
30
+ /** LLM merge of near-duplicate memories (an extra inference — capable/delegated only). */
31
+ mergeMemory: boolean;
28
32
  /** Retrieval-augmented generation (needs embeddings + enough RAM/context). */
29
33
  rag: boolean;
30
34
  /** Token budget for injected system context. */
@@ -48,6 +52,12 @@ export function capabilityProfile(input: CapabilityInput): MindCapabilities {
48
52
  const memory = budget >= 256;
49
53
  const semanticMemory = memory && hasEmb;
50
54
 
55
+ // Consolidation: embedding-only dedup is cheap (no inference) — on wherever
56
+ // semantic memory is. The LLM merge costs an extra inference, so reserve it
57
+ // for delegated or roomy on-device setups; never run it on a tiny phone model.
58
+ const dedupeMemory = semanticMemory;
59
+ const mergeMemory = dedupeMemory && (input.delegated || (ramGb >= 4 && ctx >= 4096));
60
+
51
61
  // RAG is the expensive one: needs embeddings, a non-tiny context window, and
52
62
  // (on-device) enough RAM to hold an embedding model + index.
53
63
  const rag = hasEmb && ctx >= 4096 && (input.delegated || ramGb >= 3);
@@ -59,6 +69,8 @@ export function capabilityProfile(input: CapabilityInput): MindCapabilities {
59
69
  return {
60
70
  memory,
61
71
  semanticMemory,
72
+ dedupeMemory,
73
+ mergeMemory,
62
74
  rag,
63
75
  contextBudgetTokens: budget,
64
76
  topKMemory,
@@ -60,18 +60,22 @@ describe('ContextBuilder', () => {
60
60
  });
61
61
 
62
62
  describe('capabilityProfile', () => {
63
- it('low-end phone: memory yes, RAG no', () => {
63
+ it('low-end phone: memory yes, RAG no, dedup yes but no LLM merge', () => {
64
64
  const c = capabilityProfile({ ramBytes: 2 * 1024 ** 3, modelCtxTokens: 2048, hasEmbeddings: true });
65
65
  expect(c.memory).toBe(true);
66
66
  expect(c.rag).toBe(false); // ctx too small + low RAM
67
67
  expect(c.topKRag).toBe(0);
68
+ expect(c.dedupeMemory).toBe(true); // embedding-only dedup is mobile-safe
69
+ expect(c.mergeMemory).toBe(false); // never run merge inference on a tiny phone
68
70
  });
69
71
 
70
- it('desktop / delegated: RAG on', () => {
72
+ it('desktop / delegated: RAG on, memory merge on', () => {
71
73
  const c = capabilityProfile({ modelCtxTokens: 8192, hasEmbeddings: true, delegated: true });
72
74
  expect(c.rag).toBe(true);
73
75
  expect(c.topKRag).toBeGreaterThan(0);
74
76
  expect(c.semanticMemory).toBe(true);
77
+ expect(c.dedupeMemory).toBe(true);
78
+ expect(c.mergeMemory).toBe(true);
75
79
  });
76
80
 
77
81
  it('no embeddings → no RAG, no semantic memory', () => {
package/src/engine.ts CHANGED
@@ -35,6 +35,11 @@ export interface AgenticOptions {
35
35
  onStart?: (requestId: string, turn: number) => void;
36
36
  /** Fired when the model requests a tool, before it executes. */
37
37
  onToolCall?: (call: { name: string; arguments: Record<string, unknown> }, turn: number) => void;
38
+ /**
39
+ * Fired after a tool returns (success OR error — errors arrive as `{error}`).
40
+ * Useful for surfacing the raw response back to the user in a debug UI.
41
+ */
42
+ onToolResult?: (event: { name: string; arguments: Record<string, unknown>; result: unknown }, turn: number) => void;
38
43
  /** Human-in-the-loop gate for tools flagged requiresConfirmation. */
39
44
  onConfirm?: (call: { name: string; arguments: Record<string, unknown> }) => Promise<ConfirmDecision>;
40
45
  /**
@@ -127,6 +132,7 @@ export class Engine {
127
132
  }
128
133
 
129
134
  executed.push({ name: call.name, arguments: call.arguments, result });
135
+ opts.onToolResult?.({ name: call.name, arguments: call.arguments, result }, turn);
130
136
  history.push({
131
137
  role: 'tool',
132
138
  content: typeof result === 'string' ? result : JSON.stringify(result),