@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,68 @@
1
+ /**
2
+ * Memory — the agent's persistent identity + what it has learned.
3
+ *
4
+ * Two layers, mirroring how nanobot splits SOUL.md / AGENTS.md / memory:
5
+ * - AgentProfile — static identity ("who am I, how do I behave"). Injected.
6
+ * - MemoryStore — durable, growing facts/preferences/events the agent
7
+ * remembers across sessions. Pluggable storage.
8
+ *
9
+ * Pure data + interfaces — no storage or embedding deps. The host injects
10
+ * persistence (AsyncStorage on RN, fs/SQLite on Node) and, optionally, an
11
+ * EmbeddingProvider for semantic recall.
12
+ */
13
+ /** Static agent identity, composed into the system prompt every turn. */
14
+ export interface AgentProfile {
15
+ /** Display name, e.g. "KaleidoMind". */
16
+ name: string;
17
+ /** Persona / identity — the "soul". Who the agent is, its voice, its values. */
18
+ soul: string;
19
+ /** Operating instructions / house rules (optional). */
20
+ instructions?: string;
21
+ }
22
+ export type MemoryKind = 'fact' | 'preference' | 'event' | 'note';
23
+ export interface MemoryItem {
24
+ id: string;
25
+ text: string;
26
+ kind: MemoryKind;
27
+ /** Epoch ms. */
28
+ createdAt: number;
29
+ tags?: string[];
30
+ /** Optional embedding for semantic recall (set when an embedder is wired). */
31
+ embedding?: number[];
32
+ }
33
+ /** What to add — id/createdAt/embedding are filled in by the store. */
34
+ export type NewMemory = Omit<MemoryItem, 'id' | 'createdAt' | 'embedding'> & Partial<Pick<MemoryItem, 'id' | 'createdAt' | 'embedding'>>;
35
+ export interface MemoryQuery {
36
+ /** Free text to match (semantic if embeddings are available, else substring). */
37
+ text?: string;
38
+ kind?: MemoryKind;
39
+ tags?: string[];
40
+ /** Max items to return (default 5). */
41
+ limit?: number;
42
+ }
43
+ export interface MemoryStore {
44
+ add(item: NewMemory): Promise<MemoryItem>;
45
+ all(): Promise<MemoryItem[]>;
46
+ /** Best-matching items for the query (recency-ranked, or semantic if embedded). */
47
+ search(query: MemoryQuery): Promise<MemoryItem[]>;
48
+ remove(id: string): Promise<void>;
49
+ clear(): Promise<void>;
50
+ }
51
+ /** Injected persistence — load once, save on every mutation. RN/Node provide it. */
52
+ export interface MemoryIO {
53
+ load(): Promise<MemoryItem[]>;
54
+ save(items: MemoryItem[]): Promise<void>;
55
+ }
56
+ /**
57
+ * Consolidation — fold same-kind near-duplicate memories into one item instead
58
+ * of bloating with "user likes EUR" ×5. Needs embeddings (the dup check is
59
+ * cosine). Omit for append-only. Two tiers: embedding-only dedup (zero
60
+ * inference, mobile-safe) and, when `merge` is set, an LLM rewrite.
61
+ */
62
+ export interface MemoryConsolidation {
63
+ /** Cosine threshold above which two same-kind memories are "the same". Default 0.92. */
64
+ threshold?: number;
65
+ /** Optional LLM merger; without it the newer item simply supersedes the older. */
66
+ merge?: (existing: string, incoming: string) => Promise<string>;
67
+ }
68
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,uEAAuE;AACvE,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GACxE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC;AAE9D,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7B,mFAAmF;IACnF,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,oFAAoF;AACpF,MAAM,WAAW,QAAQ;IACvB,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kFAAkF;IAClF,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACjE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Memory — the agent's persistent identity + what it has learned.
3
+ *
4
+ * Two layers, mirroring how nanobot splits SOUL.md / AGENTS.md / memory:
5
+ * - AgentProfile — static identity ("who am I, how do I behave"). Injected.
6
+ * - MemoryStore — durable, growing facts/preferences/events the agent
7
+ * remembers across sessions. Pluggable storage.
8
+ *
9
+ * Pure data + interfaces — no storage or embedding deps. The host injects
10
+ * persistence (AsyncStorage on RN, fs/SQLite on Node) and, optionally, an
11
+ * EmbeddingProvider for semantic recall.
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/memory/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Retriever — ties an injected EmbeddingProvider to a VectorStore: ingest
3
+ * documents (chunk → embed → upsert) and search (embed query → top-k). Pure
4
+ * TS; the embedding model is the host's (QVAC `embed()` on device).
5
+ */
6
+ import type { EmbeddingProvider, RagDocument, RetrievedChunk, VectorStore } from './types.js';
7
+ export interface RetrieverOptions {
8
+ embeddings: EmbeddingProvider;
9
+ /** Vector index (defaults to a fresh in-memory cosine store). */
10
+ store?: VectorStore;
11
+ /** Approx chars per chunk (default 800 ≈ 200 tokens). */
12
+ chunkSize?: number;
13
+ /** Chars of overlap between chunks (default 100). */
14
+ chunkOverlap?: number;
15
+ }
16
+ /** Split text into overlapping chunks, preferring paragraph/sentence breaks. */
17
+ export declare function chunkText(text: string, size?: number, overlap?: number): string[];
18
+ export declare class Retriever {
19
+ private readonly embeddings;
20
+ private readonly store;
21
+ private readonly chunkSize;
22
+ private readonly chunkOverlap;
23
+ constructor(opts: RetrieverOptions);
24
+ /** Chunk, embed, and index documents. Returns the number of chunks stored. */
25
+ ingest(docs: RagDocument[]): Promise<number>;
26
+ /** Embed the query and return the top-k most similar chunks. */
27
+ search(query: string, k?: number): Promise<RetrievedChunk[]>;
28
+ vectorStore(): VectorStore;
29
+ }
30
+ //# sourceMappingURL=retriever.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retriever.d.ts","sourceRoot":"","sources":["../../src/rag/retriever.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,iBAAiB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAM,EAAE,OAAO,SAAM,GAAG,MAAM,EAAE,CAwB3E;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,IAAI,EAAE,gBAAgB;IAOlC,8EAA8E;IACxE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBlD,gEAAgE;IAC1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,SAAI,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAO7D,WAAW,IAAI,WAAW;CAG3B"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Retriever — ties an injected EmbeddingProvider to a VectorStore: ingest
3
+ * documents (chunk → embed → upsert) and search (embed query → top-k). Pure
4
+ * TS; the embedding model is the host's (QVAC `embed()` on device).
5
+ */
6
+ import { InMemoryVectorStore } from './vector-store.js';
7
+ /** Split text into overlapping chunks, preferring paragraph/sentence breaks. */
8
+ export function chunkText(text, size = 800, overlap = 100) {
9
+ const clean = text.replace(/\r\n/g, '\n').trim();
10
+ if (clean.length <= size)
11
+ return clean ? [clean] : [];
12
+ const chunks = [];
13
+ let start = 0;
14
+ while (start < clean.length) {
15
+ let end = Math.min(start + size, clean.length);
16
+ if (end < clean.length) {
17
+ // Back up to the nearest paragraph/sentence/space boundary.
18
+ const slice = clean.slice(start, end);
19
+ const brk = Math.max(slice.lastIndexOf('\n\n'), slice.lastIndexOf('\n'), slice.lastIndexOf('. '), slice.lastIndexOf(' '));
20
+ if (brk > size * 0.5)
21
+ end = start + brk + 1;
22
+ }
23
+ const piece = clean.slice(start, end).trim();
24
+ if (piece)
25
+ chunks.push(piece);
26
+ if (end >= clean.length)
27
+ break;
28
+ start = Math.max(end - overlap, start + 1);
29
+ }
30
+ return chunks;
31
+ }
32
+ export class Retriever {
33
+ embeddings;
34
+ store;
35
+ chunkSize;
36
+ chunkOverlap;
37
+ constructor(opts) {
38
+ this.embeddings = opts.embeddings;
39
+ this.store = opts.store ?? new InMemoryVectorStore();
40
+ this.chunkSize = opts.chunkSize ?? 800;
41
+ this.chunkOverlap = opts.chunkOverlap ?? 100;
42
+ }
43
+ /** Chunk, embed, and index documents. Returns the number of chunks stored. */
44
+ async ingest(docs) {
45
+ const pending = [];
46
+ for (const doc of docs) {
47
+ const pieces = chunkText(doc.text, this.chunkSize, this.chunkOverlap);
48
+ pieces.forEach((text, i) => {
49
+ const baseId = doc.id ?? `doc_${pending.length}`;
50
+ pending.push({ id: `${baseId}#${i}`, text, metadata: doc.metadata });
51
+ });
52
+ }
53
+ if (pending.length === 0)
54
+ return 0;
55
+ const vectors = await this.embeddings.embed(pending.map((p) => p.text));
56
+ await this.store.upsert(pending.map((p, i) => ({ ...p, embedding: vectors[i] })));
57
+ return pending.length;
58
+ }
59
+ /** Embed the query and return the top-k most similar chunks. */
60
+ async search(query, k = 4) {
61
+ if (!query.trim())
62
+ return [];
63
+ const [qv] = await this.embeddings.embed([query]);
64
+ if (!qv)
65
+ return [];
66
+ return this.store.query(qv, k);
67
+ }
68
+ vectorStore() {
69
+ return this.store;
70
+ }
71
+ }
72
+ //# sourceMappingURL=retriever.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retriever.js","sourceRoot":"","sources":["../../src/rag/retriever.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * RAG tool source — exposes `search_knowledge` so the model can pull in
3
+ * relevant context on demand (agentic RAG). Preferred over always-injecting
4
+ * retrieved text, which burns the small-model context window.
5
+ */
6
+ import type { ToolSource } from '../tools/source.js';
7
+ import type { Retriever } from './retriever.js';
8
+ export interface RagToolOptions {
9
+ /** Chunks to return (default 4). */
10
+ k?: number;
11
+ /** Override the tool description for your corpus, e.g. "Search the docs." */
12
+ description?: string;
13
+ }
14
+ export declare function createRagToolSource(retriever: Retriever, opts?: RagToolOptions): ToolSource;
15
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/rag/tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAIhD,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,GAAE,cAAmB,GAAG,UAAU,CAmC/F"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * RAG tool source — exposes `search_knowledge` so the model can pull in
3
+ * relevant context on demand (agentic RAG). Preferred over always-injecting
4
+ * retrieved text, which burns the small-model context window.
5
+ */
6
+ const SEARCH = 'search_knowledge';
7
+ export function createRagToolSource(retriever, opts = {}) {
8
+ const tool = {
9
+ name: SEARCH,
10
+ description: opts.description ??
11
+ 'Search the knowledge base for passages relevant to a question and return ' +
12
+ 'the best matches. Use this before answering when the answer might be in ' +
13
+ 'ingested documents.',
14
+ parameters: {
15
+ type: 'object',
16
+ properties: {
17
+ query: { type: 'string', description: 'What to look up' },
18
+ k: { type: 'number', description: 'How many passages (default 4)' },
19
+ },
20
+ required: ['query'],
21
+ },
22
+ };
23
+ async function execute(_name, args) {
24
+ const query = String(args.query ?? '').trim();
25
+ if (!query)
26
+ throw new Error('search_knowledge: query is required');
27
+ const k = Number(args.k) > 0 ? Number(args.k) : (opts.k ?? 4);
28
+ const hits = await retriever.search(query, k);
29
+ if (hits.length === 0)
30
+ return 'No relevant passages found.';
31
+ return hits
32
+ .map((h, i) => `[${i + 1}] (score ${h.score.toFixed(2)}) ${h.text}`)
33
+ .join('\n\n');
34
+ }
35
+ return {
36
+ id: 'rag',
37
+ listTools: () => [tool],
38
+ has: (name) => name === SEARCH,
39
+ execute,
40
+ };
41
+ }
42
+ //# sourceMappingURL=tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/rag/tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,MAAM,GAAG,kBAAkB,CAAC;AASlC,MAAM,UAAU,mBAAmB,CAAC,SAAoB,EAAE,OAAuB,EAAE;IACjF,MAAM,IAAI,GAAY;QACpB,IAAI,EAAE,MAAM;QACZ,WAAW,EACT,IAAI,CAAC,WAAW;YAChB,2EAA2E;gBACzE,0EAA0E;gBAC1E,qBAAqB;QACzB,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBACzD,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;aACpE;YACD,QAAQ,EAAE,CAAC,OAAO,CAAC;SACpB;KACF,CAAC;IAEF,KAAK,UAAU,OAAO,CAAC,KAAa,EAAE,IAA6B;QACjE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACnE,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,6BAA6B,CAAC;QAC5D,OAAO,IAAI;aACR,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;aACnE,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;IAED,OAAO;QACL,EAAE,EAAE,KAAK;QACT,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC;QACvB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM;QAC9B,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * RAG types — retrieval-augmented generation primitives.
3
+ *
4
+ * The heavy parts (the embedding model, the vector index) are interfaces the
5
+ * host injects. On QVAC the EmbeddingProvider wraps the SDK `embed()` API
6
+ * (on-device); a server host could inject a remote embedder. The default
7
+ * VectorStore is a pure-JS in-memory cosine index (good for thousands of
8
+ * chunks); a host can swap in SQLite/native for more.
9
+ */
10
+ /** Turns text into vectors. Injected — QVAC `embed()` on device, etc. */
11
+ export interface EmbeddingProvider {
12
+ embed(texts: string[]): Promise<number[][]>;
13
+ /** Vector dimension, when known (informational). */
14
+ dimension?: number;
15
+ }
16
+ export interface Chunk {
17
+ id: string;
18
+ text: string;
19
+ metadata?: Record<string, unknown>;
20
+ embedding?: number[];
21
+ }
22
+ export interface RetrievedChunk extends Chunk {
23
+ /** Similarity score in [-1, 1] (cosine). */
24
+ score: number;
25
+ }
26
+ /** A document to ingest; chunked + embedded by the Retriever. */
27
+ export interface RagDocument {
28
+ id?: string;
29
+ text: string;
30
+ metadata?: Record<string, unknown>;
31
+ }
32
+ export interface VectorStore {
33
+ upsert(chunks: Chunk[]): Promise<void>;
34
+ /** Top-k by cosine similarity to `embedding`. */
35
+ query(embedding: number[], k: number): Promise<RetrievedChunk[]>;
36
+ size(): Promise<number>;
37
+ clear(): Promise<void>;
38
+ }
39
+ /** Injected persistence for the vector store (optional). */
40
+ export interface VectorStoreIO {
41
+ load(): Promise<Chunk[]>;
42
+ save(chunks: Chunk[]): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rag/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,yEAAyE;AACzE,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAe,SAAQ,KAAK;IAC3C,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,iDAAiD;IACjD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACjE,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACzB,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * RAG types — retrieval-augmented generation primitives.
3
+ *
4
+ * The heavy parts (the embedding model, the vector index) are interfaces the
5
+ * host injects. On QVAC the EmbeddingProvider wraps the SDK `embed()` API
6
+ * (on-device); a server host could inject a remote embedder. The default
7
+ * VectorStore is a pure-JS in-memory cosine index (good for thousands of
8
+ * chunks); a host can swap in SQLite/native for more.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rag/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * In-memory vector store — pure-JS cosine similarity index. Zero deps, so it
3
+ * bundles in Bare/RN. Good for thousands of chunks; swap in a native/SQLite
4
+ * store via the VectorStore interface for larger corpora.
5
+ */
6
+ import type { Chunk, RetrievedChunk, VectorStore, VectorStoreIO } from './types.js';
7
+ /** Cosine similarity of two equal-length vectors. Returns 0 on degenerate input. */
8
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
9
+ export interface InMemoryVectorStoreOptions {
10
+ io?: VectorStoreIO;
11
+ }
12
+ export declare class InMemoryVectorStore implements VectorStore {
13
+ private chunks;
14
+ private hydrated;
15
+ private readonly io?;
16
+ constructor(opts?: InMemoryVectorStoreOptions);
17
+ private hydrate;
18
+ upsert(chunks: Chunk[]): Promise<void>;
19
+ query(embedding: number[], k: number): Promise<RetrievedChunk[]>;
20
+ size(): Promise<number>;
21
+ clear(): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=vector-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/rag/vector-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpF,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAYjE;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,CAAC,EAAE,aAAa,CAAC;CACpB;AAED,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAgB;gBAExB,IAAI,GAAE,0BAA+B;YAInC,OAAO;IAYf,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAShE,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * In-memory vector store — pure-JS cosine similarity index. Zero deps, so it
3
+ * bundles in Bare/RN. Good for thousands of chunks; swap in a native/SQLite
4
+ * store via the VectorStore interface for larger corpora.
5
+ */
6
+ /** Cosine similarity of two equal-length vectors. Returns 0 on degenerate input. */
7
+ export function cosineSimilarity(a, b) {
8
+ const n = Math.min(a.length, b.length);
9
+ let dot = 0;
10
+ let na = 0;
11
+ let nb = 0;
12
+ for (let i = 0; i < n; i++) {
13
+ dot += a[i] * b[i];
14
+ na += a[i] * a[i];
15
+ nb += b[i] * b[i];
16
+ }
17
+ if (na === 0 || nb === 0)
18
+ return 0;
19
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
20
+ }
21
+ export class InMemoryVectorStore {
22
+ chunks = [];
23
+ hydrated = false;
24
+ io;
25
+ constructor(opts = {}) {
26
+ this.io = opts.io;
27
+ }
28
+ async hydrate() {
29
+ if (this.hydrated)
30
+ return;
31
+ this.hydrated = true;
32
+ if (this.io) {
33
+ try {
34
+ this.chunks = await this.io.load();
35
+ }
36
+ catch {
37
+ this.chunks = [];
38
+ }
39
+ }
40
+ }
41
+ async upsert(chunks) {
42
+ await this.hydrate();
43
+ for (const c of chunks) {
44
+ const i = this.chunks.findIndex((x) => x.id === c.id);
45
+ if (i >= 0)
46
+ this.chunks[i] = c;
47
+ else
48
+ this.chunks.push(c);
49
+ }
50
+ if (this.io)
51
+ await this.io.save(this.chunks);
52
+ }
53
+ async query(embedding, k) {
54
+ await this.hydrate();
55
+ return this.chunks
56
+ .filter((c) => c.embedding && c.embedding.length > 0)
57
+ .map((c) => ({ ...c, score: cosineSimilarity(embedding, c.embedding) }))
58
+ .sort((a, b) => b.score - a.score)
59
+ .slice(0, k);
60
+ }
61
+ async size() {
62
+ await this.hydrate();
63
+ return this.chunks.length;
64
+ }
65
+ async clear() {
66
+ await this.hydrate();
67
+ this.chunks = [];
68
+ if (this.io)
69
+ await this.io.save(this.chunks);
70
+ }
71
+ }
72
+ //# sourceMappingURL=vector-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.js","sourceRoot":"","sources":["../../src/rag/vector-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Built-in "send an RGB asset" recipe — distinct from the BTC payments recipe
3
+ * because an asset amount must NOT be treated as fiat.
4
+ *
5
+ * "send 10 USDT to bob" → resolve_contact → rln_send_asset 🔒
6
+ * "pay alice 5 XAUT" → resolve_contact → rln_send_asset 🔒
7
+ *
8
+ * Fixes the bug where the payments recipe parsed "USDT" as a fiat currency and
9
+ * ran fiat_to_sats. Payments now excludes RGB assets; this recipe owns them.
10
+ */
11
+ import type { Recipe } from './types.js';
12
+ /** "send 10 USDT to bob" / "pay alice 5 xaut". */
13
+ export declare function extractAssetSend(text: string): Record<string, unknown> | null;
14
+ export declare const assetSendRecipe: Recipe;
15
+ //# sourceMappingURL=asset-send.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-send.d.ts","sourceRoot":"","sources":["../../src/recipe/asset-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,YAAY,CAAC;AAoBxD,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAa7E;AAED,eAAO,MAAM,eAAe,EAAE,MA+B7B,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Built-in "send an RGB asset" recipe — distinct from the BTC payments recipe
3
+ * because an asset amount must NOT be treated as fiat.
4
+ *
5
+ * "send 10 USDT to bob" → resolve_contact → rln_send_asset 🔒
6
+ * "pay alice 5 XAUT" → resolve_contact → rln_send_asset 🔒
7
+ *
8
+ * Fixes the bug where the payments recipe parsed "USDT" as a fiat currency and
9
+ * ran fiat_to_sats. Payments now excludes RGB assets; this recipe owns them.
10
+ */
11
+ const RGB_ASSET = /\b(usdt|tether|xaut|gold)\b/i;
12
+ const isOnchainOrInvoice = (s) => /^(ln(bc|tb|bcrt)|bc1|tb1|lnurl|rgb:|[a-z0-9._-]+@)/i.test(s.trim());
13
+ function normAsset(a) {
14
+ if (!a)
15
+ return undefined;
16
+ const x = a.toLowerCase();
17
+ if (/usdt|tether/.test(x))
18
+ return 'USDT';
19
+ if (/xaut|gold/.test(x))
20
+ return 'XAUT';
21
+ return a.toUpperCase();
22
+ }
23
+ function parseAmount(t) {
24
+ const m = t.match(/(\d[\d.,]*)\s*([km])?\b/i);
25
+ if (!m)
26
+ return undefined;
27
+ let n = Number(m[1].replace(/,/g, ''));
28
+ if (m[2])
29
+ n *= m[2].toLowerCase() === 'k' ? 1_000 : 1_000_000;
30
+ return Number.isNaN(n) ? undefined : n;
31
+ }
32
+ /** "send 10 USDT to bob" / "pay alice 5 xaut". */
33
+ export function extractAssetSend(text) {
34
+ const t = text.trim();
35
+ if (!/\b(send|pay|transfer)\b/i.test(t))
36
+ return null;
37
+ const asset = normAsset(t.match(RGB_ASSET)?.[1]);
38
+ if (!asset)
39
+ return null; // not an asset send → let the payments recipe handle it
40
+ const amount = parseAmount(t);
41
+ let recipient = t.match(/\bto\s+([^\s,]+)/i)?.[1];
42
+ if (!recipient) {
43
+ const after = t.match(/\b(?:pay|send|transfer)\s+([^\s,]+)/i)?.[1];
44
+ if (after && !/^\d/.test(after) && !RGB_ASSET.test(after))
45
+ recipient = after;
46
+ }
47
+ if (!recipient && amount == null)
48
+ return null;
49
+ return { recipient, asset, amount };
50
+ }
51
+ export const assetSendRecipe = {
52
+ name: 'pay-asset',
53
+ description: 'Send an RGB asset (USDT, XAUT) to a contact or address — resolves the contact, then sends (with confirmation).',
54
+ match: (t) => /\b(send|pay|transfer)\b/i.test(t) && RGB_ASSET.test(t) && !/\b(invoice|receive|swap|buy|sell|for)\b/i.test(t),
55
+ triggers: ['send', 'pay', 'transfer'],
56
+ slots: [
57
+ { name: 'recipient', type: 'string', description: 'Contact name, address, or RGB invoice', required: true },
58
+ { name: 'asset', type: 'string', description: 'RGB asset: USDT or XAUT', required: true },
59
+ { name: 'amount', type: 'number', description: 'Asset amount' },
60
+ ],
61
+ extract: extractAssetSend,
62
+ confident: (s) => !!s.recipient && !!s.asset,
63
+ steps: [
64
+ {
65
+ tool: 'resolve_contact',
66
+ as: 'contact',
67
+ args: (ctx) => ({ name: ctx.slots.recipient }),
68
+ skipIf: (ctx) => !ctx.slots.recipient || isOnchainOrInvoice(String(ctx.slots.recipient)),
69
+ },
70
+ ],
71
+ final: {
72
+ tool: 'rln_send_asset',
73
+ args: (ctx) => {
74
+ const contact = ctx.results.contact;
75
+ return { asset: ctx.slots.asset, amount: ctx.slots.amount, to: contact?.ln_address ?? ctx.slots.recipient };
76
+ },
77
+ },
78
+ summary: (ctx) => {
79
+ const to = ctx.results.contact?.name ?? ctx.slots.recipient;
80
+ return `Sent ${ctx.slots.amount} ${ctx.slots.asset} to ${to}.`;
81
+ },
82
+ };
83
+ //# sourceMappingURL=asset-send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-send.js","sourceRoot":"","sources":["../../src/recipe/asset-send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,SAAS,GAAG,8BAA8B,CAAC;AACjD,MAAM,kBAAkB,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,qDAAqD,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAE/G,SAAS,SAAS,CAAC,CAAU;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1B,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACzC,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACvC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AACzB,CAAC;AACD,SAAS,WAAW,CAAC,CAAS;IAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,CAAC,wDAAwD;IACjF,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,sCAAsC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,SAAS,GAAG,KAAK,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAW;IACrC,IAAI,EAAE,WAAW;IACjB,WAAW,EAAE,gHAAgH;IAC7H,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5H,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC;IACrC,KAAK,EAAE;QACL,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC3G,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzF,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;KAChE;IACD,OAAO,EAAE,gBAAgB;IACzB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK;IAC5C,KAAK,EAAE;QACL;YACE,IAAI,EAAE,iBAAiB;YACvB,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YAC9C,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;SACzF;KACF;IACD,KAAK,EAAE;QACL,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,CAAC,GAAkB,EAAE,EAAE;YAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,OAA8C,CAAC;YAC3E,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QAC9G,CAAC;KACF;IACD,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,EAAE,GAAI,GAAG,CAAC,OAAO,CAAC,OAAyC,EAAE,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QAC/F,OAAO,QAAQ,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,GAAG,CAAC;IACjE,CAAC;CACF,CAAC"}
@@ -0,0 +1,27 @@
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 type { Recipe } from './types.js';
26
+ export declare const kaleidoswapAtomicRecipe: Recipe;
27
+ //# sourceMappingURL=kaleidoswap-atomic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kaleidoswap-atomic.d.ts","sourceRoot":"","sources":["../../src/recipe/kaleidoswap-atomic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAUzC,eAAO,MAAM,uBAAuB,EAAE,MAiFrC,CAAC"}