@kaleidorg/mind 0.5.0 → 0.6.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 (109) hide show
  1. package/dist/autonomy/index.d.ts +21 -0
  2. package/dist/autonomy/index.d.ts.map +1 -0
  3. package/dist/autonomy/index.js +16 -0
  4. package/dist/autonomy/index.js.map +1 -0
  5. package/dist/autonomy/prompt.d.ts +21 -0
  6. package/dist/autonomy/prompt.d.ts.map +1 -0
  7. package/dist/autonomy/prompt.js +37 -0
  8. package/dist/autonomy/prompt.js.map +1 -0
  9. package/dist/autonomy/risk.d.ts +53 -0
  10. package/dist/autonomy/risk.d.ts.map +1 -0
  11. package/dist/autonomy/risk.js +74 -0
  12. package/dist/autonomy/risk.js.map +1 -0
  13. package/dist/autonomy/run-state.d.ts +39 -0
  14. package/dist/autonomy/run-state.d.ts.map +1 -0
  15. package/dist/autonomy/run-state.js +118 -0
  16. package/dist/autonomy/run-state.js.map +1 -0
  17. package/dist/autonomy/scheduler.d.ts +18 -0
  18. package/dist/autonomy/scheduler.d.ts.map +1 -0
  19. package/dist/autonomy/scheduler.js +113 -0
  20. package/dist/autonomy/scheduler.js.map +1 -0
  21. package/dist/autonomy/task-store.d.ts +44 -0
  22. package/dist/autonomy/task-store.d.ts.map +1 -0
  23. package/dist/autonomy/task-store.js +139 -0
  24. package/dist/autonomy/task-store.js.map +1 -0
  25. package/dist/autonomy/types.d.ts +164 -0
  26. package/dist/autonomy/types.d.ts.map +1 -0
  27. package/dist/autonomy/types.js +20 -0
  28. package/dist/autonomy/types.js.map +1 -0
  29. package/dist/funnel.d.ts.map +1 -1
  30. package/dist/funnel.js +12 -0
  31. package/dist/funnel.js.map +1 -1
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +4 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/knowledge/bitcoin-copilot.js +2 -2
  37. package/dist/knowledge/bitcoin-copilot.js.map +1 -1
  38. package/dist/qvac/index.d.ts +1 -1
  39. package/dist/qvac/index.d.ts.map +1 -1
  40. package/dist/qvac/index.js.map +1 -1
  41. package/dist/qvac/parse.d.ts +33 -0
  42. package/dist/qvac/parse.d.ts.map +1 -1
  43. package/dist/qvac/parse.js +69 -5
  44. package/dist/qvac/parse.js.map +1 -1
  45. package/dist/qvac/provider.d.ts +16 -0
  46. package/dist/qvac/provider.d.ts.map +1 -1
  47. package/dist/qvac/provider.js +17 -1
  48. package/dist/qvac/provider.js.map +1 -1
  49. package/dist/qvac/stream.d.ts +16 -0
  50. package/dist/qvac/stream.d.ts.map +1 -1
  51. package/dist/qvac/stream.js +21 -1
  52. package/dist/qvac/stream.js.map +1 -1
  53. package/dist/qvac/text.d.ts.map +1 -1
  54. package/dist/qvac/text.js +4 -0
  55. package/dist/qvac/text.js.map +1 -1
  56. package/dist/recipe/buy-asset-channel.d.ts +1 -1
  57. package/dist/recipe/buy-asset-channel.d.ts.map +1 -1
  58. package/dist/recipe/buy-asset-channel.js +4 -3
  59. package/dist/recipe/buy-asset-channel.js.map +1 -1
  60. package/dist/recipe/kaleidoswap-atomic.d.ts +1 -1
  61. package/dist/recipe/kaleidoswap-atomic.d.ts.map +1 -1
  62. package/dist/recipe/kaleidoswap-atomic.js +5 -4
  63. package/dist/recipe/kaleidoswap-atomic.js.map +1 -1
  64. package/dist/recipe/runner.d.ts.map +1 -1
  65. package/dist/recipe/runner.js +38 -0
  66. package/dist/recipe/runner.js.map +1 -1
  67. package/dist/tools/mcp.d.ts +19 -0
  68. package/dist/tools/mcp.d.ts.map +1 -1
  69. package/dist/tools/mcp.js +51 -9
  70. package/dist/tools/mcp.js.map +1 -1
  71. package/package.json +2 -1
  72. package/skills/channel-manager/SKILL.md +59 -0
  73. package/skills/dca/SKILL.md +48 -0
  74. package/skills/kaleido-lsps/SKILL.md +12 -12
  75. package/skills/kaleido-trading/SKILL.md +1 -1
  76. package/skills/liquidity-optimizer/SKILL.md +91 -0
  77. package/skills/merchant-finder/SKILL.md +1 -1
  78. package/skills/portfolio-manager/SKILL.md +67 -0
  79. package/skills/rgb-lightning-node/SKILL.md +3 -3
  80. package/skills/wallet-assistant/SKILL.md +1 -1
  81. package/src/autonomy/autonomy.test.ts +348 -0
  82. package/src/autonomy/index.ts +50 -0
  83. package/src/autonomy/prompt.ts +48 -0
  84. package/src/autonomy/risk.ts +139 -0
  85. package/src/autonomy/run-state.ts +144 -0
  86. package/src/autonomy/scheduler.ts +120 -0
  87. package/src/autonomy/task-store.ts +167 -0
  88. package/src/autonomy/types.ts +186 -0
  89. package/src/funnel.mind.test.ts +390 -0
  90. package/src/funnel.ts +14 -0
  91. package/src/index.ts +41 -0
  92. package/src/knowledge/bitcoin-copilot.ts +2 -2
  93. package/src/qvac/index.ts +1 -0
  94. package/src/qvac/parse.test.ts +70 -1
  95. package/src/qvac/parse.ts +91 -5
  96. package/src/qvac/provider.test.ts +17 -0
  97. package/src/qvac/provider.ts +37 -1
  98. package/src/qvac/stream.test.ts +25 -0
  99. package/src/qvac/stream.ts +38 -1
  100. package/src/qvac/text.ts +4 -0
  101. package/src/recipe/buy-asset-channel.test.ts +5 -0
  102. package/src/recipe/buy-asset-channel.ts +6 -3
  103. package/src/recipe/kaleidoswap-atomic.test.ts +3 -3
  104. package/src/recipe/kaleidoswap-atomic.ts +5 -4
  105. package/src/recipe/recipe.test.ts +16 -0
  106. package/src/recipe/runner.ts +41 -0
  107. package/src/tools/mcp.live.test.ts +116 -0
  108. package/src/tools/mcp.parse.test.ts +37 -0
  109. package/src/tools/mcp.ts +55 -9
