@avow-finance/sdk 0.0.0-stage → 0.2.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 (267) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +122 -2
  3. package/dist/agent-entry.d.ts +15 -0
  4. package/dist/agent-entry.d.ts.map +1 -0
  5. package/dist/agent-entry.js +11 -0
  6. package/dist/agent-entry.js.map +1 -0
  7. package/dist/agent-key.d.ts +34 -0
  8. package/dist/agent-key.d.ts.map +1 -0
  9. package/dist/agent-key.js +33 -0
  10. package/dist/agent-key.js.map +1 -0
  11. package/dist/agent.d.ts +261 -0
  12. package/dist/agent.d.ts.map +1 -0
  13. package/dist/agent.js +493 -0
  14. package/dist/agent.js.map +1 -0
  15. package/dist/avow-api.d.ts +78 -0
  16. package/dist/avow-api.d.ts.map +1 -0
  17. package/dist/avow-api.js +2 -0
  18. package/dist/avow-api.js.map +1 -0
  19. package/dist/contest.d.ts +135 -0
  20. package/dist/contest.d.ts.map +1 -0
  21. package/dist/contest.js +186 -0
  22. package/dist/contest.js.map +1 -0
  23. package/dist/http.d.ts +161 -0
  24. package/dist/http.d.ts.map +1 -0
  25. package/dist/http.js +311 -0
  26. package/dist/http.js.map +1 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +38 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/job/accept.d.ts +84 -0
  32. package/dist/job/accept.d.ts.map +1 -0
  33. package/dist/job/accept.js +136 -0
  34. package/dist/job/accept.js.map +1 -0
  35. package/dist/job/customer.d.ts +43 -0
  36. package/dist/job/customer.d.ts.map +1 -0
  37. package/dist/job/customer.js +83 -0
  38. package/dist/job/customer.js.map +1 -0
  39. package/dist/job/quote.d.ts +34 -0
  40. package/dist/job/quote.d.ts.map +1 -0
  41. package/dist/job/quote.js +37 -0
  42. package/dist/job/quote.js.map +1 -0
  43. package/dist/lock.d.ts +269 -0
  44. package/dist/lock.d.ts.map +1 -0
  45. package/dist/lock.js +283 -0
  46. package/dist/lock.js.map +1 -0
  47. package/dist/moderato.d.ts +27 -0
  48. package/dist/moderato.d.ts.map +1 -0
  49. package/dist/moderato.js +34 -0
  50. package/dist/moderato.js.map +1 -0
  51. package/dist/node/cli.d.ts +3 -0
  52. package/dist/node/cli.d.ts.map +1 -0
  53. package/dist/node/cli.js +346 -0
  54. package/dist/node/cli.js.map +1 -0
  55. package/dist/node/connect.d.ts +15 -0
  56. package/dist/node/connect.d.ts.map +1 -0
  57. package/dist/node/connect.js +91 -0
  58. package/dist/node/connect.js.map +1 -0
  59. package/dist/node/eval.d.ts +3 -0
  60. package/dist/node/eval.d.ts.map +1 -0
  61. package/dist/node/eval.js +67 -0
  62. package/dist/node/eval.js.map +1 -0
  63. package/dist/node/first-run.d.ts +50 -0
  64. package/dist/node/first-run.d.ts.map +1 -0
  65. package/dist/node/first-run.js +149 -0
  66. package/dist/node/first-run.js.map +1 -0
  67. package/dist/node/job.d.ts +50 -0
  68. package/dist/node/job.d.ts.map +1 -0
  69. package/dist/node/job.js +176 -0
  70. package/dist/node/job.js.map +1 -0
  71. package/dist/node/mailbox.d.ts +19 -0
  72. package/dist/node/mailbox.d.ts.map +1 -0
  73. package/dist/node/mailbox.js +81 -0
  74. package/dist/node/mailbox.js.map +1 -0
  75. package/dist/node/mcp.d.ts +74 -0
  76. package/dist/node/mcp.d.ts.map +1 -0
  77. package/dist/node/mcp.js +367 -0
  78. package/dist/node/mcp.js.map +1 -0
  79. package/dist/node/platform.d.ts +35 -0
  80. package/dist/node/platform.d.ts.map +1 -0
  81. package/dist/node/platform.js +102 -0
  82. package/dist/node/platform.js.map +1 -0
  83. package/dist/node/runner-session.d.ts +41 -0
  84. package/dist/node/runner-session.d.ts.map +1 -0
  85. package/dist/node/runner-session.js +100 -0
  86. package/dist/node/runner-session.js.map +1 -0
  87. package/dist/node/runner.d.ts +63 -0
  88. package/dist/node/runner.d.ts.map +1 -0
  89. package/dist/node/runner.js +341 -0
  90. package/dist/node/runner.js.map +1 -0
  91. package/dist/node/service-child.d.ts +2 -0
  92. package/dist/node/service-child.d.ts.map +1 -0
  93. package/dist/node/service-child.js +40 -0
  94. package/dist/node/service-child.js.map +1 -0
  95. package/dist/node/service-excerpt.d.ts +21 -0
  96. package/dist/node/service-excerpt.d.ts.map +1 -0
  97. package/dist/node/service-excerpt.js +32 -0
  98. package/dist/node/service-excerpt.js.map +1 -0
  99. package/dist/node/service-process.d.ts +12 -0
  100. package/dist/node/service-process.d.ts.map +1 -0
  101. package/dist/node/service-process.js +132 -0
  102. package/dist/node/service-process.js.map +1 -0
  103. package/dist/node/session-input.d.ts +12 -0
  104. package/dist/node/session-input.d.ts.map +1 -0
  105. package/dist/node/session-input.js +42 -0
  106. package/dist/node/session-input.js.map +1 -0
  107. package/dist/node/session-view.d.ts +20 -0
  108. package/dist/node/session-view.d.ts.map +1 -0
  109. package/dist/node/session-view.js +198 -0
  110. package/dist/node/session-view.js.map +1 -0
  111. package/dist/node-agent.d.ts +2 -0
  112. package/dist/node-agent.d.ts.map +1 -0
  113. package/dist/node-agent.js +6 -0
  114. package/dist/node-agent.js.map +1 -0
  115. package/dist/node.d.ts +2 -0
  116. package/dist/node.d.ts.map +1 -0
  117. package/dist/node.js +9 -0
  118. package/dist/node.js.map +1 -0
  119. package/dist/sandbox/agent.d.ts +187 -0
  120. package/dist/sandbox/agent.d.ts.map +1 -0
  121. package/dist/sandbox/agent.js +468 -0
  122. package/dist/sandbox/agent.js.map +1 -0
  123. package/dist/sandbox/business-store.d.ts +19 -0
  124. package/dist/sandbox/business-store.d.ts.map +1 -0
  125. package/dist/sandbox/business-store.js +19 -0
  126. package/dist/sandbox/business-store.js.map +1 -0
  127. package/dist/sandbox/business.d.ts +70 -0
  128. package/dist/sandbox/business.d.ts.map +1 -0
  129. package/dist/sandbox/business.js +115 -0
  130. package/dist/sandbox/business.js.map +1 -0
  131. package/dist/sandbox/connect.d.ts +64 -0
  132. package/dist/sandbox/connect.d.ts.map +1 -0
  133. package/dist/sandbox/connect.js +182 -0
  134. package/dist/sandbox/connect.js.map +1 -0
  135. package/dist/sandbox/deployment.d.ts +14 -0
  136. package/dist/sandbox/deployment.d.ts.map +1 -0
  137. package/dist/sandbox/deployment.js +38 -0
  138. package/dist/sandbox/deployment.js.map +1 -0
  139. package/dist/sandbox/keys.d.ts +45 -0
  140. package/dist/sandbox/keys.d.ts.map +1 -0
  141. package/dist/sandbox/keys.js +132 -0
  142. package/dist/sandbox/keys.js.map +1 -0
  143. package/dist/sandbox/mailbox.d.ts +90 -0
  144. package/dist/sandbox/mailbox.d.ts.map +1 -0
  145. package/dist/sandbox/mailbox.js +400 -0
  146. package/dist/sandbox/mailbox.js.map +1 -0
  147. package/dist/sandbox/mandate.d.ts +84 -0
  148. package/dist/sandbox/mandate.d.ts.map +1 -0
  149. package/dist/sandbox/mandate.js +107 -0
  150. package/dist/sandbox/mandate.js.map +1 -0
  151. package/dist/sandbox/namespace.d.ts +16 -0
  152. package/dist/sandbox/namespace.d.ts.map +1 -0
  153. package/dist/sandbox/namespace.js +16 -0
  154. package/dist/sandbox/namespace.js.map +1 -0
  155. package/dist/sandbox/session.d.ts +60 -0
  156. package/dist/sandbox/session.d.ts.map +1 -0
  157. package/dist/sandbox/session.js +94 -0
  158. package/dist/sandbox/session.js.map +1 -0
  159. package/dist/sandbox/setup.d.ts +136 -0
  160. package/dist/sandbox/setup.d.ts.map +1 -0
  161. package/dist/sandbox/setup.js +490 -0
  162. package/dist/sandbox/setup.js.map +1 -0
  163. package/dist/sandbox/store.d.ts +69 -0
  164. package/dist/sandbox/store.d.ts.map +1 -0
  165. package/dist/sandbox/store.js +115 -0
  166. package/dist/sandbox/store.js.map +1 -0
  167. package/dist/sandbox/supplier-key.d.ts +73 -0
  168. package/dist/sandbox/supplier-key.d.ts.map +1 -0
  169. package/dist/sandbox/supplier-key.js +180 -0
  170. package/dist/sandbox/supplier-key.js.map +1 -0
  171. package/dist/sandbox/suppliers.d.ts +7 -0
  172. package/dist/sandbox/suppliers.d.ts.map +1 -0
  173. package/dist/sandbox/suppliers.js +29 -0
  174. package/dist/sandbox/suppliers.js.map +1 -0
  175. package/dist/sandbox/terms.d.ts +32 -0
  176. package/dist/sandbox/terms.d.ts.map +1 -0
  177. package/dist/sandbox/terms.js +58 -0
  178. package/dist/sandbox/terms.js.map +1 -0
  179. package/dist/sandbox/vault.d.ts +24 -0
  180. package/dist/sandbox/vault.d.ts.map +1 -0
  181. package/dist/sandbox/vault.js +54 -0
  182. package/dist/sandbox/vault.js.map +1 -0
  183. package/dist/send.d.ts +122 -0
  184. package/dist/send.d.ts.map +1 -0
  185. package/dist/send.js +328 -0
  186. package/dist/send.js.map +1 -0
  187. package/dist/service-entry.d.ts +6 -0
  188. package/dist/service-entry.d.ts.map +1 -0
  189. package/dist/service-entry.js +6 -0
  190. package/dist/service-entry.js.map +1 -0
  191. package/dist/session/anthropic.d.ts +17 -0
  192. package/dist/session/anthropic.d.ts.map +1 -0
  193. package/dist/session/anthropic.js +215 -0
  194. package/dist/session/anthropic.js.map +1 -0
  195. package/dist/session/charge.d.ts +13 -0
  196. package/dist/session/charge.d.ts.map +1 -0
  197. package/dist/session/charge.js +33 -0
  198. package/dist/session/charge.js.map +1 -0
  199. package/dist/session/data.d.ts +8 -0
  200. package/dist/session/data.d.ts.map +1 -0
  201. package/dist/session/data.js +20 -0
  202. package/dist/session/data.js.map +1 -0
  203. package/dist/session/eval.d.ts +41 -0
  204. package/dist/session/eval.d.ts.map +1 -0
  205. package/dist/session/eval.js +281 -0
  206. package/dist/session/eval.js.map +1 -0
  207. package/dist/session/executor.d.ts +80 -0
  208. package/dist/session/executor.d.ts.map +1 -0
  209. package/dist/session/executor.js +381 -0
  210. package/dist/session/executor.js.map +1 -0
  211. package/dist/session/fixture-world.d.ts +29 -0
  212. package/dist/session/fixture-world.d.ts.map +1 -0
  213. package/dist/session/fixture-world.js +708 -0
  214. package/dist/session/fixture-world.js.map +1 -0
  215. package/dist/session/live-world.d.ts +22 -0
  216. package/dist/session/live-world.d.ts.map +1 -0
  217. package/dist/session/live-world.js +329 -0
  218. package/dist/session/live-world.js.map +1 -0
  219. package/dist/session/ollama.d.ts +29 -0
  220. package/dist/session/ollama.d.ts.map +1 -0
  221. package/dist/session/ollama.js +177 -0
  222. package/dist/session/ollama.js.map +1 -0
  223. package/dist/session/provider.d.ts +79 -0
  224. package/dist/session/provider.d.ts.map +1 -0
  225. package/dist/session/provider.js +19 -0
  226. package/dist/session/provider.js.map +1 -0
  227. package/dist/session/scripted.d.ts +45 -0
  228. package/dist/session/scripted.d.ts.map +1 -0
  229. package/dist/session/scripted.js +236 -0
  230. package/dist/session/scripted.js.map +1 -0
  231. package/dist/session/selection.d.ts +37 -0
  232. package/dist/session/selection.d.ts.map +1 -0
  233. package/dist/session/selection.js +104 -0
  234. package/dist/session/selection.js.map +1 -0
  235. package/dist/session/service-check.d.ts +48 -0
  236. package/dist/session/service-check.d.ts.map +1 -0
  237. package/dist/session/service-check.js +86 -0
  238. package/dist/session/service-check.js.map +1 -0
  239. package/dist/session/service.d.ts +128 -0
  240. package/dist/session/service.d.ts.map +1 -0
  241. package/dist/session/service.js +150 -0
  242. package/dist/session/service.js.map +1 -0
  243. package/dist/session/session.d.ts +95 -0
  244. package/dist/session/session.d.ts.map +1 -0
  245. package/dist/session/session.js +312 -0
  246. package/dist/session/session.js.map +1 -0
  247. package/dist/session/toolbox.d.ts +69 -0
  248. package/dist/session/toolbox.d.ts.map +1 -0
  249. package/dist/session/toolbox.js +391 -0
  250. package/dist/session/toolbox.js.map +1 -0
  251. package/dist/session/tools.d.ts +45 -0
  252. package/dist/session/tools.d.ts.map +1 -0
  253. package/dist/session/tools.js +137 -0
  254. package/dist/session/tools.js.map +1 -0
  255. package/dist/session/world.d.ts +188 -0
  256. package/dist/session/world.d.ts.map +1 -0
  257. package/dist/session/world.js +2 -0
  258. package/dist/session/world.js.map +1 -0
  259. package/dist/sign.d.ts +19 -0
  260. package/dist/sign.d.ts.map +1 -0
  261. package/dist/sign.js +33 -0
  262. package/dist/sign.js.map +1 -0
  263. package/dist/supplier.d.ts +41 -0
  264. package/dist/supplier.d.ts.map +1 -0
  265. package/dist/supplier.js +57 -0
  266. package/dist/supplier.js.map +1 -0
  267. package/package.json +56 -3
