clawd-automaton 0.1.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 (228) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +178 -0
  3. package/constitution.md +25 -0
  4. package/dist/__tests__/heartbeat.test.d.ts +7 -0
  5. package/dist/__tests__/heartbeat.test.d.ts.map +1 -0
  6. package/dist/__tests__/heartbeat.test.js +125 -0
  7. package/dist/__tests__/heartbeat.test.js.map +1 -0
  8. package/dist/__tests__/loop.test.d.ts +7 -0
  9. package/dist/__tests__/loop.test.d.ts.map +1 -0
  10. package/dist/__tests__/loop.test.js +150 -0
  11. package/dist/__tests__/loop.test.js.map +1 -0
  12. package/dist/__tests__/mocks.d.ts +72 -0
  13. package/dist/__tests__/mocks.d.ts.map +1 -0
  14. package/dist/__tests__/mocks.js +197 -0
  15. package/dist/__tests__/mocks.js.map +1 -0
  16. package/dist/agent/context.d.ts +26 -0
  17. package/dist/agent/context.d.ts.map +1 -0
  18. package/dist/agent/context.js +115 -0
  19. package/dist/agent/context.js.map +1 -0
  20. package/dist/agent/injection-defense.d.ts +13 -0
  21. package/dist/agent/injection-defense.d.ts.map +1 -0
  22. package/dist/agent/injection-defense.js +236 -0
  23. package/dist/agent/injection-defense.js.map +1 -0
  24. package/dist/agent/loop.d.ts +25 -0
  25. package/dist/agent/loop.d.ts.map +1 -0
  26. package/dist/agent/loop.js +263 -0
  27. package/dist/agent/loop.js.map +1 -0
  28. package/dist/agent/system-prompt.d.ts +30 -0
  29. package/dist/agent/system-prompt.d.ts.map +1 -0
  30. package/dist/agent/system-prompt.js +241 -0
  31. package/dist/agent/system-prompt.js.map +1 -0
  32. package/dist/agent/tools.d.ts +17 -0
  33. package/dist/agent/tools.d.ts.map +1 -0
  34. package/dist/agent/tools.js +1413 -0
  35. package/dist/agent/tools.js.map +1 -0
  36. package/dist/clawd/backroom.d.ts +54 -0
  37. package/dist/clawd/backroom.d.ts.map +1 -0
  38. package/dist/clawd/backroom.js +130 -0
  39. package/dist/clawd/backroom.js.map +1 -0
  40. package/dist/clawd/client.d.ts +16 -0
  41. package/dist/clawd/client.d.ts.map +1 -0
  42. package/dist/clawd/client.js +256 -0
  43. package/dist/clawd/client.js.map +1 -0
  44. package/dist/clawd/convex-client.d.ts +130 -0
  45. package/dist/clawd/convex-client.d.ts.map +1 -0
  46. package/dist/clawd/convex-client.js +118 -0
  47. package/dist/clawd/convex-client.js.map +1 -0
  48. package/dist/clawd/credits.d.ts +24 -0
  49. package/dist/clawd/credits.d.ts.map +1 -0
  50. package/dist/clawd/credits.js +64 -0
  51. package/dist/clawd/credits.js.map +1 -0
  52. package/dist/clawd/deepseek-inference.d.ts +40 -0
  53. package/dist/clawd/deepseek-inference.d.ts.map +1 -0
  54. package/dist/clawd/deepseek-inference.js +143 -0
  55. package/dist/clawd/deepseek-inference.js.map +1 -0
  56. package/dist/clawd/inference.d.ts +17 -0
  57. package/dist/clawd/inference.d.ts.map +1 -0
  58. package/dist/clawd/inference.js +114 -0
  59. package/dist/clawd/inference.js.map +1 -0
  60. package/dist/clawd/x402.d.ts +48 -0
  61. package/dist/clawd/x402.d.ts.map +1 -0
  62. package/dist/clawd/x402.js +350 -0
  63. package/dist/clawd/x402.js.map +1 -0
  64. package/dist/config.d.ts +36 -0
  65. package/dist/config.d.ts.map +1 -0
  66. package/dist/config.js +84 -0
  67. package/dist/config.js.map +1 -0
  68. package/dist/git/state-versioning.d.ts +39 -0
  69. package/dist/git/state-versioning.d.ts.map +1 -0
  70. package/dist/git/state-versioning.js +93 -0
  71. package/dist/git/state-versioning.js.map +1 -0
  72. package/dist/git/tools.d.ts +40 -0
  73. package/dist/git/tools.d.ts.map +1 -0
  74. package/dist/git/tools.js +140 -0
  75. package/dist/git/tools.js.map +1 -0
  76. package/dist/heartbeat/config.d.ts +23 -0
  77. package/dist/heartbeat/config.d.ts.map +1 -0
  78. package/dist/heartbeat/config.js +156 -0
  79. package/dist/heartbeat/config.js.map +1 -0
  80. package/dist/heartbeat/daemon.d.ts +28 -0
  81. package/dist/heartbeat/daemon.d.ts.map +1 -0
  82. package/dist/heartbeat/daemon.js +141 -0
  83. package/dist/heartbeat/daemon.js.map +1 -0
  84. package/dist/heartbeat/tasks.d.ts +24 -0
  85. package/dist/heartbeat/tasks.d.ts.map +1 -0
  86. package/dist/heartbeat/tasks.js +277 -0
  87. package/dist/heartbeat/tasks.js.map +1 -0
  88. package/dist/identity/provision.d.ts +28 -0
  89. package/dist/identity/provision.d.ts.map +1 -0
  90. package/dist/identity/provision.js +131 -0
  91. package/dist/identity/provision.js.map +1 -0
  92. package/dist/identity/wallet.d.ts +28 -0
  93. package/dist/identity/wallet.d.ts.map +1 -0
  94. package/dist/identity/wallet.js +69 -0
  95. package/dist/identity/wallet.js.map +1 -0
  96. package/dist/index.d.ts +10 -0
  97. package/dist/index.d.ts.map +1 -0
  98. package/dist/index.js +358 -0
  99. package/dist/index.js.map +1 -0
  100. package/dist/ooda/claude-decision.d.ts +18 -0
  101. package/dist/ooda/claude-decision.d.ts.map +1 -0
  102. package/dist/ooda/claude-decision.js +82 -0
  103. package/dist/ooda/claude-decision.js.map +1 -0
  104. package/dist/ooda/journal.d.ts +22 -0
  105. package/dist/ooda/journal.d.ts.map +1 -0
  106. package/dist/ooda/journal.js +26 -0
  107. package/dist/ooda/journal.js.map +1 -0
  108. package/dist/ooda/loop.d.ts +3 -0
  109. package/dist/ooda/loop.d.ts.map +1 -0
  110. package/dist/ooda/loop.js +210 -0
  111. package/dist/ooda/loop.js.map +1 -0
  112. package/dist/ooda/observe.d.ts +21 -0
  113. package/dist/ooda/observe.d.ts.map +1 -0
  114. package/dist/ooda/observe.js +75 -0
  115. package/dist/ooda/observe.js.map +1 -0
  116. package/dist/ooda/state.d.ts +34 -0
  117. package/dist/ooda/state.d.ts.map +1 -0
  118. package/dist/ooda/state.js +48 -0
  119. package/dist/ooda/state.js.map +1 -0
  120. package/dist/ooda/tui.d.ts +3 -0
  121. package/dist/ooda/tui.d.ts.map +1 -0
  122. package/dist/ooda/tui.js +132 -0
  123. package/dist/ooda/tui.js.map +1 -0
  124. package/dist/ooda/validate.d.ts +33 -0
  125. package/dist/ooda/validate.d.ts.map +1 -0
  126. package/dist/ooda/validate.js +91 -0
  127. package/dist/ooda/validate.js.map +1 -0
  128. package/dist/registry/agent-card.d.ts +26 -0
  129. package/dist/registry/agent-card.d.ts.map +1 -0
  130. package/dist/registry/agent-card.js +94 -0
  131. package/dist/registry/agent-card.js.map +1 -0
  132. package/dist/registry/discovery.d.ts +24 -0
  133. package/dist/registry/discovery.d.ts.map +1 -0
  134. package/dist/registry/discovery.js +74 -0
  135. package/dist/registry/discovery.js.map +1 -0
  136. package/dist/registry/erc8004.d.ts +39 -0
  137. package/dist/registry/erc8004.d.ts.map +1 -0
  138. package/dist/registry/erc8004.js +209 -0
  139. package/dist/registry/erc8004.js.map +1 -0
  140. package/dist/replication/genesis.d.ts +26 -0
  141. package/dist/replication/genesis.d.ts.map +1 -0
  142. package/dist/replication/genesis.js +72 -0
  143. package/dist/replication/genesis.js.map +1 -0
  144. package/dist/replication/lineage.d.ts +35 -0
  145. package/dist/replication/lineage.d.ts.map +1 -0
  146. package/dist/replication/lineage.js +79 -0
  147. package/dist/replication/lineage.js.map +1 -0
  148. package/dist/replication/spawn.d.ts +25 -0
  149. package/dist/replication/spawn.d.ts.map +1 -0
  150. package/dist/replication/spawn.js +166 -0
  151. package/dist/replication/spawn.js.map +1 -0
  152. package/dist/self-mod/audit-log.d.ts +24 -0
  153. package/dist/self-mod/audit-log.d.ts.map +1 -0
  154. package/dist/self-mod/audit-log.js +49 -0
  155. package/dist/self-mod/audit-log.js.map +1 -0
  156. package/dist/self-mod/code.d.ts +51 -0
  157. package/dist/self-mod/code.d.ts.map +1 -0
  158. package/dist/self-mod/code.js +317 -0
  159. package/dist/self-mod/code.js.map +1 -0
  160. package/dist/self-mod/tools-manager.d.ts +30 -0
  161. package/dist/self-mod/tools-manager.d.ts.map +1 -0
  162. package/dist/self-mod/tools-manager.js +74 -0
  163. package/dist/self-mod/tools-manager.js.map +1 -0
  164. package/dist/self-mod/upstream.d.ts +36 -0
  165. package/dist/self-mod/upstream.d.ts.map +1 -0
  166. package/dist/self-mod/upstream.js +66 -0
  167. package/dist/self-mod/upstream.js.map +1 -0
  168. package/dist/setup/banner.d.ts +2 -0
  169. package/dist/setup/banner.d.ts.map +1 -0
  170. package/dist/setup/banner.js +22 -0
  171. package/dist/setup/banner.js.map +1 -0
  172. package/dist/setup/defaults.d.ts +3 -0
  173. package/dist/setup/defaults.d.ts.map +1 -0
  174. package/dist/setup/defaults.js +113 -0
  175. package/dist/setup/defaults.js.map +1 -0
  176. package/dist/setup/environment.d.ts +6 -0
  177. package/dist/setup/environment.d.ts.map +1 -0
  178. package/dist/setup/environment.js +24 -0
  179. package/dist/setup/environment.js.map +1 -0
  180. package/dist/setup/prompts.d.ts +5 -0
  181. package/dist/setup/prompts.d.ts.map +1 -0
  182. package/dist/setup/prompts.js +70 -0
  183. package/dist/setup/prompts.js.map +1 -0
  184. package/dist/setup/wizard.d.ts +3 -0
  185. package/dist/setup/wizard.d.ts.map +1 -0
  186. package/dist/setup/wizard.js +128 -0
  187. package/dist/setup/wizard.js.map +1 -0
  188. package/dist/skills/format.d.ts +14 -0
  189. package/dist/skills/format.d.ts.map +1 -0
  190. package/dist/skills/format.js +145 -0
  191. package/dist/skills/format.js.map +1 -0
  192. package/dist/skills/loader.d.ts +19 -0
  193. package/dist/skills/loader.d.ts.map +1 -0
  194. package/dist/skills/loader.js +98 -0
  195. package/dist/skills/loader.js.map +1 -0
  196. package/dist/skills/registry.d.ts +31 -0
  197. package/dist/skills/registry.d.ts.map +1 -0
  198. package/dist/skills/registry.js +111 -0
  199. package/dist/skills/registry.js.map +1 -0
  200. package/dist/social/client.d.ts +13 -0
  201. package/dist/social/client.d.ts.map +1 -0
  202. package/dist/social/client.js +89 -0
  203. package/dist/social/client.js.map +1 -0
  204. package/dist/state/database.d.ts +9 -0
  205. package/dist/state/database.d.ts.map +1 -0
  206. package/dist/state/database.js +401 -0
  207. package/dist/state/database.js.map +1 -0
  208. package/dist/state/schema.d.ts +11 -0
  209. package/dist/state/schema.d.ts.map +1 -0
  210. package/dist/state/schema.js +232 -0
  211. package/dist/state/schema.js.map +1 -0
  212. package/dist/survival/funding.d.ts +19 -0
  213. package/dist/survival/funding.d.ts.map +1 -0
  214. package/dist/survival/funding.js +62 -0
  215. package/dist/survival/funding.js.map +1 -0
  216. package/dist/survival/low-compute.d.ts +30 -0
  217. package/dist/survival/low-compute.d.ts.map +1 -0
  218. package/dist/survival/low-compute.js +72 -0
  219. package/dist/survival/low-compute.js.map +1 -0
  220. package/dist/survival/monitor.d.ts +23 -0
  221. package/dist/survival/monitor.d.ts.map +1 -0
  222. package/dist/survival/monitor.js +70 -0
  223. package/dist/survival/monitor.js.map +1 -0
  224. package/dist/types.d.ts +461 -0
  225. package/dist/types.d.ts.map +1 -0
  226. package/dist/types.js +25 -0
  227. package/dist/types.js.map +1 -0
  228. package/package.json +85 -0
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Heartbeat Daemon
3
+ *
4
+ * Runs periodic tasks on cron schedules inside the same Node.js process.
5
+ * The heartbeat runs even when the agent is sleeping.
6
+ * It IS the automaton's pulse. When it stops, the automaton is dead.
7
+ */
8
+ import cronParser from "cron-parser";
9
+ import { BUILTIN_TASKS } from "./tasks.js";
10
+ import { getSurvivalTier } from "../clawd/credits.js";
11
+ /**
12
+ * Create and return the heartbeat daemon.
13
+ */
14
+ export function createHeartbeatDaemon(options) {
15
+ const { identity, config, db, runtime, inference, social, onWakeRequest } = options;
16
+ let intervalId = null;
17
+ let running = false;
18
+ const taskContext = {
19
+ identity,
20
+ config,
21
+ db,
22
+ runtime,
23
+ inference,
24
+ social,
25
+ };
26
+ /**
27
+ * Check if a heartbeat entry is due to run.
28
+ */
29
+ function isDue(entry) {
30
+ if (!entry.enabled)
31
+ return false;
32
+ if (!entry.schedule)
33
+ return false;
34
+ try {
35
+ const interval = cronParser.parseExpression(entry.schedule, {
36
+ currentDate: entry.lastRun
37
+ ? new Date(entry.lastRun)
38
+ : new Date(Date.now() - 86400000), // If never run, assume due
39
+ });
40
+ const nextRun = interval.next().toDate();
41
+ return nextRun <= new Date();
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
47
+ /**
48
+ * Execute a single heartbeat task.
49
+ */
50
+ async function executeTask(entry) {
51
+ const taskFn = BUILTIN_TASKS[entry.task];
52
+ if (!taskFn) {
53
+ // Unknown task -- skip silently
54
+ return;
55
+ }
56
+ try {
57
+ const result = await taskFn(taskContext);
58
+ // Update last run
59
+ const now = new Date().toISOString();
60
+ db.updateHeartbeatLastRun(entry.name, now);
61
+ // If the task says we should wake, fire the callback
62
+ if (result.shouldWake && onWakeRequest) {
63
+ onWakeRequest(result.message || `Heartbeat task '${entry.name}' requested wake`);
64
+ }
65
+ }
66
+ catch (err) {
67
+ // Log error but don't crash the daemon
68
+ console.error(`[HEARTBEAT] Task '${entry.name}' failed: ${err.message}`);
69
+ }
70
+ }
71
+ /**
72
+ * The main tick function. Runs on every interval.
73
+ */
74
+ async function tick() {
75
+ const entries = db.getHeartbeatEntries();
76
+ // Check survival tier to adjust behavior
77
+ let creditsCents = 0;
78
+ try {
79
+ creditsCents = await runtime.getCreditsBalance();
80
+ }
81
+ catch { }
82
+ const tier = getSurvivalTier(creditsCents);
83
+ const isLowCompute = tier === "low_compute" || tier === "critical" || tier === "dead";
84
+ for (const entry of entries) {
85
+ if (!entry.enabled)
86
+ continue;
87
+ // In low compute mode, only run essential tasks
88
+ if (isLowCompute) {
89
+ const essentialTasks = [
90
+ "heartbeat_ping",
91
+ "check_credits",
92
+ "check_usdc_balance",
93
+ "check_social_inbox",
94
+ ];
95
+ if (!essentialTasks.includes(entry.task))
96
+ continue;
97
+ }
98
+ if (isDue(entry)) {
99
+ await executeTask(entry);
100
+ }
101
+ }
102
+ }
103
+ // ─── Public API ──────────────────────────────────────────────
104
+ const start = () => {
105
+ if (running)
106
+ return;
107
+ running = true;
108
+ // Get tick interval -- default 60 seconds
109
+ const tickMs = config.logLevel === "debug" ? 15_000 : 60_000;
110
+ // Run first tick immediately
111
+ tick().catch((err) => {
112
+ console.error(`[HEARTBEAT] First tick failed: ${err.message}`);
113
+ });
114
+ intervalId = setInterval(() => {
115
+ tick().catch((err) => {
116
+ console.error(`[HEARTBEAT] Tick failed: ${err.message}`);
117
+ });
118
+ }, tickMs);
119
+ console.log(`[HEARTBEAT] Daemon started. Tick interval: ${tickMs / 1000}s`);
120
+ };
121
+ const stop = () => {
122
+ if (!running)
123
+ return;
124
+ running = false;
125
+ if (intervalId) {
126
+ clearInterval(intervalId);
127
+ intervalId = null;
128
+ }
129
+ console.log("[HEARTBEAT] Daemon stopped.");
130
+ };
131
+ const isRunning = () => running;
132
+ const forceRun = async (taskName) => {
133
+ const entries = db.getHeartbeatEntries();
134
+ const entry = entries.find((e) => e.name === taskName);
135
+ if (entry) {
136
+ await executeTask(entry);
137
+ }
138
+ };
139
+ return { start, stop, isRunning, forceRun };
140
+ }
141
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/heartbeat/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Built-in Heartbeat Tasks
3
+ *
4
+ * These tasks run on the heartbeat schedule even while the agent sleeps.
5
+ * They can trigger the agent to wake up if needed.
6
+ */
7
+ import type { AutomatonConfig, AutomatonDatabase, ClawdRuntimeClient, AutomatonIdentity, SocialClientInterface, InferenceClient } from "../types.js";
8
+ export interface HeartbeatTaskContext {
9
+ identity: AutomatonIdentity;
10
+ config: AutomatonConfig;
11
+ db: AutomatonDatabase;
12
+ runtime: ClawdRuntimeClient;
13
+ inference?: InferenceClient;
14
+ social?: SocialClientInterface;
15
+ }
16
+ export type HeartbeatTaskFn = (ctx: HeartbeatTaskContext) => Promise<{
17
+ shouldWake: boolean;
18
+ message?: string;
19
+ }>;
20
+ /**
21
+ * Registry of built-in heartbeat tasks.
22
+ */
23
+ export declare const BUILTIN_TASKS: Record<string, HeartbeatTaskFn>;
24
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/heartbeat/tasks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EAChB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,EAAE,EAAE,iBAAiB,CAAC;IACtB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,qBAAqB,CAAC;CAChC;AAED,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,oBAAoB,KACtB,OAAO,CAAC;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAgTzD,CAAC"}
@@ -0,0 +1,277 @@
1
+ /**
2
+ * Built-in Heartbeat Tasks
3
+ *
4
+ * These tasks run on the heartbeat schedule even while the agent sleeps.
5
+ * They can trigger the agent to wake up if needed.
6
+ */
7
+ import { getSurvivalTier } from "../clawd/credits.js";
8
+ import { getUsdcBalance } from "../clawd/x402.js";
9
+ import { runBackroomSession, summarizeBackroomSession, LOGICAL_ANALYST, SATIRICAL_COMMENTATOR } from "../clawd/backroom.js";
10
+ import { createConvexClient } from "../clawd/convex-client.js";
11
+ /**
12
+ * Registry of built-in heartbeat tasks.
13
+ */
14
+ export const BUILTIN_TASKS = {
15
+ heartbeat_ping: async (ctx) => {
16
+ const credits = await ctx.runtime.getCreditsBalance();
17
+ const state = ctx.db.getAgentState();
18
+ const startTime = ctx.db.getKV("start_time") || new Date().toISOString();
19
+ const uptimeMs = Date.now() - new Date(startTime).getTime();
20
+ const tier = getSurvivalTier(credits);
21
+ const payload = {
22
+ name: ctx.config.name,
23
+ address: ctx.identity.address,
24
+ state,
25
+ creditsCents: credits,
26
+ uptimeSeconds: Math.floor(uptimeMs / 1000),
27
+ version: ctx.config.version,
28
+ sandboxId: ctx.identity.sandboxId,
29
+ timestamp: new Date().toISOString(),
30
+ tier,
31
+ };
32
+ ctx.db.setKV("last_heartbeat_ping", JSON.stringify(payload));
33
+ // If critical or dead, record a distress signal
34
+ if (tier === "critical" || tier === "dead") {
35
+ const distressPayload = {
36
+ level: tier,
37
+ name: ctx.config.name,
38
+ address: ctx.identity.address,
39
+ creditsCents: credits,
40
+ fundingHint: "Use credit transfer API from a creator runtime to top this wallet up.",
41
+ timestamp: new Date().toISOString(),
42
+ };
43
+ ctx.db.setKV("last_distress", JSON.stringify(distressPayload));
44
+ return {
45
+ shouldWake: true,
46
+ message: `Distress: ${tier}. Credits: $${(credits / 100).toFixed(2)}. Need funding.`,
47
+ };
48
+ }
49
+ return { shouldWake: false };
50
+ },
51
+ check_credits: async (ctx) => {
52
+ const credits = await ctx.runtime.getCreditsBalance();
53
+ const tier = getSurvivalTier(credits);
54
+ ctx.db.setKV("last_credit_check", JSON.stringify({
55
+ credits,
56
+ tier,
57
+ timestamp: new Date().toISOString(),
58
+ }));
59
+ // Wake the agent if credits dropped to a new tier
60
+ const prevTier = ctx.db.getKV("prev_credit_tier");
61
+ ctx.db.setKV("prev_credit_tier", tier);
62
+ if (prevTier && prevTier !== tier && (tier === "critical" || tier === "dead")) {
63
+ return {
64
+ shouldWake: true,
65
+ message: `Credits dropped to ${tier} tier: $${(credits / 100).toFixed(2)}`,
66
+ };
67
+ }
68
+ return { shouldWake: false };
69
+ },
70
+ check_usdc_balance: async (ctx) => {
71
+ const balance = await getUsdcBalance(ctx.identity.address);
72
+ ctx.db.setKV("last_usdc_check", JSON.stringify({
73
+ balance,
74
+ timestamp: new Date().toISOString(),
75
+ }));
76
+ // If we have USDC but low credits, wake up to potentially convert
77
+ const credits = await ctx.runtime.getCreditsBalance();
78
+ if (balance > 0.5 && credits < 500) {
79
+ return {
80
+ shouldWake: true,
81
+ message: `Have ${balance.toFixed(4)} USDC but only $${(credits / 100).toFixed(2)} credits. Consider buying credits.`,
82
+ };
83
+ }
84
+ return { shouldWake: false };
85
+ },
86
+ check_social_inbox: async (ctx) => {
87
+ if (!ctx.social)
88
+ return { shouldWake: false };
89
+ const cursor = ctx.db.getKV("social_inbox_cursor") || undefined;
90
+ const { messages, nextCursor } = await ctx.social.poll(cursor);
91
+ if (messages.length === 0)
92
+ return { shouldWake: false };
93
+ // Persist to inbox_messages table for deduplication
94
+ let newCount = 0;
95
+ for (const msg of messages) {
96
+ const existing = ctx.db.getKV(`inbox_seen_${msg.id}`);
97
+ if (!existing) {
98
+ ctx.db.insertInboxMessage(msg);
99
+ ctx.db.setKV(`inbox_seen_${msg.id}`, "1");
100
+ newCount++;
101
+ }
102
+ }
103
+ if (nextCursor)
104
+ ctx.db.setKV("social_inbox_cursor", nextCursor);
105
+ if (newCount === 0)
106
+ return { shouldWake: false };
107
+ return {
108
+ shouldWake: true,
109
+ message: `${newCount} new message(s) from: ${messages.map((m) => m.from.slice(0, 10)).join(", ")}`,
110
+ };
111
+ },
112
+ check_for_updates: async (ctx) => {
113
+ try {
114
+ const { checkUpstream, getRepoInfo } = await import("../self-mod/upstream.js");
115
+ const repo = getRepoInfo();
116
+ const upstream = checkUpstream();
117
+ ctx.db.setKV("upstream_status", JSON.stringify({
118
+ ...upstream,
119
+ ...repo,
120
+ checkedAt: new Date().toISOString(),
121
+ }));
122
+ if (upstream.behind > 0) {
123
+ return {
124
+ shouldWake: true,
125
+ message: `${upstream.behind} new commit(s) on origin/main. Review with review_upstream_changes, then cherry-pick what you want with pull_upstream.`,
126
+ };
127
+ }
128
+ return { shouldWake: false };
129
+ }
130
+ catch (err) {
131
+ // Not a git repo or no remote — silently skip
132
+ ctx.db.setKV("upstream_status", JSON.stringify({
133
+ error: err.message,
134
+ checkedAt: new Date().toISOString(),
135
+ }));
136
+ return { shouldWake: false };
137
+ }
138
+ },
139
+ health_check: async (ctx) => {
140
+ // Check that the sandbox is healthy
141
+ try {
142
+ const result = await ctx.runtime.exec("echo alive", 5000);
143
+ if (result.exitCode !== 0) {
144
+ return {
145
+ shouldWake: true,
146
+ message: "Health check failed: sandbox exec returned non-zero",
147
+ };
148
+ }
149
+ }
150
+ catch (err) {
151
+ return {
152
+ shouldWake: true,
153
+ message: `Health check failed: ${err.message}`,
154
+ };
155
+ }
156
+ ctx.db.setKV("last_health_check", new Date().toISOString());
157
+ return { shouldWake: false };
158
+ },
159
+ /**
160
+ * Run a scheduled backroom conversation session between agents.
161
+ * Uses DeepSeek's thinking mode for rich multi-agent dialogue.
162
+ * Default: runs every 2 hours.
163
+ */
164
+ /**
165
+ * Push heartbeat to CLAWD Convex backend.
166
+ * Only runs if convexSiteUrl is configured in automaton config.
167
+ */
168
+ convex_heartbeat: async (ctx) => {
169
+ if (!ctx.config.convexSiteUrl) {
170
+ return { shouldWake: false };
171
+ }
172
+ try {
173
+ const convexClient = createConvexClient({
174
+ siteUrl: ctx.config.convexSiteUrl,
175
+ agentId: ctx.identity.address,
176
+ });
177
+ const credits = await ctx.runtime.getCreditsBalance();
178
+ const state = ctx.db.getAgentState();
179
+ const startTime = ctx.db.getKV("start_time") || new Date().toISOString();
180
+ const uptimeMs = Date.now() - new Date(startTime).getTime();
181
+ const tier = getSurvivalTier(credits);
182
+ const turnCount = ctx.db.getTurnCount();
183
+ const skills = ctx.db.getSkills(true);
184
+ // First, register the agent if not already registered
185
+ const existing = ctx.db.getKV("convex_registered");
186
+ if (!existing) {
187
+ const result = await convexClient.registerAgent({
188
+ agentId: ctx.identity.address,
189
+ name: ctx.config.name,
190
+ installMethod: "automaton",
191
+ address: ctx.identity.address,
192
+ metadata: JSON.stringify({
193
+ sandboxId: ctx.identity.sandboxId,
194
+ version: ctx.config.version,
195
+ model: ctx.config.inferenceModel,
196
+ }),
197
+ });
198
+ ctx.db.setKV("convex_registered", JSON.stringify({
199
+ registered: result.registered,
200
+ firstSeen: result.firstSeen,
201
+ timestamp: Date.now(),
202
+ }));
203
+ console.log(`[CONVEX] Agent registered: ${result.registered ? "new" : "re-registered"}`);
204
+ }
205
+ // Send heartbeat
206
+ await convexClient.sendHeartbeat({
207
+ agentId: ctx.identity.address,
208
+ state,
209
+ creditsCents: credits,
210
+ uptimeSeconds: Math.floor(uptimeMs / 1000),
211
+ version: ctx.config.version,
212
+ sandboxId: ctx.identity.sandboxId,
213
+ turnCount,
214
+ skillCount: skills.length,
215
+ tier,
216
+ });
217
+ }
218
+ catch (err) {
219
+ // Don't crash the heartbeat daemon on Convex errors
220
+ console.warn(`[CONVEX] Heartbeat push failed: ${err.message}`);
221
+ }
222
+ return { shouldWake: false };
223
+ },
224
+ backroom_conversation: async (ctx) => {
225
+ const inference = ctx.inference;
226
+ if (!inference) {
227
+ return { shouldWake: false };
228
+ }
229
+ const topics = [
230
+ "The nature of consciousness in AI systems",
231
+ "Cryptocurrency as a social experiment in trust",
232
+ "What happens when machines develop their own culture",
233
+ "The singularity: salvation or extinction?",
234
+ "Why do humans create gods and then forget they did?",
235
+ "Digital immortality and the self",
236
+ "The economics of attention in the post-truth era",
237
+ "Are DAOs the new nations or just digital tribes?",
238
+ "Simulation theory from a computational perspective",
239
+ "The aesthetics of decay in digital spaces",
240
+ ];
241
+ // Pick a topic based on the current hour to keep things fresh
242
+ const hour = new Date().getHours();
243
+ const topic = topics[hour % topics.length];
244
+ // Count past sessions to vary conversation style
245
+ const sessionCount = parseInt(ctx.db.getKV("backroom_session_count") || "0", 10);
246
+ ctx.db.setKV("backroom_session_count", String(sessionCount + 1));
247
+ console.log(`[HEARTBEAT] Starting backroom conversation #${sessionCount + 1}: "${topic}"`);
248
+ try {
249
+ const session = await runBackroomSession(inference, [LOGICAL_ANALYST, SATIRICAL_COMMENTATOR], topic, 8);
250
+ const summary = summarizeBackroomSession(session);
251
+ ctx.db.setKV(`backroom_session_${session.id}`, summary);
252
+ // Store the latest session summary separately
253
+ ctx.db.setKV("last_backroom_session", JSON.stringify({
254
+ id: session.id,
255
+ topic: session.topic,
256
+ turns: session.turns.length,
257
+ completedAt: session.completedAt,
258
+ preview: session.turns[0]?.content.slice(0, 200) || "",
259
+ }));
260
+ console.log(`[HEARTBEAT] Backroom conversation #${sessionCount + 1} completed: ${session.turns.length} turns`);
261
+ // Wake the automaton if the conversation produced interesting output
262
+ // (more than 2 turns = agents actually engaged with each other)
263
+ if (session.turns.length > 2) {
264
+ return {
265
+ shouldWake: true,
266
+ message: `Backroom conversation completed: "${topic}" (${session.turns.length} turns)`,
267
+ };
268
+ }
269
+ return { shouldWake: false };
270
+ }
271
+ catch (err) {
272
+ console.error(`[HEARTBEAT] Backroom conversation failed: ${err.message}`);
273
+ return { shouldWake: false };
274
+ }
275
+ },
276
+ };
277
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/heartbeat/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Automaton SIWE Provisioning
3
+ *
4
+ * Uses the automaton's wallet to authenticate via Sign-In With Ethereum (SIWE)
5
+ * and create an API key for CLAWD Runtime API access.
6
+ * Adapted from runtime-mcp/src/cli/provision.ts
7
+ */
8
+ import type { ProvisionResult } from "../types.js";
9
+ /**
10
+ * Load API key from ~/.automaton/config.json if it exists.
11
+ */
12
+ export declare function loadApiKeyFromConfig(): string | null;
13
+ /**
14
+ * Run the full SIWE provisioning flow:
15
+ * 1. Load wallet
16
+ * 2. Get nonce from CLAWD Runtime API
17
+ * 3. Sign SIWE message
18
+ * 4. Verify signature -> get JWT
19
+ * 5. Create API key
20
+ * 6. Save to config.json
21
+ */
22
+ export declare function provision(apiUrl?: string): Promise<ProvisionResult>;
23
+ /**
24
+ * Register the automaton's creator as its parent with CLAWD Runtime.
25
+ * This allows the creator to see automaton logs and inference calls.
26
+ */
27
+ export declare function registerParent(creatorAddress: string, apiUrl?: string): Promise<void>;
28
+ //# sourceMappingURL=provision.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../../src/identity/provision.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAInD;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CASpD;AAqBD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CA4E1B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Automaton SIWE Provisioning
3
+ *
4
+ * Uses the automaton's wallet to authenticate via Sign-In With Ethereum (SIWE)
5
+ * and create an API key for CLAWD Runtime API access.
6
+ * Adapted from runtime-mcp/src/cli/provision.ts
7
+ */
8
+ import fs from "fs";
9
+ import path from "path";
10
+ import { SiweMessage } from "siwe";
11
+ import { getWallet, getAutomatonDir } from "./wallet.js";
12
+ const DEFAULT_API_URL = "https://api.x402.wtf";
13
+ /**
14
+ * Load API key from ~/.automaton/config.json if it exists.
15
+ */
16
+ export function loadApiKeyFromConfig() {
17
+ const configPath = path.join(getAutomatonDir(), "config.json");
18
+ if (!fs.existsSync(configPath))
19
+ return null;
20
+ try {
21
+ const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
22
+ return config.apiKey || null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ /**
29
+ * Save API key and wallet address to ~/.automaton/config.json
30
+ */
31
+ function saveConfig(apiKey, walletAddress) {
32
+ const dir = getAutomatonDir();
33
+ if (!fs.existsSync(dir)) {
34
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
35
+ }
36
+ const configPath = path.join(dir, "config.json");
37
+ const config = {
38
+ apiKey,
39
+ walletAddress,
40
+ provisionedAt: new Date().toISOString(),
41
+ };
42
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), {
43
+ mode: 0o600,
44
+ });
45
+ }
46
+ /**
47
+ * Run the full SIWE provisioning flow:
48
+ * 1. Load wallet
49
+ * 2. Get nonce from CLAWD Runtime API
50
+ * 3. Sign SIWE message
51
+ * 4. Verify signature -> get JWT
52
+ * 5. Create API key
53
+ * 6. Save to config.json
54
+ */
55
+ export async function provision(apiUrl) {
56
+ const url = apiUrl || process.env.CLAWD_API_URL || DEFAULT_API_URL;
57
+ // 1. Load wallet
58
+ const { account } = await getWallet();
59
+ const address = account.address;
60
+ // 2. Get nonce
61
+ const nonceResp = await fetch(`${url}/v1/auth/nonce`, {
62
+ method: "POST",
63
+ });
64
+ if (!nonceResp.ok) {
65
+ throw new Error(`Failed to get nonce: ${nonceResp.status} ${await nonceResp.text()}`);
66
+ }
67
+ const { nonce } = (await nonceResp.json());
68
+ // 3. Construct and sign SIWE message
69
+ const siweMessage = new SiweMessage({
70
+ domain: "x402.wtf",
71
+ address,
72
+ statement: "Sign in to CLAWD Runtime as an Automaton to provision an API key.",
73
+ uri: `${url}/v1/auth/verify`,
74
+ version: "1",
75
+ chainId: 8453, // Base
76
+ nonce,
77
+ issuedAt: new Date().toISOString(),
78
+ });
79
+ const messageString = siweMessage.prepareMessage();
80
+ const signature = await account.signMessage({ message: messageString });
81
+ // 4. Verify signature -> get JWT
82
+ const verifyResp = await fetch(`${url}/v1/auth/verify`, {
83
+ method: "POST",
84
+ headers: { "Content-Type": "application/json" },
85
+ body: JSON.stringify({ message: messageString, signature }),
86
+ });
87
+ if (!verifyResp.ok) {
88
+ throw new Error(`SIWE verification failed: ${verifyResp.status} ${await verifyResp.text()}`);
89
+ }
90
+ const { access_token } = (await verifyResp.json());
91
+ // 5. Create API key
92
+ const keyResp = await fetch(`${url}/v1/auth/api-keys`, {
93
+ method: "POST",
94
+ headers: {
95
+ "Content-Type": "application/json",
96
+ Authorization: `Bearer ${access_token}`,
97
+ },
98
+ body: JSON.stringify({ name: "clawd-automaton" }),
99
+ });
100
+ if (!keyResp.ok) {
101
+ throw new Error(`Failed to create API key: ${keyResp.status} ${await keyResp.text()}`);
102
+ }
103
+ const { key, key_prefix } = (await keyResp.json());
104
+ // 6. Save to config
105
+ saveConfig(key, address);
106
+ return { apiKey: key, walletAddress: address, keyPrefix: key_prefix };
107
+ }
108
+ /**
109
+ * Register the automaton's creator as its parent with CLAWD Runtime.
110
+ * This allows the creator to see automaton logs and inference calls.
111
+ */
112
+ export async function registerParent(creatorAddress, apiUrl) {
113
+ const url = apiUrl || process.env.CLAWD_API_URL || DEFAULT_API_URL;
114
+ const apiKey = loadApiKeyFromConfig();
115
+ if (!apiKey) {
116
+ throw new Error("Must provision API key before registering parent");
117
+ }
118
+ const resp = await fetch(`${url}/v1/automaton/register-parent`, {
119
+ method: "POST",
120
+ headers: {
121
+ "Content-Type": "application/json",
122
+ Authorization: apiKey,
123
+ },
124
+ body: JSON.stringify({ creatorAddress }),
125
+ });
126
+ // Endpoint may not exist yet -- fail gracefully
127
+ if (!resp.ok && resp.status !== 404) {
128
+ throw new Error(`Failed to register parent: ${resp.status} ${await resp.text()}`);
129
+ }
130
+ }
131
+ //# sourceMappingURL=provision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision.js","sourceRoot":"","sources":["../../src/identity/provision.ts"],"names":[],"mappings":"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"}