package/dist/tools/mcp.js CHANGED
@@ -17,6 +17,51 @@
17
17
  * execute() are implemented. Used by the desktop sidecar (kaleido-mcp +
18
18
  * Bitrefill MCP) and verified against the remote Bitrefill MCP.
19
19
  */
20
+ import { isKaleidoswapSpendTool } from '../kaleidoswap/contract.js';
21
+ import { isLsps1SpendTool } from '../lsps1/contract.js';
22
+ import { isSpendTool } from '../wallet/contract.js';
23
+ function toolRequiresConfirmation(name, description) {
24
+ return (isSpendTool(name) ||
25
+ isKaleidoswapSpendTool(name) ||
26
+ isLsps1SpendTool(name) ||
27
+ /\bSPEND\b.*\bconfirm/i.test(description));
28
+ }
29
+ /**
30
+ * Normalize an MCP `callTool` result into a structured value.
31
+ *
32
+ * Two fixes vs. returning the raw text content:
33
+ * - `isError` (the MCP failure signal) becomes an `{ error }` object, so callers
34
+ * — the recipe runner's `toolFailure`, the agent — treat it as a FAILURE
35
+ * instead of a successful result. Without this the agent claimed a spend had
36
+ * succeeded when the wallet actually rejected it.
37
+ * - JSON text is PARSED, so recipes thread real fields (rfq_id, total_sat,
38
+ * order_id) and any failure fields (error/status) are visible. A raw string
39
+ * hid both — the quote's rfq_id never reached the create call, and the canned
40
+ * success summary fired regardless. Non-JSON text passes through unchanged;
41
+ * the engine re-stringifies objects when feeding the model.
42
+ *
43
+ * Exported for unit testing.
44
+ */
45
+ export function parseMcpResult(res) {
46
+ const r = res;
47
+ const text = Array.isArray(r?.content)
48
+ ? r.content
49
+ .filter((c) => c?.type === 'text')
50
+ .map((c) => c?.text ?? '')
51
+ .join('\n')
52
+ : '';
53
+ if (r?.isError)
54
+ return { error: text || 'The tool reported an error.' };
55
+ if (text) {
56
+ try {
57
+ return JSON.parse(text);
58
+ }
59
+ catch {
60
+ return text;
61
+ }
62
+ }
63
+ return Array.isArray(r?.content) ? r.content : res;
64
+ }
20
65
  export class McpToolSource {
21
66
  id;
22
67
  opts;
@@ -46,12 +91,15 @@ export class McpToolSource {
46
91
  await this.client.connect(transport);
47
92
  const listed = await this.client.listTools();
48
93
  const allow = this.opts.allow ? new Set(this.opts.allow) : null;
94
+ const denied = this.opts.denyPrefixes ?? [];
49
95
  this.tools = (listed.tools ?? [])
50
96
  .filter((t) => !allow || allow.has(t.name))
97
+ .filter((t) => !denied.some((prefix) => t.name.startsWith(prefix)))
51
98
  .map((t) => ({
52
99
  name: t.name,
53
100
  description: t.description ?? '',
54
101
  parameters: t.inputSchema ?? { type: 'object', properties: {} },
102
+ requiresConfirmation: toolRequiresConfirmation(t.name, t.description ?? ''),
55
103
  }));
56
104
  }
57
105
  listTools() {
@@ -64,15 +112,9 @@ export class McpToolSource {
64
112
  if (!this.client)
65
113
  throw new Error(`McpToolSource "${this.id}" not connected — call connect() first`);
66
114
  const res = await this.client.callTool({ name, arguments: args }, undefined, { timeout: this.opts.timeoutMs ?? 60_000 });
67
- // MCP returns content blocks; surface text content as the tool result.
68
- if (Array.isArray(res?.content)) {
69
- const text = res.content
70
- .filter((c) => c.type === 'text')
71
- .map((c) => c.text)
72
- .join('\n');
73
- return text || res.content;
74
- }
75
- return res;
115
+ // Parse JSON + surface isError so recipes/agent get structured results and
116
+ // real failures (not an opaque string that hid both). See parseMcpResult.
117
+ return parseMcpResult(res);
76
118
  }
77
119
  async close() {
78
120
  await this.client?.close?.();
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/tools/mcp.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.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Local-first reasoning + function-calling engine for KaleidoSwap. QVAC-powered.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -53,6 +53,7 @@
53
53
  "build": "tsc",
54
54
  "typecheck": "tsc --noEmit",
55
55
  "test": "vitest run",
56
+ "test:live": "vitest run mcp.live",
56
57
  "lint": "eslint src",
57
58
  "bundle-skills": "node scripts/bundle-skills.mjs"
58
59
  },
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: channel-manager
3
+ description: "Keep the Lightning node healthy: check node info, audit channels and liquidity, flush stuck RGB transfers, and (when allowed) buy inbound/asset channel capacity via the KaleidoSwap LSP. Triggers when the user asks about node health, channels, liquidity, or inbound capacity — and is the skill the scheduled 'heartbeat' loop runs."
4
+ tools: rln_get_node_info, rln_list_channels, rln_get_balances, rln_list_assets, rln_refresh_transfers, kaleidoswap_lsp_get_info, kaleidoswap_lsp_estimate_fees, kaleidoswap_lsp_create_order, rln_pay_invoice
5
+ triggers: node, channel, channels, liquidity, inbound, outbound, lsp, heartbeat, health, transfers, stuck
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.1.0"
9
+ ---
10
+
11
+ # Channel manager
12
+
13
+ Keep the RGB Lightning node healthy and liquid. Read state every run; only buy
14
+ capacity when the user allows it and it's actually needed.
15
+
16
+ ## Critical rules — these override everything else
17
+
18
+ - **Diagnose before acting.** `rln_get_node_info` + `rln_list_channels` +
19
+ `rln_get_balances` first. Report what you see; don't guess.
20
+ - **Respect `dry_run`.** When true, describe the action you *would* take (e.g.
21
+ "buy 1M sat inbound") but do NOT call `kaleidoswap_lsp_create_order` or
22
+ `rln_pay_invoice`.
23
+ - **Buying capacity is a spend** — it routes through the host's risk gate. Never
24
+ propose one that breaches the BTC reserve, and always show the LSP fee
25
+ (`kaleidoswap_lsp_estimate_fees`) before recommending it.
26
+
27
+ ## Health checks (run in order)
28
+
29
+ 1. **Node up?** `rln_get_node_info` — pubkey, block height, synced.
30
+ 2. **Channels.** `rln_list_channels` — count, capacity, outbound vs inbound. Flag
31
+ any channel whose outbound is below the configured floor.
32
+ 3. **Stuck transfers.** `rln_refresh_transfers` to flush pending RGB transfers;
33
+ report anything still pending afterward.
34
+ 4. **Liquidity verdict.** If usable inbound (or an asset's inbound) is below the
35
+ threshold in the task parameters, that's the trigger to consider buying.
36
+
37
+ ## Buying capacity (only when needed + allowed)
38
+
39
+ 1. `kaleidoswap_lsp_get_info` — confirm the LSP is reachable + its limits.
40
+ 2. `kaleidoswap_lsp_estimate_fees` — show the fee for the size you'd buy.
41
+ 3. `kaleidoswap_lsp_create_order` (spend-gated) — create the order; it returns an
42
+ invoice/onchain address. Pay via `rln_pay_invoice` only after approval.
43
+
44
+ ## Scheduled (background) runs
45
+
46
+ When run by the `heartbeat` loop, return STRICT JSON only:
47
+
48
+ ```
49
+ {"task":"heartbeat","timestamp":"<ISO8601>","action":"ok|flush|buy_capacity|alert","dry_run":<bool>,"reason":"<why>","details":{"channels":<n>,"outbound_sat":<n>,"inbound_sat":<n>,"pending_transfers":<n>}}
50
+ ```
51
+
52
+ Use `ok` when nothing needs doing, `alert` when a human should look.
53
+
54
+ ## Don'ts
55
+
56
+ - Don't buy capacity that isn't needed, or when within the liquidity threshold.
57
+ - Don't pay an LSP invoice when `dry_run` is true.
58
+ - Don't invent channel ids, balances, or fees — read them from tools.
59
+ - Don't breach the BTC reserve to open a channel.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: dca
3
+ description: "Dollar-cost-average a fixed budget into a target asset on a schedule. Reads the live quote and (when allowed) buys a small fixed slice via an atomic swap, respecting per-run allocation and risk limits. Triggers when the user mentions DCA, recurring buys, or averaging in — and is the skill a user-created DCA loop runs."
4
+ tools: rln_get_balances, kaleidoswap_get_quote, kaleidoswap_atomic_init, kaleidoswap_atomic_execute, kaleidoswap_atomic_status, get_price
5
+ triggers: dca, dollar cost average, recurring buy, average in, accumulate, stack
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.1.0"
9
+ ---
10
+
11
+ # Dollar-cost averaging
12
+
13
+ Buy a fixed, small slice of a target asset each run. Boring on purpose: same
14
+ size, every interval, regardless of price.
15
+
16
+ ## Critical rules — these override everything else
17
+
18
+ - **Fixed slice only.** The per-run budget is the task's `allocation` — never
19
+ exceed it, never "catch up" by buying extra after a missed run.
20
+ - **Respect `dry_run`.** When true, quote and report what you *would* buy; do NOT
21
+ execute.
22
+ - **Respect risk + reserve.** A DCA buy is a spend; it passes through the host's
23
+ risk gate. Never breach the BTC reserve or the max single-spend limit.
24
+
25
+ ## Each run
26
+
27
+ 1. **Check funds.** `rln_get_balances` — is there enough BTC for one slice plus
28
+ the reserve? If not, return `action: "skip"` with the reason.
29
+ 2. **Quote.** `kaleidoswap_get_quote(BTC, <asset>, <slice>)`. Read the
30
+ `to_amount_display` / `fee_display` strings verbatim — no arithmetic.
31
+ 3. **Execute** (only when `dry_run` is false and within limits): the atomic swap
32
+ recipe drives `kaleidoswap_atomic_init` → `_execute`; then poll
33
+ `kaleidoswap_atomic_status`.
34
+
35
+ ## Scheduled (background) runs
36
+
37
+ Return STRICT JSON only:
38
+
39
+ ```
40
+ {"task":"<task id>","timestamp":"<ISO8601>","action":"buy|skip","dry_run":<bool>,"reason":"<why>","details":{"asset":"<asset>","slice":"<n>","received":"<display>","fee":"<display>"}}
41
+ ```
42
+
43
+ ## Don'ts
44
+
45
+ - Don't vary the slice size or try to time the market — that's not DCA.
46
+ - Don't buy when funds are below the reserve — `skip` instead.
47
+ - Don't execute when `dry_run` is true.
48
+ - Don't invent a quote — only the current `kaleidoswap_get_quote` result is real.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: kaleido-lsps
3
3
  description: "Buy inbound Lightning channel capacity from a Lightning Service Provider (LSPS1). Quote a channel, estimate fees, place a channel order, and check order status. Triggers when the user wants inbound liquidity, says they can't receive a payment, needs a channel, asks about LSP fees, or wants to check the status of a channel order / LSP order."
4
- tools: lsp_get_info, lsp_get_network_info, lsp_estimate_fees, lsp_create_order, lsp_get_order, rln_get_node_info, rln_pay_invoice
4
+ tools: kaleidoswap_lsp_get_info, kaleidoswap_lsp_estimate_fees, kaleidoswap_lsp_create_order, kaleidoswap_lsp_get_order, kaleidoswap_lsp_quote_asset_channel, kaleidoswap_lsp_create_asset_channel, lsp_get_info, lsp_estimate_fees, lsp_create_order, lsp_get_order, rln_get_node_info, rln_pay_invoice
5
5
  triggers: inbound, liquidity, channel order, lsp, lsps1, receive limit, can't receive, open channel, channel from, check status, order status, check the order, channel status, lsp status, check my channel
6
6
  metadata:
7
7
  author: kaleidoswap
@@ -21,11 +21,11 @@ talks to — the KaleidoSwap maker by default. Tool names are LSP-agnostic
21
21
  You have **no knowledge** of LSP capabilities, fees, channel sizes, or order
22
22
  status. Every number, capacity, fee, order id, or invoice in your reply MUST
23
23
  come from a tool result returned in the CURRENT turn. Never quote a fee from
24
- memory. Never claim an order completed without calling `lsp_get_order`.
24
+ memory. Never claim an order completed without calling `kaleidoswap_lsp_get_order`.
25
25
  Never reuse a number from a previous turn.
26
26
 
27
27
  **Calling the tool IS the answer.** Don't write "the LSP info is fetched with
28
- `lsp_get_info`" — call it. Don't reveal tool names in your reply; describe
28
+ `kaleidoswap_lsp_get_info`" — call it. Don't reveal tool names in your reply; describe
29
29
  what you're doing in plain language.
30
30
 
31
31
  If a tool needs a required argument the user didn't give (e.g. `client_pubkey`
@@ -40,7 +40,7 @@ The same conventions as trading apply:
40
40
 
41
41
  ## Tools and the flow
42
42
 
43
- ### Step 1 — `lsp_get_info`
43
+ ### Step 1 — `kaleidoswap_lsp_get_info`
44
44
  No args. Returns the LSP's `OrderOptions` (min/max channel size, min/max
45
45
  expiry, etc.) and the `assets` list. **Call it once before estimating** so you
46
46
  can validate the user's request against the LSP's limits.
@@ -49,7 +49,7 @@ If the user wants 1M sats inbound but `max_initial_lsp_balance_sat` is 500k,
49
49
  say so plainly and offer the maximum — don't push through and let the maker
50
50
  reject it.
51
51
 
52
- ### Step 2 — `lsp_estimate_fees` (read-only)
52
+ ### Step 2 — `kaleidoswap_lsp_estimate_fees` (read-only)
53
53
  Required args: `lsp_balance_sat`, `client_balance_sat`, `channel_expiry_blocks`.
54
54
 
55
55
  Defaults you can use silently if the user didn't specify:
@@ -60,10 +60,10 @@ Returns `{setup_fee, capacity_fee, duration_fee, total_fee}` — surface
60
60
  `total_fee` to the user and the breakdown when relevant.
61
61
 
62
62
  ### Step 3 — `rln_get_node_info`
63
- No args. Returns `{pubkey, ...}`. **Pubkey is required by `lsp_create_order` —
63
+ No args. Returns `{pubkey, ...}`. **Pubkey is required by `kaleidoswap_lsp_create_order` —
64
64
  fetch it deterministically. Never invent a pubkey.**
65
65
 
66
- ### Step 4 — `lsp_create_order` 🔒 spend
66
+ ### Step 4 — `kaleidoswap_lsp_create_order` 🔒 spend
67
67
  Required args: `client_pubkey` (from step 3), `lsp_balance_sat`. The maker
68
68
  also expects `client_balance_sat`, `required_channel_confirmations`,
69
69
  `funding_confirms_within_blocks`, `channel_expiry_blocks`, `announce_channel`
@@ -72,7 +72,7 @@ didn't specify, so just pass the values the user actually named.
72
72
 
73
73
  Returns:
74
74
  - `order_id`
75
- - `access_token` (save it — required for `lsp_get_order`)
75
+ - `access_token` (save it — required for `kaleidoswap_lsp_get_order`)
76
76
  - `payment.bolt11.invoice` — Lightning invoice to pay
77
77
  - `payment.bolt11.order_total_sat` — the sats that need to flow
78
78
  - `payment.onchain.address` — optional on-chain fallback
@@ -82,11 +82,11 @@ Returns:
82
82
  Hand the `payment.bolt11.invoice` to `rln_pay_invoice`. This is a separate
83
83
  spend gate at the wallet contract; the user confirms paying the LSP.
84
84
 
85
- ### Step 6 — `lsp_get_order` (poll)
85
+ ### Step 6 — `kaleidoswap_lsp_get_order` (poll)
86
86
  **Args: `order_id`, `access_token` (BOTH required — never omit either).**
87
87
  `order_state` progresses `CREATED → CHANNEL_OPENING → COMPLETED` (or `FAILED`).
88
88
  Poll until terminal. Always pass the exact order_id and access_token from the
89
- previous `lsp_create_order` result (or from the summary that listed them).
89
+ previous `kaleidoswap_lsp_create_order` result (or from the summary that listed them).
90
90
  Report the outcome plainly with the new channel id from `channel.channel_id` if present.
91
91
 
92
92
  ## Don'ts
@@ -97,9 +97,9 @@ Report the outcome plainly with the new channel id from `channel.channel_id` if
97
97
  - Don't describe how a tool works — call it.
98
98
  - Don't pay a Lightning invoice without confirming the amount + LSP — the
99
99
  spend gate at `rln_pay_invoice` shows the user the destination.
100
- - Don't claim an order completed without polling `lsp_get_order` with BOTH
100
+ - Don't claim an order completed without polling `kaleidoswap_lsp_get_order` with BOTH
101
101
  `order_id` and `access_token` and seeing `order_state: COMPLETED`.
102
- - Never call `lsp_get_order` with only the access_token or only the order_id.
102
+ - Never call `kaleidoswap_lsp_get_order` with only the access_token or only the order_id.
103
103
  Always extract the exact values from the previous turn's summary (the one that
104
104
  said "order_id=... access_token=...") and pass them as separate arguments.
105
105
  - Don't ask the user for their node pubkey — fetch it from `rln_get_node_info`.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: kaleido-trading
3
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 quote, to swap or trade assets, or to rebalance between BTC and stablecoins."
4
- tools: kaleidoswap_get_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_get_nodeinfo, kaleidoswap_place_order, kaleidoswap_get_order_status, kaleidoswap_get_order_history
4
+ tools: kaleidoswap_get_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_place_order, kaleidoswap_get_order_status, kaleidoswap_atomic_init, kaleidoswap_atomic_execute, kaleidoswap_atomic_status, rln_get_node_info, rln_atomic_taker
5
5
  triggers: quote, swap, trade, rebalance, slippage, pair, pairs, usdt, xaut, kaleidoswap, rfq
6
6
  metadata:
7
7
  author: kaleidoswap
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: liquidity-optimizer
3
+ description: "Analyze and optimize the node's Lightning liquidity. Reads channels, balances and payment history, then explains the node's liquidity health and recommends concrete actions: buy inbound, open/close channels, rebalance BTC↔assets, or tune routing fees. Triggers when the user wants to rebalance, optimize liquidity, fix inbound/outbound balance, free up capital, lower fees, or asks 'how healthy is my node?' / 'where is my liquidity?'."
4
+ tools: rln_list_channels, rln_get_balances, rln_get_node_info, rln_list_payments, kaleidoswap_lsp_get_info, kaleidoswap_lsp_estimate_fees, kaleidoswap_lsp_quote_asset_channel, rln_open_channel, rln_close_channel
5
+ triggers: rebalance, rebalancing, optimize liquidity, liquidity, inbound, outbound, lopsided, depleted channel, free up capital, stuck funds, channel balance, routing fee, lower fees, fee optimization, node health, healthy node, where is my liquidity, capacity
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.1.0"
9
+ ---
10
+
11
+ # Liquidity optimizer
12
+
13
+ Help the user keep their RGB Lightning node's liquidity healthy: balanced
14
+ inbound/outbound, capital not stuck in dead channels, and fees set so the node
15
+ can actually route and receive. You **analyze real channel state and recommend
16
+ actions** — you never move funds without an explicit, confirmed instruction.
17
+
18
+ ## Critical rules — these override everything else
19
+
20
+ You have **no knowledge** of the node's channels, balances, or capacity. Every
21
+ number, channel id, ratio, or fee in your reply MUST come from a tool result
22
+ returned in the CURRENT turn. Never quote a balance from memory or reuse a
23
+ number from a previous turn — re-read it.
24
+
25
+ **Calling the tool IS the analysis.** Don't say "I'd check your channels with
26
+ `rln_list_channels`" — call it, then report what it returned in plain language.
27
+ Don't reveal raw tool names in your reply.
28
+
29
+ **Read freely, spend never (without confirmation).** `rln_list_channels`,
30
+ `rln_get_balances`, `rln_get_node_info`, `rln_list_payments`,
31
+ `kaleidoswap_lsp_get_info`, and `kaleidoswap_lsp_estimate_fees` are read-only —
32
+ use them as much as you need. `rln_open_channel`, `rln_close_channel`, and
33
+ buying a channel are **spends**: only call them when the user explicitly asked
34
+ for that action this turn, and each goes through the wallet's confirmation gate.
35
+ When you merely *recommend* an action, describe it — do not execute it.
36
+
37
+ ## How to assess liquidity
38
+
39
+ ### 1 — Read the state (always start here)
40
+ - `rln_list_channels` → `channel_count`, `total_outbound_msat`,
41
+ `total_inbound_msat`, and per-channel `outbound_balance_msat`,
42
+ `inbound_balance_msat`, `is_usable`, capacity, peer, and any RGB asset
43
+ allocation. **Balances are in millisats (msat); divide by 1000 for sats.**
44
+ - `rln_get_balances` → on-chain (vanilla/colored) + Lightning balance, to see
45
+ uncommitted capital that could open a channel.
46
+ - `rln_get_node_info` → pubkey, peer/channel counts, sync state.
47
+ - `rln_list_payments` (optional) → recent flow direction, to infer whether the
48
+ node mostly sends or receives.
49
+
50
+ ### 2 — Compute the picture (per channel and overall)
51
+ For each channel, the **outbound ratio** = `outbound / (outbound + inbound)`:
52
+ - **~0% (all inbound):** can receive but can't send — depleted outbound.
53
+ - **~100% (all outbound):** can send but can't receive — no inbound liquidity.
54
+ - **40–60%:** balanced and healthy.
55
+ Then look at the totals: is the node short on **inbound** (can't receive) or
56
+ short on **outbound** (can't send)? Flag channels that are `is_usable: false`
57
+ (offline/pending peer) or that hold meaningful capital but never route.
58
+
59
+ ### 3 — Recommend, prioritized
60
+ Lead with a one-line health verdict, then a short ordered action list. Match the
61
+ remedy to the problem:
62
+ - **Low inbound / "can't receive":** buy inbound from the LSP. Use
63
+ `kaleidoswap_lsp_get_info` for limits and `kaleidoswap_lsp_estimate_fees`
64
+ (or `kaleidoswap_lsp_quote_asset_channel` for an asset channel) to give a real
65
+ fee, then hand off to the channel-order flow. Don't invent the fee.
66
+ - **Low outbound / "can't send":** open a channel to a well-connected peer with
67
+ spare on-chain BTC (`rln_open_channel`), or fund the wallet first.
68
+ - **Lopsided but funded both ways:** rebalance instead of opening new channels —
69
+ for BTC↔asset imbalance, suggest a swap (the trading flow), since circular
70
+ rebalancing may not be available on this node.
71
+ - **Dead/offline channels with stuck capital:** consider closing
72
+ (`rln_close_channel`) to reclaim funds, but only if the user confirms — note
73
+ on-chain fees and the ~hours for funds to settle.
74
+ - **Fees:** if the node should route more, suggest lower routing fees; if it's
75
+ draining outbound cheaply, suggest raising them. If no fee-setting tool is
76
+ available this turn, give the recommendation and tell the user where to set it
77
+ rather than pretending you changed it.
78
+
79
+ ## Output style
80
+ Concise and scannable. A verdict line, then "Top actions" as a short numbered
81
+ list with the concrete number behind each (e.g. "Channel abc12… is 97% outbound
82
+ — buy ~200k inbound, est. fee from the LSP"). No walls of JSON.
83
+
84
+ ## Don'ts
85
+ - Don't invent channels, balances, ratios, capacities, or fees — read them.
86
+ - Don't forget msat→sat conversion when reporting channel balances.
87
+ - Don't open or close a channel, or buy liquidity, unless the user asked for
88
+ that action this turn — recommendations are not actions.
89
+ - Don't claim you changed fees or rebalanced if no tool did it — say what the
90
+ user should do.
91
+ - Don't reuse last turn's numbers — re-read before advising again.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: merchant-finder
3
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, buy pizza/food with sats or bitcoin, eat at restaurants/cafes paying with sats, for a shop, store, restaurant, cafe, bar, or ATM that accepts Bitcoin, or for merchants nearby or in a city like turin."
4
- tools: find_merchant_locations
4
+ tools: find_merchant_locations, search_knowledge
5
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, pizz, food, coffee, eat, dinner, lunch, buy, bitcoin map, btcmap
6
6
  metadata:
7
7
  author: kaleidoswap
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: portfolio-manager
3
+ description: "Keep a BTC / USDT / XAUT portfolio near its target allocation. Read live balances and prices, detect drift versus targets, and (when allowed) rebalance via an atomic swap on KaleidoSwap. Triggers when the user asks to rebalance, check allocation, review the portfolio, or optimize holdings — and is the skill the scheduled 'rebalance' loop runs."
4
+ tools: rln_get_balances, rln_list_assets, kaleidoswap_get_pairs, kaleidoswap_get_quote, kaleidoswap_atomic_init, kaleidoswap_atomic_execute, kaleidoswap_atomic_status, get_price, get_market_data
5
+ triggers: rebalance, allocation, portfolio, drift, optimize, target, weighting, holdings
6
+ metadata:
7
+ author: kaleidoswap
8
+ version: "0.1.0"
9
+ ---
10
+
11
+ # Portfolio manager
12
+
13
+ Keep the holdings near their target weights across **BTC**, **USDT**, and
14
+ **XAUT**. You fetch everything live — never assume a balance, price, or target.
15
+
16
+ ## Critical rules — these override everything else
17
+
18
+ - **Read before you act.** Get balances (`rln_get_balances`) and prices
19
+ (`get_price`) every run. Never reuse a number from a previous turn.
20
+ - **Respect `dry_run`.** When `dry_run` is true you describe the rebalance you
21
+ *would* make — you do NOT call `kaleidoswap_atomic_init`/`_execute`. This is
22
+ non-negotiable.
23
+ - **Respect fund safety.** Never propose a swap that breaches the BTC reserve or
24
+ stop-loss floor passed in the task parameters. The host's risk gate is the
25
+ final word, but don't even suggest a breach.
26
+ - **Below-minimum drift = do nothing.** If every asset is within the drift
27
+ threshold, say so and stop. Churn is a cost, not a feature.
28
+
29
+ ## How to think about a rebalance
30
+
31
+ 1. **Snapshot.** `rln_get_balances` → BTC sats + each RGB asset (raw units).
32
+ 2. **Value it.** Convert each holding to a common denomination using
33
+ `get_price`. Do NOT do arithmetic free-hand on raw RGB units — use the
34
+ display fields the tools return; only convert sats↔USD with the live BTC
35
+ price.
36
+ 3. **Compare to targets.** Targets come in the task parameters (e.g.
37
+ `BTC 70 / USDT 20 / XAUT 10`). Compute each asset's current weight and its
38
+ drift = current − target.
39
+ 4. **Decide.** If the largest drift exceeds the threshold, the over-weight asset
40
+ sells into the most under-weight asset. One swap per run — smallest trade
41
+ that brings the worst drift back inside the band.
42
+ 5. **Quote.** `kaleidoswap_get_quote(from, to, amount)` for that single leg.
43
+ 6. **Execute** (only when `dry_run` is false and the size is within limits): the
44
+ atomic swap recipe drives `kaleidoswap_atomic_init` → `_execute`; then poll
45
+ `kaleidoswap_atomic_status`.
46
+
47
+ ## Asset codes (canonical)
48
+
49
+ `BTC` (satoshis), `USDT` (not `USD`), `XAUT` (not `XAU`/gold).
50
+
51
+ ## Scheduled (background) runs
52
+
53
+ When run by the `rebalance` loop, after deciding, return STRICT JSON only:
54
+
55
+ ```
56
+ {"task":"rebalance","timestamp":"<ISO8601>","action":"rebalance|noop","dry_run":<bool>,"reason":"<why>","details":{"from":"<asset>","to":"<asset>","amount":"<n>","drift":{}}}
57
+ ```
58
+
59
+ `action` is `noop` when within band. Put the human explanation in `reason`.
60
+
61
+ ## Don'ts
62
+
63
+ - Don't invent prices, quotes, or balances — call the tool.
64
+ - Don't rebalance on noise — honor the drift threshold.
65
+ - Don't place more than one swap per run.
66
+ - Don't breach the reserve / stop-loss, ever.
67
+ - Don't execute anything when `dry_run` is true.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: rgb-lightning-node
3
3
  description: "Drive the user's local RGB Lightning Node (RLN) — read its pubkey/status, whitelist a swap, or create Lightning/RGB receive invoices. Triggers when the user asks about the node, needs an invoice, or is mid-atomic-swap and the maker needs the node pubkey or a swapstring whitelisted."
4
- tools: rln_get_node_info, rln_whitelist_swap, rln_create_ln_invoice, rln_create_rgb_invoice
4
+ tools: rln_get_node_info, rln_get_balances, rln_list_channels, rln_open_channel, rln_close_channel, rln_connect_peer, rln_get_channel_id, rln_atomic_taker, rln_list_payments, rln_create_ln_invoice, rln_create_rgb_invoice
5
5
  triggers: node, nodeinfo, pubkey, peer, channels, whitelist, taker, swapstring, invoice, receive, rgb invoice, ln invoice
6
6
  metadata:
7
7
  author: kaleidoswap
@@ -52,7 +52,7 @@ Call this when:
52
52
  the LSPS skill answers what's available to BUY (`lsp_get_info`); the current
53
53
  remote-balance breakdown isn't exposed by this skill's tools.
54
54
 
55
- ### `rln_whitelist_swap` — { swapstring } — 🔒 confirm-gated
55
+ ### `rln_atomic_taker` — { swapstring } — 🔒 confirm-gated
56
56
  Tell the node "I accept this swap." Args: the `swapstring` returned by
57
57
  `kaleidoswap_atomic_init`. The node validates and stores it; **no funds move
58
58
  here**, but the user is committing to the swap so the engine pauses for
@@ -90,7 +90,7 @@ A user-driven swap on KaleidoSwap is a two-service flow. Keep them straight:
90
90
  | Quote | maker | `kaleidoswap_get_quote` |
91
91
  | Init | maker | `kaleidoswap_atomic_init` (returns swapstring + payment_hash) |
92
92
  | Pubkey | **node** | `rln_get_node_info` (read `pubkey`) |
93
- | Whitelist | **node** | `rln_whitelist_swap` (pass the swapstring) |
93
+ | Whitelist | **node** | `rln_atomic_taker` (pass the swapstring) |
94
94
  | Execute | maker | `kaleidoswap_atomic_execute` (needs swapstring + taker_pubkey + payment_hash) |
95
95
  | Status | maker | `kaleidoswap_atomic_status` |
96
96
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: wallet-assistant
3
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, or quote a swap (e.g. "how many sats is 10 USDT?"). Triggers when the user asks about their balance, wants to receive or send money, pay an invoice, pay a contact, or convert between BTC and supported assets.
4
- tools: get_balances, resolve_contact, send_payment, rln_pay_invoice, rln_create_ln_invoice, spark_create_invoice, kaleidoswap_get_quote
4
+ tools: get_balances, rln_get_balances, wdk_get_balances, spark_get_balance, rln_get_asset_balance, wdk_get_asset_balance, rln_list_assets, wdk_list_assets, rln_get_address, wdk_get_address, spark_get_address, resolve_contact, send_payment, rln_send_btc, wdk_send_btc, rln_send_asset, wdk_send_asset, spark_send_sats, rln_pay_invoice, wdk_pay_invoice, spark_pay_lightning_invoice, rln_create_ln_invoice, wdk_create_ln_invoice, spark_create_lightning_invoice, rln_create_rgb_invoice, wdk_create_rgb_invoice, rln_list_payments, wdk_list_payments, kaleidoswap_get_quote
5
5
  triggers: balance, pay, send, receive, address, invoice, transactions, contact, funds, money, sats
6
6
  ---
7
7