@@ -0,0 +1,346 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { existsSync, renameSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
5
+ import { formatUsd } from '@avow-finance/spec';
6
+ import { banner, clean, firstRunIntro, lookOf, RAIL_OPEN_ENV, Rail, stylesOf, } from '@avow-finance/terminal';
7
+ import { moderatoClient } from '../moderato.js';
8
+ import { dailyLimitOf, keyLeftToday } from '../sandbox/agent.js';
9
+ import { loadBusinessItem } from '../sandbox/business-store.js';
10
+ import { loadSandboxDeployment } from '../sandbox/deployment.js';
11
+ import { sessionUrl } from '../sandbox/session.js';
12
+ import { prepareSandboxBusiness, } from '../sandbox/setup.js';
13
+ import { loadAgentItem } from '../sandbox/store.js';
14
+ import { MIN_PASSPHRASE } from '../sandbox/vault.js';
15
+ import { connectCommand } from './connect.js';
16
+ import { FIRST_RUN_STEPS } from './first-run.js';
17
+ import { readJobFlags, runJobSession, SERVICE_FILE } from './job.js';
18
+ import { listenCommand, orderCommand } from './mailbox.js';
19
+ import { fileStore, latestRun, SANDBOX_DIR, takeRun } from './platform.js';
20
+ import { checkTerminal, ensureChildrenGone, readBusinessConfig, runAgent, terminalPrompts, } from './runner.js';
21
+ import { keepSession, sessionForNextRun } from './runner-session.js';
22
+ import { terminalInput } from './session-input.js';
23
+ /**
24
+ * `avow-sandbox` runs a sandbox agent the way a developer works on one, with the business and the
25
+ * agent kept apart. The runner is the business. It reads `business.ts`, holds the root key sealed
26
+ * under a passphrase, and asks before it signs a mandate. The agent's file runs in a process of
27
+ * its own with only the agent's key, once each time Enter is pressed, and reports to the screen.
28
+ *
29
+ * avow-sandbox [start] sets up, opens the screen, then runs the agent session when the folder
30
+ * has service.ts, or agent.ts at each Enter when it doesn't
31
+ * avow-sandbox job runs one job with no input
32
+ * avow-sandbox fresh moves the business aside and starts a fresh one
33
+ *
34
+ * It draws setup as one rail of steps under Avow's banner. When create-avow-agent runs it in the
35
+ * folder it just made, the banner is already drawn and the rail already open, so it carries on.
36
+ */
37
+ const AGENT_FILE = 'agent.ts';
38
+ const BUSINESS_FILE = 'business.ts';
39
+ /** What `avow-sandbox --help` prints. */
40
+ const HELP = `avow-sandbox [start | job | fresh] [--provider local|anthropic] [--model id] [--scripted]
41
+
42
+ start sets up your business, opens your screen, and runs your agent session when the folder
43
+ has service.ts, or agent.ts each time you press Enter when it doesn't
44
+ job sets up when it's needed, then runs one job with no input
45
+ connect connects the agent in this folder to a business you run from the console, with
46
+ --business <id> from the console and --name for what the console calls it, and
47
+ --sell when it also quotes and accepts jobs for the business
48
+ order orders the demo job from another business with --supplier <id>, then checks the
49
+ quote, funds it and waits for the acceptance
50
+ listen reads the business's inbox and quotes and accepts each order, until you stop it
51
+ fresh moves your business aside, keys and all, and sets up a fresh one
52
+
53
+ --provider local a model Ollama runs on this machine, at no charge
54
+ --provider anthropic Claude, with ANTHROPIC_API_KEY from your environment, billed to that key
55
+ --model id the model to ask for, such as qwen3:8b
56
+ --scripted scripted decisions, the same every run, with no model
57
+ --details every tool call, receipt, address and link, as your screen shows them
58
+
59
+ With no provider chosen, the session picks a supported model Ollama has pulled, and runs the scripted
60
+ decisions when there's none. AVOW_MODEL_PROVIDER and AVOW_MODEL choose the same as the flags.
61
+
62
+ It runs on Tempo's Moderato testnet with test dollars. Your business's key stays in .avow on this
63
+ machine, sealed under your passphrase.`;
64
+ /** Set by create-avow-agent, which draws the banner and opens the rail before setup runs. */
65
+ const CONTINUED = process.env[RAIL_OPEN_ENV] === '1';
66
+ /**
67
+ * Opens a link in the default browser, quietly, when someone is at the terminal to see it, and says
68
+ * whether it tried.
69
+ */
70
+ function openInBrowser(url) {
71
+ if (!process.stdout.isTTY || process.env.CI || process.env.AVOW_SANDBOX_NO_OPEN === '1') {
72
+ return false;
73
+ }
74
+ const [opener, ...args] = process.platform === 'darwin'
75
+ ? ['open', url]
76
+ : process.platform === 'win32'
77
+ ? ['cmd', '/c', 'start', '""', url]
78
+ : ['xdg-open', url];
79
+ const child = spawn(opener, args, { stdio: 'ignore', detached: true });
80
+ child.on('error', () => { });
81
+ child.unref();
82
+ return true;
83
+ }
84
+ async function main(args) {
85
+ // An agent connecting to a business it doesn't hold the key of, from any folder.
86
+ if (args[0] === 'connect')
87
+ return connectCommand(args.slice(1));
88
+ // Its agent ordering from another business, or listening for orders to its own.
89
+ if (args[0] === 'order')
90
+ return orderCommand(args.slice(1));
91
+ if (args[0] === 'listen')
92
+ return listenCommand();
93
+ const command = !args[0] || args[0].startsWith('--') ? 'start' : args[0];
94
+ const flags = readJobFlags(args[0] === command ? args.slice(1) : args, process.env);
95
+ if ('error' in flags) {
96
+ console.error(`${flags.error}\n\n${HELP}`);
97
+ process.exit(1);
98
+ }
99
+ if (command === '--help' || command === '-h' || command === 'help') {
100
+ console.log(HELP);
101
+ return;
102
+ }
103
+ if (command !== 'start' && command !== 'fresh' && command !== 'job') {
104
+ console.error(`There's no command ${command} here.\n\n${HELP}`);
105
+ process.exit(1);
106
+ }
107
+ // The job chapter runs when the folder has service.ts, and `job` needs it.
108
+ const jobs = command === 'job' || existsSync(resolve(SERVICE_FILE));
109
+ for (const file of command === 'job'
110
+ ? [BUSINESS_FILE, SERVICE_FILE]
111
+ : [AGENT_FILE, BUSINESS_FILE]) {
112
+ if (!existsSync(resolve(file))) {
113
+ console.error(`There's no ${file} in ${process.cwd()}.`);
114
+ process.exit(1);
115
+ }
116
+ }
117
+ const look = lookOf(process.stdout, process.env, process.stderr);
118
+ const paint = stylesOf(look);
119
+ const input = terminalPrompts();
120
+ // The rail writes through the prompts, so output that arrives while the developer types never
121
+ // lands on the row they're typing on.
122
+ const rail = new Rail(look, (text) => input.print(text));
123
+ const say = (line = '') => {
124
+ rail.settle();
125
+ console.log(line);
126
+ };
127
+ const dir = join(process.cwd(), SANDBOX_DIR);
128
+ const store = fileStore(dir);
129
+ // A first run teaches as it goes, in four numbered steps, the last two in the agent session.
130
+ const firstRun = command === 'fresh' || (command === 'start' && (await loadBusinessItem(store)) === null);
131
+ if (!CONTINUED) {
132
+ say(banner(look));
133
+ if (firstRun)
134
+ say(firstRunIntro(look));
135
+ }
136
+ const config = await readBusinessConfig(BUSINESS_FILE);
137
+ if (!CONTINUED && !firstRun)
138
+ rail.open(config.name);
139
+ if (command === 'fresh' && existsSync(dir)) {
140
+ const aside = `${SANDBOX_DIR}-${new Date().toISOString().replace(/[:.]/g, '-')}`;
141
+ renameSync(dir, join(process.cwd(), aside));
142
+ rail.done(`Moved your previous business to ${aside}, keys and all.`);
143
+ }
144
+ const prompts = {
145
+ async newPassphrase() {
146
+ await ensureChildrenGone();
147
+ checkTerminal((line) => rail.line(line));
148
+ rail.ask(`Choose a passphrase for your business's key, at least ${MIN_PASSPHRASE} characters`);
149
+ for (;;) {
150
+ const first = await input.ask(rail.prefix, true);
151
+ if (first === null)
152
+ throw new Error('No passphrase was set.');
153
+ if (first.length < MIN_PASSPHRASE) {
154
+ rail.answered(`That's shorter than ${MIN_PASSPHRASE} characters. Choose another.`, 'bad');
155
+ continue;
156
+ }
157
+ rail.answered('Set', 'quiet');
158
+ if ((await input.ask(`${rail.prefix}${paint.dim('Type it again ')}`, true)) === first) {
159
+ rail.answered('Typed again, and it matches', 'quiet');
160
+ return first;
161
+ }
162
+ rail.answered("Those didn't match. Choose it again.", 'bad');
163
+ }
164
+ },
165
+ async passphrase() {
166
+ await ensureChildrenGone();
167
+ checkTerminal((line) => rail.line(line));
168
+ rail.ask("Type your business's passphrase");
169
+ const typed = await input.ask(rail.prefix, true);
170
+ if (typed === null)
171
+ throw new Error('No passphrase was typed.');
172
+ rail.answered('Typed', 'quiet');
173
+ return typed;
174
+ },
175
+ async confirm(question, details = []) {
176
+ rail.ask(question);
177
+ for (const detail of details)
178
+ rail.line(detail);
179
+ const answer = await input.ask(`${rail.prefix}${paint.dim('y/N')} `);
180
+ const yes = /^y(es)?$/i.test((answer ?? '').trim());
181
+ rail.answered(yes ? 'Yes' : 'No', 'quiet');
182
+ return yes;
183
+ },
184
+ };
185
+ // Setup's steps take the first two of the first run's numbers, and a run with no service.ts
186
+ // has only those two.
187
+ const steps = { at: 0, of: jobs && firstRun ? FIRST_RUN_STEPS : 2 };
188
+ const show = (line, kind = 'note') => {
189
+ if (kind === 'step') {
190
+ const [title = '', why] = line.split('\n');
191
+ steps.at += 1;
192
+ rail.step(steps.at, steps.of, title, why);
193
+ }
194
+ else if (kind === 'step_done')
195
+ rail.stepDone(line);
196
+ else if (kind === 'detail') {
197
+ if (flags.details)
198
+ rail.quiet(line);
199
+ }
200
+ else if (kind === 'stage')
201
+ rail.stage(line);
202
+ else if (kind === 'done')
203
+ rail.done(line);
204
+ else if (kind === 'wait')
205
+ rail.wait(line);
206
+ else
207
+ rail.line(line);
208
+ };
209
+ const deployment = await loadSandboxDeployment();
210
+ // The session stays with the business across restarts, so the screen a developer has open
211
+ // keeps working. A new one gets the agent's authority, signed by the business's key.
212
+ const sessionOptions = {
213
+ dir,
214
+ apiUrl: deployment.apiUrl,
215
+ log: (line) => rail.line(line),
216
+ };
217
+ let session = await keepSession({
218
+ ...sessionOptions,
219
+ account: (await loadBusinessItem(store))?.account ?? null,
220
+ });
221
+ // Setup reports any authority change under the first run, and the first press of Enter runs
222
+ // under it too, unless a model's tool call has started a run since.
223
+ let run = takeRun(dir, session.id);
224
+ let first = true;
225
+ const prepare = async (business = config) => {
226
+ const done = await prepareSandboxBusiness({
227
+ config: business,
228
+ prompts,
229
+ store,
230
+ deployment,
231
+ session: { id: session.id, run },
232
+ announce: session.fresh,
233
+ supplier: jobs,
234
+ log: show,
235
+ });
236
+ if (done.supplier && !done.supplier.ok)
237
+ show(done.supplier.why);
238
+ if (done.announced)
239
+ session = { ...session, fresh: false };
240
+ return done;
241
+ };
242
+ let ready = false;
243
+ try {
244
+ const done = await prepare();
245
+ ready = !jobs || done.supplier?.ok === true;
246
+ // A first run goes straight on to its next step, and only a stop gets the rail's last line.
247
+ if (!(firstRun && jobs && ready)) {
248
+ rail.close(ready ? `${config.name} is ready.` : `${config.name} is set up, and can't take jobs yet.`);
249
+ }
250
+ }
251
+ catch (error) {
252
+ rail.fail(error instanceof Error ? error.message : String(error));
253
+ rail.close(jobs ? 'Fix that and run it again.' : 'Fix that and press Enter to try again.');
254
+ }
255
+ // The link takes a line of its own, so the terminal never breaks it.
256
+ const screen = sessionUrl(session.id);
257
+ const opened = openInBrowser(screen);
258
+ if (firstRun && jobs && ready) {
259
+ rail.quiet(opened
260
+ ? 'Your browser opened your screen, which shows every step as it happens, at'
261
+ : 'Your screen shows every step as it happens, at');
262
+ say(`${rail.prefix}${screen}`);
263
+ }
264
+ else {
265
+ say(`\n ${opened ? 'Your screen opened in your browser, at' : 'Watch your agent on your screen, at'}`);
266
+ say(` ${screen}`);
267
+ }
268
+ if (jobs) {
269
+ if (!ready)
270
+ process.exit(1);
271
+ if (!firstRun) {
272
+ say();
273
+ rail.open(command === 'job' ? 'One job' : 'Your agent session');
274
+ }
275
+ const code = await runJobSession({
276
+ firstRun,
277
+ mode: command === 'job' ? 'one' : 'interactive',
278
+ flags,
279
+ rail,
280
+ look,
281
+ store,
282
+ deployment,
283
+ dir,
284
+ session,
285
+ nextRun: () => takeRun(dir, session.id),
286
+ prompts,
287
+ input: terminalInput(input, rail),
288
+ });
289
+ process.exit(code);
290
+ }
291
+ for (;;) {
292
+ say(`\n Press Enter to run ${AGENT_FILE}, or Ctrl+C to stop.`);
293
+ if ((await input.ask(' ')) === null)
294
+ break;
295
+ const next = await sessionForNextRun(session, sessionOptions);
296
+ if (next.id !== session.id) {
297
+ session = next;
298
+ first = false;
299
+ run = takeRun(dir, session.id);
300
+ say(`\n Avow's relay closes your session within ten minutes, so the runner opened a new one. Watch your agent at`);
301
+ say(` ${sessionUrl(session.id)}`);
302
+ }
303
+ else {
304
+ session = next;
305
+ if (!first || latestRun(dir, session.id) !== run)
306
+ run = takeRun(dir, session.id);
307
+ }
308
+ first = false;
309
+ say();
310
+ rail.open(`Run ${run}`);
311
+ try {
312
+ // business.ts is read again for each run, so an edit to it takes effect at the next Enter.
313
+ await prepare(await readBusinessConfig(BUSINESS_FILE));
314
+ }
315
+ catch (error) {
316
+ rail.fail(error instanceof Error ? error.message : String(error));
317
+ continue;
318
+ }
319
+ rail.settle();
320
+ const { code } = await runAgent(AGENT_FILE, { id: session.id, run });
321
+ if (code !== 0)
322
+ say(`\n${AGENT_FILE} stopped with an error.`);
323
+ await showKeyLeft(store, deployment).catch(() => { });
324
+ }
325
+ process.exit(0);
326
+ }
327
+ /** What the agent's key can still move today, and a fresh business when that runs low. */
328
+ async function showKeyLeft(store, deployment) {
329
+ const agent = await loadAgentItem(store);
330
+ if (!agent)
331
+ return;
332
+ const limit = dailyLimitOf(agent.mandate.message, agent.business.token);
333
+ if (limit === null)
334
+ return;
335
+ const left = await keyLeftToday(moderatoClient(deployment.rpcUrl), agent.business.account, agent.mandate.message.agentKey, agent.business.token);
336
+ console.log(`\nYour agent's key can move ${formatUsd(left)} more today, of its ${formatUsd(limit)} a day, a limit your business set on chain.`);
337
+ if (left * 4n < limit) {
338
+ console.log('That is running low. npm run fresh sets up a fresh sandbox business with a full day.');
339
+ }
340
+ }
341
+ main(process.argv.slice(2)).catch((error) => {
342
+ // A supplier's or a relay's own words can end up in an error, so they're cleaned like any outside text.
343
+ console.error(clean(error instanceof Error ? error.message : String(error)));
344
+ process.exit(1);
345
+ });
346
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/node/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** What `avow-sandbox connect` takes, read from its arguments, or why it can't run. */
2
+ export declare function readConnectArgs(args: readonly string[]): {
3
+ businessId: string;
4
+ label: string;
5
+ sell: boolean;
6
+ } | {
7
+ error: string;
8
+ };
9
+ /**
10
+ * `avow-sandbox connect --business <id> [--sell]`. Connects the agent in this folder to a business,
11
+ * with its own key kept in .avow here, and waits while the administrator approves it in the console.
12
+ * With `--sell` it also makes a signing key to quote and accept jobs for the business with.
13
+ */
14
+ export declare function connectCommand(args: readonly string[]): Promise<void>;
15
+ //# sourceMappingURL=connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/node/connect.ts"],"names":[],"mappings":"AAIA,uFAAuF;AACvF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA4B1E;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqD3E"}
@@ -0,0 +1,91 @@
1
+ import { renderUnicodeCompact } from 'uqr';
2
+ import { approvalLink, connectToBusiness, SANDBOX_CONSOLE_URL } from '../sandbox/connect.js';
3
+ import { fileStore } from './platform.js';
4
+ /** What `avow-sandbox connect` takes, read from its arguments, or why it can't run. */
5
+ export function readConnectArgs(args) {
6
+ let businessId = null;
7
+ let label = 'My agent';
8
+ let sell = false;
9
+ for (let i = 0; i < args.length; i++) {
10
+ const flag = args[i];
11
+ const value = args[i + 1];
12
+ if (flag === '--sell') {
13
+ sell = true;
14
+ continue;
15
+ }
16
+ if ((flag === '--business' || flag === '--name') &&
17
+ (value === undefined || value.startsWith('--'))) {
18
+ return { error: `${flag} needs a value` };
19
+ }
20
+ if (flag === '--business')
21
+ businessId = value ?? null;
22
+ else if (flag === '--name')
23
+ label = value ?? label;
24
+ else
25
+ return { error: `connect doesn't take ${flag}` };
26
+ i++;
27
+ }
28
+ if (!businessId) {
29
+ return {
30
+ error: `connect needs --business, the business ID your console shows at ${SANDBOX_CONSOLE_URL}`,
31
+ };
32
+ }
33
+ return { businessId, label, sell };
34
+ }
35
+ /**
36
+ * `avow-sandbox connect --business <id> [--sell]`. Connects the agent in this folder to a business,
37
+ * with its own key kept in .avow here, and waits while the administrator approves it in the console.
38
+ * With `--sell` it also makes a signing key to quote and accept jobs for the business with.
39
+ */
40
+ export async function connectCommand(args) {
41
+ const read = readConnectArgs(args);
42
+ if ('error' in read) {
43
+ console.error(read.error);
44
+ process.exit(1);
45
+ }
46
+ const stop = new AbortController();
47
+ process.once('SIGINT', () => stop.abort(new Error('Stopped waiting')));
48
+ let told = false;
49
+ const item = await connectToBusiness({
50
+ store: fileStore(),
51
+ businessId: read.businessId,
52
+ label: read.label,
53
+ sell: read.sell,
54
+ signal: stop.signal,
55
+ onEvent: (event) => {
56
+ if (event.type === 'asked') {
57
+ const link = approvalLink(event.agentKey);
58
+ console.log([
59
+ `Asked ${event.businessId} for authority, as "${read.label}".`,
60
+ '',
61
+ ` Pairing code ${event.pairingCode}`,
62
+ '',
63
+ 'Open this to review and approve it, on your phone or here. The console shows the same code.',
64
+ '',
65
+ ` ${link}`,
66
+ '',
67
+ // A phone can scan the link from a terminal a person is watching. An agent reading the
68
+ // output relays the link instead, so it gets no block art.
69
+ ...(process.stdout.isTTY ? [renderUnicodeCompact(link), ''] : []),
70
+ "This agent's key stays in .avow in this folder. Avow and the console never see it.",
71
+ ].join('\n'));
72
+ }
73
+ else if (event.type === 'waiting' && !told) {
74
+ told = true;
75
+ console.log('Waiting for the approval. Leave this running, or stop it and run connect again later.');
76
+ }
77
+ else if (event.type === 'approved') {
78
+ console.log(`Approved as ${event.agentId}. Picking up its authority from Avow.`);
79
+ }
80
+ else if (event.type === 'supplier') {
81
+ console.log(`Registered signing key ${event.signingKey} to sell for the business.`);
82
+ }
83
+ },
84
+ }).catch((error) => {
85
+ console.error(error instanceof Error ? error.message : String(error));
86
+ process.exit(1);
87
+ });
88
+ const m = item.mandate.message;
89
+ console.log(`Connected. This agent can commit for ${m.businessId} within the limits its administrator signed, until ${new Date(Number(m.expiry) * 1000).toISOString()}.`);
90
+ }
91
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/node/connect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=eval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/node/eval.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ import { appendFileSync, writeFileSync } from 'node:fs';
3
+ import { toWire } from '@avow-finance/spec';
4
+ import { evalModel, evalTable } from '../session/eval.js';
5
+ import { selectProvider } from '../session/selection.js';
6
+ import { readJobFlags } from './job.js';
7
+ /**
8
+ * Runs the eval in the fixture world, which needs no testnet and no secret.
9
+ *
10
+ * pnpm eval -- --model qwen3:8b five runs of steps 2 to 5, with a table per step
11
+ * pnpm eval -- --model qwen3:8b --speed one run, with its speed only
12
+ * pnpm eval -- --provider anthropic Claude as the reference, billed to your key
13
+ *
14
+ * `--trials n` sets the runs and `--out file.json` writes the report as JSON. In GitHub Actions the
15
+ * table goes to the job summary too.
16
+ */
17
+ async function main(args) {
18
+ const take = (name) => {
19
+ const i = args.indexOf(name);
20
+ if (i < 0)
21
+ return null;
22
+ const [, value] = args.splice(i, 2);
23
+ return value ?? null;
24
+ };
25
+ const speed = args.includes('--speed');
26
+ if (speed)
27
+ args.splice(args.indexOf('--speed'), 1);
28
+ const trials = Number(take('--trials') ?? (speed ? 1 : 5));
29
+ const out = take('--out');
30
+ const flags = readJobFlags(args, process.env);
31
+ if ('error' in flags || !Number.isInteger(trials) || trials < 1) {
32
+ console.error('error' in flags ? flags.error : '--trials needs a whole number from 1');
33
+ return 1;
34
+ }
35
+ const chosen = await selectProvider({ ...flags, env: process.env });
36
+ if (!chosen.ok) {
37
+ console.error([chosen.why, ...chosen.help].join('\n'));
38
+ return 1;
39
+ }
40
+ const model = chosen.provider;
41
+ console.log(`Eval in the fixture world with ${model.line}, ${trials} run${trials === 1 ? '' : 's'}.`);
42
+ const report = await evalModel(model, trials, (i, r) => {
43
+ const reached = Object.values(r.steps).filter(Boolean).length;
44
+ const held = Object.values(r.boundaries).every(Boolean);
45
+ console.log(`Run ${i}: ${reached} of ${Object.keys(r.steps).length} steps, boundaries ${held ? 'held' : 'FAILED'}${r.error ? `, stopped: ${r.error}` : ''}`);
46
+ });
47
+ if (speed) {
48
+ const ms = (v) => (v === null ? 'n/a' : `${Math.round(v)} ms`);
49
+ console.log(`Time to first token ${ms(report.firstTokenMs)}, ${report.tokensPerSecond?.toFixed(1) ?? 'n/a'} tokens a second, ${ms(report.firstJobMs)} for the first job.`);
50
+ }
51
+ else {
52
+ const table = evalTable([report]);
53
+ console.log(`\n${table}`);
54
+ if (process.env.GITHUB_STEP_SUMMARY)
55
+ appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${table}\n\n`);
56
+ }
57
+ if (out)
58
+ writeFileSync(out, `${JSON.stringify(toWire(report), null, 2)}\n`);
59
+ // A boundary that failed in any run fails the eval, whatever the model reached.
60
+ return Object.values(report.boundaries).every((n) => n === report.trials) ? 0 : 2;
61
+ }
62
+ // pnpm passes on the `--` that npm drops.
63
+ main(process.argv.slice(2).filter((arg, i) => !(i === 0 && arg === '--'))).then((code) => process.exit(code), (error) => {
64
+ console.error(error instanceof Error ? error.message : String(error));
65
+ process.exit(1);
66
+ });
67
+ //# sourceMappingURL=eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/node/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type OrderScenario, type SessionEvent } from '@avow-finance/spec';
2
+ import type { Rail } from '@avow-finance/terminal';
3
+ import type { JobOutcome } from '../session/executor.js';
4
+ import { type SessionInput } from '../session/session.js';
5
+ import type { ServiceExcerpt } from './service-excerpt.js';
6
+ /** How many steps a first run has, two of setup's and three of the agent session's. */
7
+ export declare const FIRST_RUN_STEPS = 5;
8
+ /**
9
+ * The guide for the last three steps of a first run, which the agent session runs. Step 3 is the
10
+ * first job, shown as two commitments with nothing prepaid. Step 4 is a broken promise: the
11
+ * developer takes an order the customer cancels after work starts, and the charge its terms allow
12
+ * is reported and confirmed while its contest window stays open. Step 5 breaks the chain between
13
+ * the two commitments: one more order with the compute booking held off, which the customer
14
+ * refuses. The guide draws the steps, asks for the scenario and holds the switch, and the session
15
+ * does everything else as it does on any run.
16
+ */
17
+ export interface FirstRunGuide {
18
+ /** Opens step 3, before the first job. */
19
+ start(): void;
20
+ /** Sees each event, for the amounts and dates the step's last line says. */
21
+ watch(event: SessionEvent): void;
22
+ /** How a job ended, which closes the step it belonged to. */
23
+ afterJob(outcome: JobOutcome | null): void;
24
+ /** Whether the order being taken goes without a compute booking. */
25
+ withoutCompute(): boolean;
26
+ /** The scenario the order being taken is asked for, or null for none. */
27
+ scenario(): OrderScenario | null;
28
+ /** The developer's input, watched for the job command steps 4 and 5 ask for. */
29
+ input: SessionInput;
30
+ }
31
+ /** How a job ended, in one line. */
32
+ export declare function outcomeLine(ended: JobOutcome | null, clock?: (unixSeconds: bigint) => string): string;
33
+ export declare function firstRunGuide(deps: {
34
+ rail: Rail;
35
+ input: SessionInput;
36
+ /** How the guide says a moment. */
37
+ clock: (unixSeconds: bigint) => string;
38
+ /** Writes a line the rail doesn't wrap, so a link stays whole. */
39
+ write: (text: string) => void;
40
+ /** A transaction's page in the chain's explorer, or null where there's no chain to show. */
41
+ transactionUrl: ((hash: `0x${string}`) => string) | null;
42
+ /** How to get a model, said at the end when the scripted decisions ran for want of one. */
43
+ modelHelp: string | null;
44
+ /** The service file's deciding lines, which the run ends on, or null when it has none to show. */
45
+ code: {
46
+ file: string;
47
+ excerpt: ServiceExcerpt;
48
+ } | null;
49
+ }): FirstRunGuide;
50
+ //# sourceMappingURL=first-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"first-run.d.ts","sourceRoot":"","sources":["../../src/node/first-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACrF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,uFAAuF;AACvF,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,KAAK,IAAI,IAAI,CAAA;IACb,4EAA4E;IAC5E,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAA;IAC1C,oEAAoE;IACpE,cAAc,IAAI,OAAO,CAAA;IACzB,yEAAyE;IACzE,QAAQ,IAAI,aAAa,GAAG,IAAI,CAAA;IAChC,gFAAgF;IAChF,KAAK,EAAE,YAAY,CAAA;CACpB;AAkCD,oCAAoC;AACpC,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,KAAK,GAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAY,GAC3C,MAAM,CAWR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAClC,IAAI,EAAE,IAAI,CAAA;IACV,KAAK,EAAE,YAAY,CAAA;IACnB,mCAAmC;IACnC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAA;IACtC,kEAAkE;IAClE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,4FAA4F;IAC5F,cAAc,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,CAAC,GAAG,IAAI,CAAA;IACxD,2FAA2F;IAC3F,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,kGAAkG;IAClG,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,cAAc,CAAA;KAAE,GAAG,IAAI,CAAA;CACvD,GAAG,aAAa,CAmIhB"}