@kaleidorg/mind 0.1.0 → 0.3.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 (182) hide show
  1. package/dist/capabilities.d.ts +38 -0
  2. package/dist/capabilities.d.ts.map +1 -0
  3. package/dist/capabilities.js +41 -0
  4. package/dist/capabilities.js.map +1 -0
  5. package/dist/context/budget.d.ts +29 -0
  6. package/dist/context/budget.d.ts.map +1 -0
  7. package/dist/context/budget.js +36 -0
  8. package/dist/context/budget.js.map +1 -0
  9. package/dist/context/builder.d.ts +39 -0
  10. package/dist/context/builder.d.ts.map +1 -0
  11. package/dist/context/builder.js +77 -0
  12. package/dist/context/builder.js.map +1 -0
  13. package/dist/engine.d.ts +9 -0
  14. package/dist/engine.d.ts.map +1 -1
  15. package/dist/engine.js +1 -0
  16. package/dist/engine.js.map +1 -1
  17. package/dist/fastpath/fastpath.d.ts +38 -0
  18. package/dist/fastpath/fastpath.d.ts.map +1 -0
  19. package/dist/fastpath/fastpath.js +52 -0
  20. package/dist/fastpath/fastpath.js.map +1 -0
  21. package/dist/funnel.d.ts +117 -0
  22. package/dist/funnel.d.ts.map +1 -0
  23. package/dist/funnel.js +195 -0
  24. package/dist/funnel.js.map +1 -0
  25. package/dist/index.d.ts +44 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +36 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/kaleidoswap/contract.d.ts +72 -0
  30. package/dist/kaleidoswap/contract.d.ts.map +1 -0
  31. package/dist/kaleidoswap/contract.js +125 -0
  32. package/dist/kaleidoswap/contract.js.map +1 -0
  33. package/dist/knowledge/bitcoin-copilot.d.ts +11 -0
  34. package/dist/knowledge/bitcoin-copilot.d.ts.map +1 -0
  35. package/dist/knowledge/bitcoin-copilot.js +155 -0
  36. package/dist/knowledge/bitcoin-copilot.js.map +1 -0
  37. package/dist/knowledge/btc-map.d.ts +87 -0
  38. package/dist/knowledge/btc-map.d.ts.map +1 -0
  39. package/dist/knowledge/btc-map.js +365 -0
  40. package/dist/knowledge/btc-map.js.map +1 -0
  41. package/dist/knowledge/merchants.d.ts +24 -0
  42. package/dist/knowledge/merchants.d.ts.map +1 -0
  43. package/dist/knowledge/merchants.js +34 -0
  44. package/dist/knowledge/merchants.js.map +1 -0
  45. package/dist/knowledge/wallet.d.ts +34 -0
  46. package/dist/knowledge/wallet.d.ts.map +1 -0
  47. package/dist/knowledge/wallet.js +63 -0
  48. package/dist/knowledge/wallet.js.map +1 -0
  49. package/dist/lsps1/contract.d.ts +55 -0
  50. package/dist/lsps1/contract.d.ts.map +1 -0
  51. package/dist/lsps1/contract.js +91 -0
  52. package/dist/lsps1/contract.js.map +1 -0
  53. package/dist/memory/store.d.ts +40 -0
  54. package/dist/memory/store.d.ts.map +1 -0
  55. package/dist/memory/store.js +143 -0
  56. package/dist/memory/store.js.map +1 -0
  57. package/dist/memory/tool.d.ts +9 -0
  58. package/dist/memory/tool.d.ts.map +1 -0
  59. package/dist/memory/tool.js +70 -0
  60. package/dist/memory/tool.js.map +1 -0
  61. package/dist/memory/types.d.ts +68 -0
  62. package/dist/memory/types.d.ts.map +1 -0
  63. package/dist/memory/types.js +14 -0
  64. package/dist/memory/types.js.map +1 -0
  65. package/dist/rag/retriever.d.ts +30 -0
  66. package/dist/rag/retriever.d.ts.map +1 -0
  67. package/dist/rag/retriever.js +72 -0
  68. package/dist/rag/retriever.js.map +1 -0
  69. package/dist/rag/tool.d.ts +15 -0
  70. package/dist/rag/tool.d.ts.map +1 -0
  71. package/dist/rag/tool.js +42 -0
  72. package/dist/rag/tool.js.map +1 -0
  73. package/dist/rag/types.d.ts +44 -0
  74. package/dist/rag/types.d.ts.map +1 -0
  75. package/dist/rag/types.js +11 -0
  76. package/dist/rag/types.js.map +1 -0
  77. package/dist/rag/vector-store.d.ts +23 -0
  78. package/dist/rag/vector-store.d.ts.map +1 -0
  79. package/dist/rag/vector-store.js +72 -0
  80. package/dist/rag/vector-store.js.map +1 -0
  81. package/dist/recipe/asset-send.d.ts +15 -0
  82. package/dist/recipe/asset-send.d.ts.map +1 -0
  83. package/dist/recipe/asset-send.js +83 -0
  84. package/dist/recipe/asset-send.js.map +1 -0
  85. package/dist/recipe/kaleidoswap-atomic.d.ts +27 -0
  86. package/dist/recipe/kaleidoswap-atomic.d.ts.map +1 -0
  87. package/dist/recipe/kaleidoswap-atomic.js +111 -0
  88. package/dist/recipe/kaleidoswap-atomic.js.map +1 -0
  89. package/dist/recipe/payments.d.ts +15 -0
  90. package/dist/recipe/payments.d.ts.map +1 -0
  91. package/dist/recipe/payments.js +119 -0
  92. package/dist/recipe/payments.js.map +1 -0
  93. package/dist/recipe/receive.d.ts +14 -0
  94. package/dist/recipe/receive.d.ts.map +1 -0
  95. package/dist/recipe/receive.js +109 -0
  96. package/dist/recipe/receive.js.map +1 -0
  97. package/dist/recipe/runner.d.ts +42 -0
  98. package/dist/recipe/runner.d.ts.map +1 -0
  99. package/dist/recipe/runner.js +106 -0
  100. package/dist/recipe/runner.js.map +1 -0
  101. package/dist/recipe/swap.d.ts +16 -0
  102. package/dist/recipe/swap.d.ts.map +1 -0
  103. package/dist/recipe/swap.js +73 -0
  104. package/dist/recipe/swap.js.map +1 -0
  105. package/dist/recipe/types.d.ts +71 -0
  106. package/dist/recipe/types.d.ts.map +1 -0
  107. package/dist/recipe/types.js +13 -0
  108. package/dist/recipe/types.js.map +1 -0
  109. package/dist/skills/registry.d.ts.map +1 -1
  110. package/dist/skills/registry.js +20 -2
  111. package/dist/skills/registry.js.map +1 -1
  112. package/dist/tools/cli.d.ts +43 -0
  113. package/dist/tools/cli.d.ts.map +1 -0
  114. package/dist/tools/cli.js +61 -0
  115. package/dist/tools/cli.js.map +1 -0
  116. package/dist/tools/mcp.d.ts +3 -2
  117. package/dist/tools/mcp.d.ts.map +1 -1
  118. package/dist/tools/mcp.js +3 -2
  119. package/dist/tools/mcp.js.map +1 -1
  120. package/dist/wallet/confirm.d.ts +12 -0
  121. package/dist/wallet/confirm.d.ts.map +1 -0
  122. package/dist/wallet/confirm.js +67 -0
  123. package/dist/wallet/confirm.js.map +1 -0
  124. package/dist/wallet/contract.d.ts +57 -0
  125. package/dist/wallet/contract.d.ts.map +1 -0
  126. package/dist/wallet/contract.js +113 -0
  127. package/dist/wallet/contract.js.map +1 -0
  128. package/package.json +10 -5
  129. package/skills/README.md +6 -1
  130. package/skills/kaleido-lsps/SKILL.md +56 -0
  131. package/skills/kaleido-trading/SKILL.md +85 -18
  132. package/skills/merchant-finder/SKILL.md +87 -0
  133. package/skills/paid-data/SKILL.md +12 -0
  134. package/skills/wallet-assistant/SKILL.md +38 -0
  135. package/src/capabilities.ts +79 -0
  136. package/src/context/budget.ts +46 -0
  137. package/src/context/builder.ts +100 -0
  138. package/src/context/context.test.ts +87 -0
  139. package/src/engine.ts +6 -0
  140. package/src/fastpath/fastpath.test.ts +34 -0
  141. package/src/fastpath/fastpath.ts +70 -0
  142. package/src/funnel.test.ts +207 -0
  143. package/src/funnel.ts +285 -0
  144. package/src/index.ts +128 -0
  145. package/src/kaleidoswap/contract.test.ts +147 -0
  146. package/src/kaleidoswap/contract.ts +212 -0
  147. package/src/knowledge/bitcoin-copilot.ts +177 -0
  148. package/src/knowledge/btc-map.test.ts +188 -0
  149. package/src/knowledge/btc-map.ts +446 -0
  150. package/src/knowledge/knowledge.test.ts +63 -0
  151. package/src/knowledge/merchants.ts +49 -0
  152. package/src/knowledge/wallet.ts +84 -0
  153. package/src/lsps1/contract.test.ts +81 -0
  154. package/src/lsps1/contract.ts +132 -0
  155. package/src/memory/memory.test.ts +140 -0
  156. package/src/memory/store.ts +174 -0
  157. package/src/memory/tool.ts +76 -0
  158. package/src/memory/types.ts +76 -0
  159. package/src/rag/rag.test.ts +85 -0
  160. package/src/rag/retriever.ts +94 -0
  161. package/src/rag/tool.ts +55 -0
  162. package/src/rag/types.ts +49 -0
  163. package/src/rag/vector-store.ts +78 -0
  164. package/src/recipe/asset-send.ts +79 -0
  165. package/src/recipe/kaleidoswap-atomic.test.ts +138 -0
  166. package/src/recipe/kaleidoswap-atomic.ts +117 -0
  167. package/src/recipe/payments.ts +116 -0
  168. package/src/recipe/receive.ts +98 -0
  169. package/src/recipe/recipe.test.ts +193 -0
  170. package/src/recipe/runner.ts +134 -0
  171. package/src/recipe/swap.ts +74 -0
  172. package/src/recipe/types.ts +76 -0
  173. package/src/skills/registry.ts +21 -2
  174. package/src/skills/skills.test.ts +42 -0
  175. package/src/tools/cli.test.ts +53 -0
  176. package/src/tools/cli.ts +98 -0
  177. package/src/tools/mcp.ts +3 -2
  178. package/src/wallet/confirm.test.ts +57 -0
  179. package/src/wallet/confirm.ts +74 -0
  180. package/src/wallet/contract.test.ts +89 -0
  181. package/src/wallet/contract.ts +157 -0
  182. package/skills/kaleido-wallet/SKILL.md +0 -28
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Built-in "atomic swap on KaleidoSwap" recipe — trust-minimised chain.
3
+ *
4
+ * Most users want the simple market-order swap (`swapRecipe` over generic
5
+ * `get_swap_quote` / `execute_swap`). This recipe is the EXPLICIT atomic path:
6
+ * the user creates an RGB/LN receive invoice, the maker locks the swap, the
7
+ * user pays the maker's Lightning invoice, and the maker releases.
8
+ *
9
+ * Triggered only by explicit atomic-swap intent ("atomic swap", "trustless
10
+ * swap", "htlc swap") so it never preempts the simpler swap path for vague
11
+ * phrasings.
12
+ *
13
+ * "atomic swap 100000 sats for usdt"
14
+ * ↓ 1 model inference (slot extraction)
15
+ * kaleidoswap_get_quote ← maker prices the swap
16
+ * rln_create_rgb_invoice ← user's node prepares receive (if to_asset is RGB)
17
+ * rln_create_ln_invoice ← (alt) if to_asset is BTC
18
+ * kaleidoswap_atomic_init 🔒 ← maker locks the swap, returns its invoice
19
+ * rln_pay_invoice 🔒 ← user pays the maker
20
+ * kaleidoswap_atomic_execute 🔒 ← (final) maker releases the asset
21
+ *
22
+ * Two-or-three confirmation gates are intentional: each represents a distinct
23
+ * decision point. The host's confirm UI describes what's about to happen.
24
+ */
25
+ import { extractSwap } from './swap.js';
26
+ const ATOMIC_INTENT = /\b(atomic|trustless|htlc)\b.*\b(swap|exchange|convert|trade)\b|\b(swap|exchange|convert|trade)\b.*\b(atomic|trustless|htlc)\b/i;
27
+ function isBtc(asset) {
28
+ return String(asset ?? '').toUpperCase() === 'BTC';
29
+ }
30
+ export const kaleidoswapAtomicRecipe = {
31
+ name: 'kaleidoswap-atomic',
32
+ description: 'Trust-minimised atomic swap on KaleidoSwap: quote, prepare a receive invoice on the user\'s node, lock the swap with the maker, pay, and execute.',
33
+ match: (t) => ATOMIC_INTENT.test(t),
34
+ triggers: ['atomic swap', 'trustless swap', 'htlc swap'],
35
+ slots: [
36
+ { name: 'from_asset', type: 'string', description: 'Asset to spend (BTC / USDT / XAUT)', required: true },
37
+ { name: 'to_asset', type: 'string', description: 'Asset to receive (BTC / USDT / XAUT)', required: true },
38
+ { name: 'amount', type: 'number', description: 'Amount of from_asset to swap' },
39
+ ],
40
+ extract: extractSwap,
41
+ confident: (s) => !!s.from_asset && !!s.to_asset && !!s.amount,
42
+ steps: [
43
+ // 1. Maker quotes the swap. Returns { quote_id, receive_amount, fees, ttl_ms, ... }.
44
+ {
45
+ tool: 'kaleidoswap_get_quote',
46
+ as: 'quote',
47
+ args: (ctx) => ({
48
+ from_asset: ctx.slots.from_asset,
49
+ to_asset: ctx.slots.to_asset,
50
+ amount: ctx.slots.amount,
51
+ }),
52
+ },
53
+ // 2a. User's node creates an RGB receive invoice (when to_asset is an RGB asset).
54
+ {
55
+ tool: 'rln_create_rgb_invoice',
56
+ as: 'receive_rgb',
57
+ args: (ctx) => {
58
+ const q = ctx.results.quote;
59
+ return { asset: ctx.slots.to_asset, amount: q?.receive_amount };
60
+ },
61
+ skipIf: (ctx) => isBtc(ctx.slots.to_asset),
62
+ },
63
+ // 2b. User's node creates an LN receive invoice (when to_asset is BTC).
64
+ {
65
+ tool: 'rln_create_ln_invoice',
66
+ as: 'receive_ln',
67
+ args: (ctx) => {
68
+ const q = ctx.results.quote;
69
+ return { amount_sats: q?.receive_amount };
70
+ },
71
+ skipIf: (ctx) => !isBtc(ctx.slots.to_asset),
72
+ },
73
+ // 3. Maker locks the swap. Returns { atomic_id, maker_invoice }. Spend-gated.
74
+ {
75
+ tool: 'kaleidoswap_atomic_init',
76
+ as: 'atomic',
77
+ args: (ctx) => {
78
+ const rgb = ctx.results.receive_rgb;
79
+ const ln = ctx.results.receive_ln;
80
+ const q = ctx.results.quote;
81
+ return {
82
+ quote_id: q?.quote_id,
83
+ receive_invoice: rgb?.invoice ?? ln?.invoice,
84
+ };
85
+ },
86
+ },
87
+ // 4. User pays the maker's Lightning invoice. Spend-gated by the wallet contract.
88
+ {
89
+ tool: 'rln_pay_invoice',
90
+ as: 'paid',
91
+ args: (ctx) => {
92
+ const a = ctx.results.atomic;
93
+ return { invoice: a?.maker_invoice };
94
+ },
95
+ },
96
+ ],
97
+ // 5. Maker releases the receive asset → swap completes. Spend-gated.
98
+ final: {
99
+ tool: 'kaleidoswap_atomic_execute',
100
+ args: (ctx) => {
101
+ const a = ctx.results.atomic;
102
+ return { atomic_id: a?.atomic_id };
103
+ },
104
+ },
105
+ summary: (ctx) => {
106
+ const q = ctx.results.quote;
107
+ const tail = q?.receive_amount ? ` ≈ ${q.receive_amount} ${ctx.slots.to_asset}` : '';
108
+ return `Atomic swap: ${ctx.slots.amount} ${ctx.slots.from_asset} → ${ctx.slots.to_asset}${tail}.`;
109
+ },
110
+ };
111
+ //# sourceMappingURL=kaleidoswap-atomic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kaleidoswap-atomic.js","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,aAAa,GACjB,gIAAgI,CAAC;AAEnI,SAAS,KAAK,CAAC,KAAc;IAC3B,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAW;IAC7C,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,mJAAmJ;IACrJ,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,aAAa,EAAE,gBAAgB,EAAE,WAAW,CAAC;IACxD,KAAK,EAAE;QACL,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzG,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;KAChF;IACD,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM;IAC9D,KAAK,EAAE;QACL,qFAAqF;QACrF;YACE,IAAI,EAAE,uBAAuB;YAC7B,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACd,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,UAAU;gBAChC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ;gBAC5B,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;aACzB,CAAC;SACH;QACD,kFAAkF;QAClF;YACE,IAAI,EAAE,wBAAwB;YAC9B,EAAE,EAAE,aAAa;YACjB,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,KAAgD,CAAC;gBACvE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC;YAClE,CAAC;YACD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC3C;QACD,wEAAwE;QACxE;YACE,IAAI,EAAE,uBAAuB;YAC7B,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,KAAgD,CAAC;gBACvE,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC;YAC5C,CAAC;YACD,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC5C;QACD,8EAA8E;QAC9E;YACE,IAAI,EAAE,yBAAyB;YAC/B,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAA+C,CAAC;gBACxE,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,UAA8C,CAAC;gBACtE,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,KAA0C,CAAC;gBACjE,OAAO;oBACL,QAAQ,EAAE,CAAC,EAAE,QAAQ;oBACrB,eAAe,EAAE,GAAG,EAAE,OAAO,IAAI,EAAE,EAAE,OAAO;iBAC7C,CAAC;YACJ,CAAC;SACF;QACD,kFAAkF;QAClF;YACE,IAAI,EAAE,iBAAiB;YACvB,EAAE,EAAE,MAAM;YACV,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBACZ,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAgD,CAAC;gBACvE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;YACvC,CAAC;SACF;KACF;IACD,qEAAqE;IACrE,KAAK,EAAE;QACL,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;YACZ,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAA4C,CAAC;YACnE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC;QACrC,CAAC;KACF;IACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,KAAgD,CAAC;QACvE,MAAM,IAAI,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,OAAO,gBAAgB,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,GAAG,CAAC;IACpG,CAAC;CACF,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Built-in "pay a contact" recipe — the flagship mobile multi-step flow.
3
+ *
4
+ * "pay bob 3 EUR" → resolve_contact → fiat_to_sats → send_payment 🔒
5
+ * "send 5000 sats to alice" → resolve_contact → send_payment 🔒
6
+ *
7
+ * Uses the canonical contract tools. The deterministic extractor handles most
8
+ * phrasings with no LLM at all (Tier-0); the runner falls back to one LLM
9
+ * extraction otherwise.
10
+ */
11
+ import type { Recipe } from './types.js';
12
+ /** "pay bob 3 eur", "send 5,000 sats to alice", "pay lnbc... ", "send 0.001 btc to bob" */
13
+ export declare function extractPayment(text: string): Record<string, unknown> | null;
14
+ export declare const paymentsRecipe: Recipe;
15
+ //# sourceMappingURL=payments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payments.d.ts","sourceRoot":"","sources":["../../src/recipe/payments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAgBxD,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAuB3E;AAgBD,eAAO,MAAM,cAAc,EAAE,MAgD5B,CAAC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Built-in "pay a contact" recipe — the flagship mobile multi-step flow.
3
+ *
4
+ * "pay bob 3 EUR" → resolve_contact → fiat_to_sats → send_payment 🔒
5
+ * "send 5000 sats to alice" → resolve_contact → send_payment 🔒
6
+ *
7
+ * Uses the canonical contract tools. The deterministic extractor handles most
8
+ * phrasings with no LLM at all (Tier-0); the runner falls back to one LLM
9
+ * extraction otherwise.
10
+ */
11
+ const CURRENCIES = /\b(sats?|sat|btc|usdt|xaut|eur|usd|gbp|dollars?|euros?|pounds?)\b/i;
12
+ const isOnchainOrInvoice = (s) => /^(ln(bc|tb|bcrt)|bc1|tb1|lnurl|[a-z0-9._-]+@)/i.test(s.trim());
13
+ function normCurrency(c) {
14
+ if (!c)
15
+ return undefined;
16
+ const x = c.toLowerCase();
17
+ if (/^sat/.test(x))
18
+ return 'sats';
19
+ if (x === 'btc')
20
+ return 'btc';
21
+ if (/dollar|^usd/.test(x))
22
+ return 'usd';
23
+ if (/euro|^eur/.test(x))
24
+ return 'eur';
25
+ if (/pound|^gbp/.test(x))
26
+ return 'gbp';
27
+ return x.toUpperCase();
28
+ }
29
+ /** "pay bob 3 eur", "send 5,000 sats to alice", "pay lnbc... ", "send 0.001 btc to bob" */
30
+ export function extractPayment(text) {
31
+ const t = text.trim();
32
+ if (!/\b(pay|send|transfer)\b/i.test(t))
33
+ return null;
34
+ // Amount with optional k/m shorthand: "5k" → 5000, "2m" → 2_000_000.
35
+ const amtMatch = t.match(/(\d[\d.,]*)\s*([km])?\b/i);
36
+ let amountNum = amtMatch ? Number(amtMatch[1].replace(/,/g, '')) : undefined;
37
+ if (amountNum != null && amtMatch?.[2])
38
+ amountNum *= amtMatch[2].toLowerCase() === 'k' ? 1_000 : 1_000_000;
39
+ const amount = amountNum != null && !Number.isNaN(amountNum) ? String(amountNum) : undefined;
40
+ const currency = normCurrency(t.match(CURRENCIES)?.[1]);
41
+ // recipient: prefer "to <x>", else the token right after pay/send that isn't a number/currency
42
+ let recipient = t.match(/\bto\s+([^\s,]+)/i)?.[1];
43
+ if (!recipient) {
44
+ const after = t.match(/\b(?:pay|send|transfer)\s+([^\s,]+)/i)?.[1];
45
+ if (after && !/^\d/.test(after) && !CURRENCIES.test(after))
46
+ recipient = after;
47
+ }
48
+ if (!recipient && !amount)
49
+ return null;
50
+ return {
51
+ recipient,
52
+ amount: amount ? Number(amount) : undefined,
53
+ currency,
54
+ };
55
+ }
56
+ /** Compute the sats amount when no fiat conversion step is needed. */
57
+ function directSats(ctx) {
58
+ const amount = Number(ctx.slots.amount);
59
+ if (!amount || Number.isNaN(amount))
60
+ return undefined;
61
+ const cur = String(ctx.slots.currency ?? 'sats').toLowerCase();
62
+ if (cur === 'btc')
63
+ return Math.round(amount * 1e8);
64
+ return Math.round(amount); // sats (default)
65
+ }
66
+ const isFiat = (ctx) => {
67
+ const c = String(ctx.slots.currency ?? '').toLowerCase();
68
+ return c !== '' && c !== 'sats' && c !== 'btc';
69
+ };
70
+ export const paymentsRecipe = {
71
+ name: 'pay-contact',
72
+ description: 'Pay a contact or address — resolves the contact, converts fiat to sats, then sends (with confirmation).',
73
+ // A BTC/fiat spend intent — NOT a receive/invoice, and NOT an RGB-asset send
74
+ // ("send 10 USDT to bob" is handled by the asset-send recipe, so USDT/XAUT
75
+ // amounts are never mis-parsed as fiat).
76
+ match: (t) => /\b(pay|send|transfer)\b/i.test(t) && !/\b(invoice|receive|request|address|qr|deposit|usdt|tether|xaut|gold)\b/i.test(t),
77
+ triggers: ['pay', 'send', 'transfer'],
78
+ slots: [
79
+ { name: 'recipient', type: 'string', description: 'Who to pay: a contact name, Lightning address, or invoice', required: true },
80
+ { name: 'amount', type: 'number', description: 'The amount to send' },
81
+ { name: 'currency', type: 'string', description: 'Unit of the amount: sats, btc, or a fiat code like eur/usd' },
82
+ ],
83
+ extract: extractPayment,
84
+ confident: (s) => !!s.recipient,
85
+ steps: [
86
+ {
87
+ // Resolve a contact name → payable address (skip if already an address/invoice).
88
+ tool: 'resolve_contact',
89
+ as: 'contact',
90
+ args: (ctx) => ({ name: ctx.slots.recipient }),
91
+ skipIf: (ctx) => !ctx.slots.recipient || isOnchainOrInvoice(String(ctx.slots.recipient)),
92
+ },
93
+ {
94
+ // Convert fiat → sats (skip when the amount is already sats/btc or absent).
95
+ tool: 'fiat_to_sats',
96
+ as: 'conv',
97
+ args: (ctx) => ({ amount: ctx.slots.amount, currency: ctx.slots.currency }),
98
+ skipIf: (ctx) => !ctx.slots.amount || !isFiat(ctx),
99
+ },
100
+ ],
101
+ final: {
102
+ tool: 'send_payment',
103
+ args: (ctx) => {
104
+ const contact = ctx.results.contact;
105
+ const conv = ctx.results.conv;
106
+ return {
107
+ to: contact?.ln_address ?? ctx.slots.recipient,
108
+ amount_sats: conv?.sats ?? directSats(ctx),
109
+ };
110
+ },
111
+ },
112
+ summary: (ctx) => {
113
+ const conv = ctx.results.conv;
114
+ const sats = conv?.sats ?? directSats(ctx);
115
+ const to = ctx.results.contact?.name ?? ctx.slots.recipient;
116
+ return sats ? `Sent ${sats.toLocaleString()} sats to ${to}.` : `Payment sent to ${to}.`;
117
+ },
118
+ };
119
+ //# sourceMappingURL=payments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/recipe/payments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Built-in "receive" recipe — create an invoice/address to get paid, in sats,
3
+ * BTC, an RGB asset, OR a fiat amount (converted to sats deterministically so a
4
+ * small model never mis-parses "$2.00").
5
+ *
6
+ * "invoice for 5000 sats" → BTC invoice, 5000 sats
7
+ * "create a payment request of $2" → fiat_to_sats(2, USD) → BTC invoice
8
+ * "invoice for 25 USDT on Liquid" → RGB asset invoice
9
+ * "an invoice" → BTC invoice, any amount
10
+ */
11
+ import type { Recipe } from './types.js';
12
+ export declare function extractReceive(text: string): Record<string, unknown> | null;
13
+ export declare const receiveRecipe: Recipe;
14
+ //# sourceMappingURL=receive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive.d.ts","sourceRoot":"","sources":["../../src/recipe/receive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA+BzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAO3E;AAED,eAAO,MAAM,aAAa,EAAE,MA8C3B,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Built-in "receive" recipe — create an invoice/address to get paid, in sats,
3
+ * BTC, an RGB asset, OR a fiat amount (converted to sats deterministically so a
4
+ * small model never mis-parses "$2.00").
5
+ *
6
+ * "invoice for 5000 sats" → BTC invoice, 5000 sats
7
+ * "create a payment request of $2" → fiat_to_sats(2, USD) → BTC invoice
8
+ * "invoice for 25 USDT on Liquid" → RGB asset invoice
9
+ * "an invoice" → BTC invoice, any amount
10
+ */
11
+ const LAYER = /\b(spark|arkade|liquid|rln|lightning|rgb)\b/i;
12
+ const RECEIVE_INTENT = /\b(invoice|receive|deposit|get paid|pay me|payment request|request (a )?payment)\b/i;
13
+ function classify(text) {
14
+ if (/\$|\busd\b|dollar/i.test(text))
15
+ return { kind: 'fiat', code: 'USD' };
16
+ if (/€|\beur\b|euro/i.test(text))
17
+ return { kind: 'fiat', code: 'EUR' };
18
+ if (/£|\bgbp\b|pound/i.test(text))
19
+ return { kind: 'fiat', code: 'GBP' };
20
+ if (/usdt|tether/i.test(text))
21
+ return { kind: 'asset', code: 'USDT' };
22
+ if (/xaut|gold/i.test(text))
23
+ return { kind: 'asset', code: 'XAUT' };
24
+ if (/\bbtc\b|bitcoin/i.test(text))
25
+ return { kind: 'btc', code: 'BTC' };
26
+ return { kind: 'sats', code: 'BTC' }; // default: sats
27
+ }
28
+ function normLayer(l) {
29
+ if (!l)
30
+ return undefined;
31
+ const x = l.toLowerCase();
32
+ if (x === 'lightning' || x === 'rgb')
33
+ return 'rln';
34
+ if (['spark', 'arkade', 'liquid', 'rln'].includes(x))
35
+ return x;
36
+ return undefined;
37
+ }
38
+ function parseAmount(t) {
39
+ const m = t.match(/(\d[\d.,]*)\s*([km])?\b/i);
40
+ if (!m)
41
+ return undefined;
42
+ let n = Number(m[1].replace(/,/g, ''));
43
+ if (m[2])
44
+ n *= m[2].toLowerCase() === 'k' ? 1_000 : 1_000_000;
45
+ return Number.isNaN(n) ? undefined : n;
46
+ }
47
+ export function extractReceive(text) {
48
+ const t = text.trim();
49
+ if (!RECEIVE_INTENT.test(t))
50
+ return null;
51
+ const amount = parseAmount(t);
52
+ const { kind, code } = classify(t);
53
+ const layer = normLayer(t.match(LAYER)?.[1]);
54
+ return { ...(amount != null ? { amount } : {}), kind, currency: code, ...(layer ? { layer } : {}) };
55
+ }
56
+ export const receiveRecipe = {
57
+ name: 'receive',
58
+ description: 'Create an invoice/address to receive funds — sats, BTC, a fiat amount (converted), or an RGB asset.',
59
+ match: (t) => RECEIVE_INTENT.test(t) && !/\b(send|transfer|swap|buy|sell)\b/i.test(t),
60
+ triggers: ['invoice', 'receive', 'deposit', 'payment request'],
61
+ slots: [
62
+ { name: 'amount', type: 'number', description: 'Amount to receive (optional)' },
63
+ { name: 'currency', type: 'string', description: 'sats | BTC | USD | EUR | USDT | XAUT' },
64
+ { name: 'layer', type: 'string', description: 'Rail: spark, rln, liquid (optional)' },
65
+ ],
66
+ extract: extractReceive,
67
+ confident: () => true,
68
+ steps: [
69
+ {
70
+ // Fiat → sats, only when the amount is fiat-denominated.
71
+ tool: 'fiat_to_sats',
72
+ as: 'conv',
73
+ args: (ctx) => ({ amount: ctx.slots.amount, currency: ctx.slots.currency }),
74
+ skipIf: (ctx) => ctx.slots.kind !== 'fiat' || ctx.slots.amount == null,
75
+ },
76
+ ],
77
+ final: {
78
+ tool: 'create_invoice',
79
+ args: (ctx) => {
80
+ const kind = ctx.slots.kind;
81
+ const conv = ctx.results.conv;
82
+ let asset = 'BTC';
83
+ let amount = ctx.slots.amount;
84
+ if (kind === 'asset')
85
+ asset = String(ctx.slots.currency);
86
+ else if (kind === 'fiat')
87
+ amount = conv?.sats;
88
+ else if (kind === 'btc' && amount != null)
89
+ amount = Math.round(amount * 1e8); // sats
90
+ return { asset, amount, layer: ctx.slots.layer };
91
+ },
92
+ },
93
+ summary: (ctx, result) => {
94
+ const r = result;
95
+ const dest = r?.invoice ?? r?.address ?? '';
96
+ const kind = ctx.slots.kind;
97
+ const conv = ctx.results.conv;
98
+ let amt = 'any amount';
99
+ if (kind === 'fiat' && ctx.slots.amount != null)
100
+ amt = `${ctx.slots.currency} ${ctx.slots.amount} (${(conv?.sats ?? 0).toLocaleString()} sats)`;
101
+ else if (kind === 'asset' && ctx.slots.amount != null)
102
+ amt = `${Number(ctx.slots.amount).toLocaleString()} ${ctx.slots.currency}`;
103
+ else if (ctx.slots.amount != null)
104
+ amt = `${Number(ctx.slots.amount).toLocaleString()} ${kind === 'btc' ? 'BTC' : 'sats'}`;
105
+ const label = kind === 'asset' ? String(ctx.slots.currency) : 'BTC';
106
+ return dest ? `Here's your ${label} invoice for ${amt}:\n\n${dest}` : `Created an invoice for ${amt}.`;
107
+ },
108
+ };
109
+ //# sourceMappingURL=receive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receive.js","sourceRoot":"","sources":["../../src/recipe/receive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Recipe runner — executes a Recipe with ONE structured extraction (or a
3
+ * deterministic regex), then runs the deterministic step chain and the
4
+ * confirmation-gated final action. This is mobile multi-step: a tiny model
5
+ * fills slots; the engine does the planning.
6
+ */
7
+ import type { LLMProvider } from '../providers/types.js';
8
+ import type { ToolRegistry } from '../tools/registry.js';
9
+ import type { ConfirmDecision } from '../types.js';
10
+ import type { Recipe, RecipeResult } from './types.js';
11
+ export interface RunRecipeOptions {
12
+ provider: LLMProvider;
13
+ tools: ToolRegistry;
14
+ /** Called before the (spend) final action when its tool is confirmation-gated. */
15
+ onConfirm?: (call: {
16
+ name: string;
17
+ arguments: Record<string, unknown>;
18
+ }) => Promise<ConfirmDecision>;
19
+ /** Progress hook per completed step. */
20
+ onStep?: (name: string, args: Record<string, unknown>, result: unknown) => void;
21
+ /** Skip extraction and use these slots (deterministic Tier-0 / tests). */
22
+ slots?: Record<string, unknown>;
23
+ signal?: AbortSignal;
24
+ }
25
+ /** Extract the recipe's slots — deterministic regex first, else ONE LLM call. */
26
+ export declare function extractSlots(provider: LLMProvider, recipe: Recipe, text: string): Promise<{
27
+ slots: Record<string, unknown>;
28
+ inferences: number;
29
+ }>;
30
+ /** Run a recipe end to end. Never throws — failures come back as status:'error'. */
31
+ export declare function runRecipe(recipe: Recipe, text: string, opts: RunRecipeOptions): Promise<RecipeResult>;
32
+ /** Selects a recipe for a request. Use before falling back to the free agentic loop. */
33
+ export declare class RecipeRegistry {
34
+ private recipes;
35
+ constructor(recipes?: Recipe[]);
36
+ add(recipe: Recipe): void;
37
+ list(): Recipe[];
38
+ get(name: string): Recipe | undefined;
39
+ /** First recipe whose match()/triggers fit the text, else null. */
40
+ select(text: string): Recipe | null;
41
+ }
42
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/recipe/runner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAC;AAItE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,kFAAkF;IAClF,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;IACrG,wCAAwC;IACxC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAChF,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,iFAAiF;AACjF,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBjE;AAED,oFAAoF;AACpF,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAsD3G;AAED,wFAAwF;AACxF,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAW;gBACd,OAAO,GAAE,MAAM,EAAO;IAGlC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAGzB,IAAI,IAAI,MAAM,EAAE;IAGhB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAGrC,mEAAmE;IACnE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAQpC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Recipe runner — executes a Recipe with ONE structured extraction (or a
3
+ * deterministic regex), then runs the deterministic step chain and the
4
+ * confirmation-gated final action. This is mobile multi-step: a tiny model
5
+ * fills slots; the engine does the planning.
6
+ */
7
+ const EXTRACT_TOOL = 'extract_request';
8
+ /** Extract the recipe's slots — deterministic regex first, else ONE LLM call. */
9
+ export async function extractSlots(provider, recipe, text) {
10
+ const det = recipe.extract?.(text);
11
+ if (det && Object.values(det).some((v) => v !== undefined && v !== null && v !== '')) {
12
+ return { slots: det, inferences: 0 };
13
+ }
14
+ const properties = {};
15
+ for (const s of recipe.slots)
16
+ properties[s.name] = { type: s.type ?? 'string', description: s.description };
17
+ const extractTool = {
18
+ name: EXTRACT_TOOL,
19
+ description: `Extract the fields from the user's request.`,
20
+ parameters: { type: 'object', properties, required: recipe.slots.filter((s) => s.required).map((s) => s.name) },
21
+ };
22
+ const out = await provider.runTurn({
23
+ system: `Call ${EXTRACT_TOOL} with the fields from the user's message. Do not call any other tool and do not add commentary.`,
24
+ messages: [{ role: 'user', content: text }],
25
+ tools: [extractTool],
26
+ });
27
+ const call = out.toolCalls?.find((c) => c.name === EXTRACT_TOOL) ?? out.toolCalls?.[0];
28
+ return { slots: call?.arguments ?? {}, inferences: 1 };
29
+ }
30
+ /** Run a recipe end to end. Never throws — failures come back as status:'error'. */
31
+ export async function runRecipe(recipe, text, opts) {
32
+ const ctx = { text, slots: opts.slots ?? {}, results: {} };
33
+ let inferences = 0;
34
+ try {
35
+ if (!opts.slots) {
36
+ const ex = await extractSlots(opts.provider, recipe, text);
37
+ ctx.slots = ex.slots;
38
+ inferences = ex.inferences;
39
+ }
40
+ // Deterministic steps. Intermediate spend tools fire the same confirmation
41
+ // gate as the final step — recipes with multi-spend chains (e.g. atomic
42
+ // swaps) MUST have every money-moving call gated, never just the last one.
43
+ // Missing onConfirm fails closed, matching the Engine.
44
+ for (const step of recipe.steps) {
45
+ if (step.skipIf?.(ctx))
46
+ continue;
47
+ const args = step.args(ctx);
48
+ const def = await opts.tools.getDef(step.tool);
49
+ if (def?.requiresConfirmation) {
50
+ const decision = opts.onConfirm
51
+ ? await opts.onConfirm({ name: step.tool, arguments: args })
52
+ : { approved: false, reason: 'no confirmation handler available' };
53
+ if (!decision.approved) {
54
+ return { recipe: recipe.name, slots: ctx.slots, results: ctx.results, text: 'Cancelled — nothing was sent.', status: 'cancelled', inferences };
55
+ }
56
+ }
57
+ const result = await opts.tools.execute(step.tool, args);
58
+ ctx.results[step.as ?? step.tool] = result;
59
+ opts.onStep?.(step.tool, args, result);
60
+ }
61
+ // Final action — confirmation-gated if the tool requires it. Like the
62
+ // Engine, a missing onConfirm FAILS CLOSED: the spend is declined, never
63
+ // silently executed.
64
+ const finalArgs = recipe.final.args(ctx);
65
+ const def = await opts.tools.getDef(recipe.final.tool);
66
+ if (def?.requiresConfirmation) {
67
+ const decision = opts.onConfirm
68
+ ? await opts.onConfirm({ name: recipe.final.tool, arguments: finalArgs })
69
+ : { approved: false, reason: 'no confirmation handler available' };
70
+ if (!decision.approved) {
71
+ return { recipe: recipe.name, slots: ctx.slots, results: ctx.results, text: 'Cancelled — nothing was sent.', status: 'cancelled', inferences };
72
+ }
73
+ }
74
+ const finalResult = await opts.tools.execute(recipe.final.tool, finalArgs);
75
+ ctx.results[recipe.final.as ?? recipe.final.tool] = finalResult;
76
+ opts.onStep?.(recipe.final.tool, finalArgs, finalResult);
77
+ const out = recipe.summary?.(ctx, finalResult) ?? 'Done.';
78
+ return { recipe: recipe.name, slots: ctx.slots, results: ctx.results, final: finalResult, text: out, status: 'done', inferences };
79
+ }
80
+ catch (e) {
81
+ const msg = e?.message ?? String(e);
82
+ return { recipe: recipe.name, slots: ctx.slots, results: ctx.results, text: `Couldn't complete that: ${msg}`, status: 'error', error: msg, inferences };
83
+ }
84
+ }
85
+ /** Selects a recipe for a request. Use before falling back to the free agentic loop. */
86
+ export class RecipeRegistry {
87
+ recipes;
88
+ constructor(recipes = []) {
89
+ this.recipes = [...recipes];
90
+ }
91
+ add(recipe) {
92
+ this.recipes.push(recipe);
93
+ }
94
+ list() {
95
+ return [...this.recipes];
96
+ }
97
+ get(name) {
98
+ return this.recipes.find((r) => r.name === name);
99
+ }
100
+ /** First recipe whose match()/triggers fit the text, else null. */
101
+ select(text) {
102
+ const lc = text.toLowerCase();
103
+ return (this.recipes.find((r) => r.match ? r.match(text) : (r.triggers ?? []).some((t) => lc.includes(t.toLowerCase()))) ?? null);
104
+ }
105
+ }
106
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/recipe/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Built-in "swap" recipe — quote → (confirm) → execute, over the contract tools.
3
+ *
4
+ * "buy 0.001 btc with usdt" → from USDT, to BTC
5
+ * "swap 10 usdt for btc" → from USDT, to BTC
6
+ * "sell 100 usdt for sats" → from USDT, to BTC
7
+ *
8
+ * The deterministic extractor handles the common phrasings; the runner falls
9
+ * back to one LLM extraction otherwise. execute_swap is a spend → the engine's
10
+ * confirmation gate fires before it runs.
11
+ */
12
+ import type { Recipe } from './types.js';
13
+ /** "buy 0.001 btc with usdt" / "swap 10 usdt for btc" / "sell 100 usdt for sats". */
14
+ export declare function extractSwap(text: string): Record<string, unknown> | null;
15
+ export declare const swapRecipe: Recipe;
16
+ //# sourceMappingURL=swap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/recipe/swap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAczC,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAYxE;AAED,eAAO,MAAM,UAAU,EAAE,MAgCxB,CAAC"}