@aomi-labs/client 0.1.0 → 0.1.2

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.
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # @aomi-labs/client
2
+
3
+ TypeScript client for the Aomi on-chain agent backend. Works in Node.js and browsers.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @aomi-labs/client
9
+ # or
10
+ pnpm add @aomi-labs/client
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ### Low-level client
16
+
17
+ Direct HTTP/SSE access to all backend endpoints.
18
+
19
+ ```ts
20
+ import { AomiClient } from "@aomi-labs/client";
21
+
22
+ const client = new AomiClient({ baseUrl: "https://api.aomi.dev" });
23
+
24
+ const threadId = crypto.randomUUID();
25
+ await client.createThread(threadId);
26
+
27
+ const response = await client.sendMessage(threadId, "What's the price of ETH?");
28
+ console.log(response.messages);
29
+ ```
30
+
31
+ ### Session (high-level)
32
+
33
+ Handles polling, event dispatch, and wallet request management automatically.
34
+
35
+ ```ts
36
+ import { Session } from "@aomi-labs/client";
37
+
38
+ const session = new Session(
39
+ { baseUrl: "https://api.aomi.dev" },
40
+ { namespace: "default" },
41
+ );
42
+
43
+ // Blocking send — polls until the agent finishes responding
44
+ const result = await session.send("Swap 1 ETH for USDC on Uniswap");
45
+ console.log(result.messages);
46
+
47
+ // Listen for wallet signing requests
48
+ session.on("wallet_tx_request", async (req) => {
49
+ const signed = await mySigner.signTransaction(req.payload);
50
+ await session.resolve(req.id, { txHash: signed.hash });
51
+ });
52
+
53
+ session.close();
54
+ ```
55
+
56
+ ### Session API
57
+
58
+ #### Constructor
59
+
60
+ ```ts
61
+ new Session(clientOptions: AomiClientOptions, sessionOptions?: SessionOptions)
62
+ // or pass an existing AomiClient instance:
63
+ new Session(client: AomiClient, sessionOptions?: SessionOptions)
64
+ ```
65
+
66
+ | Option | Default | Description |
67
+ |--------|---------|-------------|
68
+ | `sessionId` | `crypto.randomUUID()` | Thread/session ID |
69
+ | `namespace` | `"default"` | Backend namespace |
70
+ | `publicKey` | — | Wallet address |
71
+ | `apiKey` | — | API key for private namespaces |
72
+ | `userState` | — | Arbitrary user state sent with requests |
73
+ | `pollIntervalMs` | `500` | Polling interval in ms |
74
+ | `logger` | — | Pass `console` for debug output |
75
+
76
+ #### Methods
77
+
78
+ | Method | Description |
79
+ |--------|-------------|
80
+ | `send(message)` | Send a message, wait for completion, return `{ messages, title }` |
81
+ | `sendAsync(message)` | Send without waiting — poll in background, listen via events |
82
+ | `resolve(id, result)` | Resolve a pending wallet request |
83
+ | `reject(id, reason?)` | Reject a pending wallet request |
84
+ | `interrupt()` | Cancel current processing |
85
+ | `close()` | Stop polling, unsubscribe SSE, clean up |
86
+ | `getMessages()` | Current messages |
87
+ | `getTitle()` | Current session title |
88
+ | `getPendingRequests()` | Pending wallet requests |
89
+ | `getIsProcessing()` | Whether the agent is processing |
90
+
91
+ #### Events
92
+
93
+ ```ts
94
+ session.on("wallet_tx_request", (req) => { ... });
95
+ session.on("wallet_eip712_request", (req) => { ... });
96
+ session.on("messages", (msgs) => { ... });
97
+ session.on("processing_start", () => { ... });
98
+ session.on("processing_end", () => { ... });
99
+ session.on("title_changed", ({ title }) => { ... });
100
+ session.on("tool_update", (event) => { ... });
101
+ session.on("tool_complete", (event) => { ... });
102
+ session.on("system_notice", ({ message }) => { ... });
103
+ session.on("system_error", ({ message }) => { ... });
104
+ session.on("error", ({ error }) => { ... });
105
+ session.on("*", ({ type, payload }) => { ... }); // wildcard
106
+ ```
107
+
108
+ `.on()` returns an unsubscribe function:
109
+
110
+ ```ts
111
+ const unsub = session.on("messages", handler);
112
+ unsub(); // stop listening
113
+ ```
114
+
115
+ ## CLI
116
+
117
+ The package includes an `aomi` CLI for scripting and Claude Code skills.
118
+ When installed globally or in a project, the executable name is `aomi`.
119
+ For one-off usage, run commands via `npx @aomi-labs/client ...`.
120
+
121
+ ```bash
122
+ npx @aomi-labs/client chat "swap 1 ETH for USDC" # talk to the agent
123
+ npx @aomi-labs/client chat "swap 1 ETH for USDC" --model claude-sonnet-4
124
+ npx @aomi-labs/client chat "swap 1 ETH" --verbose # stream tool calls + responses live
125
+ npx @aomi-labs/client models # list available models
126
+ npx @aomi-labs/client model set claude-sonnet-4 # switch the current session model
127
+ npx @aomi-labs/client log # show full conversation history
128
+ npx @aomi-labs/client tx # list pending + signed txs
129
+ npx @aomi-labs/client sign tx-1 # sign a specific pending tx
130
+ npx @aomi-labs/client status # session info
131
+ npx @aomi-labs/client events # system events
132
+ npx @aomi-labs/client close # clear session
133
+ ```
134
+
135
+ ### Wallet connection
136
+
137
+ Pass `--public-key` so the agent knows your wallet address. This lets it build
138
+ transactions and check your balances:
139
+
140
+ ```bash
141
+ npx @aomi-labs/client chat "send 0 ETH to myself" \
142
+ --public-key 0x5D907BEa404e6F821d467314a9cA07663CF64c9B
143
+ ```
144
+
145
+ The address is persisted in the state file, so subsequent commands in the same
146
+ session don't need it again.
147
+
148
+ ### Model selection
149
+
150
+ The CLI can discover and switch backend models for the active session:
151
+
152
+ ```bash
153
+ $ npx @aomi-labs/client models
154
+ claude-sonnet-4
155
+ gpt-5
156
+
157
+ $ npx @aomi-labs/client model set gpt-5
158
+ Model set to gpt-5
159
+
160
+ $ npx @aomi-labs/client chat "hello" --model claude-sonnet-4
161
+ ```
162
+
163
+ `aomi model set` persists the selected model in the local session state after a
164
+ successful backend update. `aomi chat --model ...` applies the requested model
165
+ before sending the message and updates that persisted state as well.
166
+
167
+ ### Transaction flow
168
+
169
+ The backend builds transactions; the CLI persists and signs them:
170
+
171
+ ```
172
+ $ npx @aomi-labs/client chat "swap 1 ETH for USDC on Uniswap" --public-key 0xYourAddr
173
+ ⚡ Wallet request queued: tx-1
174
+ to: 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD
175
+ value: 1000000000000000000
176
+ chain: 1
177
+ Run `aomi tx` to see pending transactions, `aomi sign <id>` to sign.
178
+
179
+ $ npx @aomi-labs/client tx
180
+ Pending (1):
181
+ ⏳ tx-1 to: 0x3fC9...7FAD value: 1000000000000000000 chain: 1
182
+
183
+ $ npx @aomi-labs/client sign tx-1 --private-key 0xac0974...
184
+ Signer: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
185
+ ID: tx-1
186
+ Kind: transaction
187
+ To: 0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD
188
+ Value: 1000000000000000000
189
+ ✅ Sent! Hash: 0xabc123...
190
+ Backend notified.
191
+
192
+ $ npx @aomi-labs/client tx
193
+ Signed (1):
194
+ ✅ tx-1 hash: 0xabc123... to: 0x3fC9...7FAD value: 1000000000000000000
195
+ ```
196
+
197
+ **EIP-712 signing** is also supported. When the backend requests a typed data
198
+ signature (e.g. for CoW Protocol orders or permit approvals), it shows up as a
199
+ pending tx with `kind: eip712_sign`. `aomi sign` handles both kinds
200
+ automatically:
201
+
202
+ ```
203
+ $ npx @aomi-labs/client tx
204
+ Pending (1):
205
+ ⏳ tx-2 eip712 Sign CoW swap order (2:15:30 PM)
206
+
207
+ $ npx @aomi-labs/client sign tx-2 --private-key 0xac0974...
208
+ Signer: 0xf39Fd...92266
209
+ ID: tx-2
210
+ Kind: eip712_sign
211
+ Desc: Sign CoW swap order
212
+ Type: Order
213
+ ✅ Signed! Signature: 0x1a2b3c4d5e6f...
214
+ Backend notified.
215
+ ```
216
+
217
+ Pending and signed transactions are persisted in `$TMPDIR/aomi-session.json`
218
+ alongside the session pointer, so they survive between CLI invocations.
219
+
220
+ ### Verbose mode & conversation log
221
+
222
+ Use `--verbose` (or `-v`) to see tool calls and agent responses in real-time:
223
+
224
+ ```
225
+ $ npx @aomi-labs/client chat "what's the price of ETH?" --verbose
226
+ ⏳ Processing…
227
+ 🔧 [tool] get_token_price: running
228
+ ✔ [tool] get_token_price → {"price": 2045.67, "symbol": "ETH"}
229
+ 🤖 ETH is currently trading at $2,045.67.
230
+ ✅ Done
231
+ ```
232
+
233
+ Without `--verbose`, only the final agent message is printed.
234
+
235
+ Use `aomi log` to replay the full conversation with all messages and tool results:
236
+
237
+ ```
238
+ $ npx @aomi-labs/client log
239
+ 10:30:15 AM 👤 You: what's the price of ETH?
240
+ 10:30:16 AM 🤖 Agent: Let me check the current on-chain context for you.
241
+ 10:30:16 AM 🔧 [Current ETH price] {"price": 2045.67, "symbol": "ETH"}
242
+ 10:30:17 AM 🤖 Agent: ETH is currently trading at $2,045.67.
243
+
244
+ — 4 messages —
245
+ ```
246
+
247
+ ### Options
248
+
249
+ All config can be passed as flags (which take priority over env vars):
250
+
251
+ | Flag | Env Variable | Default | Description |
252
+ |------|-------------|---------|-------------|
253
+ | `--backend-url` | `AOMI_BASE_URL` | `https://api.aomi.dev` | Backend URL |
254
+ | `--api-key` | `AOMI_API_KEY` | — | API key for non-default namespaces |
255
+ | `--namespace` | `AOMI_NAMESPACE` | `default` | Namespace |
256
+ | `--model` | `AOMI_MODEL` | — | Model rig to apply before chat |
257
+ | `--public-key` | `AOMI_PUBLIC_KEY` | — | Wallet address (tells agent your wallet) |
258
+ | `--private-key` | `PRIVATE_KEY` | — | Hex private key for `aomi sign` |
259
+ | `--rpc-url` | `CHAIN_RPC_URL` | — | RPC URL for transaction submission |
260
+ | `--verbose`, `-v` | — | — | Stream tool calls and agent responses live |
261
+
262
+ ```bash
263
+ # Use a custom backend
264
+ npx @aomi-labs/client chat "hello" --backend-url https://my-backend.example.com
265
+
266
+ # Full signing flow with all flags
267
+ npx @aomi-labs/client chat "send 0.1 ETH to vitalik.eth" \
268
+ --public-key 0xYourAddress \
269
+ --api-key sk-abc123 \
270
+ --namespace my-agent \
271
+ --model claude-sonnet-4
272
+ npx @aomi-labs/client sign tx-1 \
273
+ --private-key 0xYourPrivateKey \
274
+ --rpc-url https://eth.llamarpc.com
275
+ ```
276
+
277
+ ### How state works
278
+
279
+ The CLI is **not** a long-running process — each command starts, runs, and
280
+ exits. Conversation history lives on the backend. Between invocations, the CLI
281
+ persists a small JSON file to `$TMPDIR/aomi-session.json`:
282
+
283
+ | Field | Purpose |
284
+ |-------|---------|
285
+ | `sessionId` | Which conversation to continue |
286
+ | `model` | Last successfully applied model for the session |
287
+ | `publicKey` | Wallet address (from `--public-key`) |
288
+ | `pendingTxs` | Unsigned transactions waiting for `aomi sign <id>` |
289
+ | `signedTxs` | Completed transactions with hashes/signatures |
290
+
291
+ ```
292
+ $ npx @aomi-labs/client chat "hello" # creates session, saves sessionId
293
+ $ npx @aomi-labs/client chat "swap 1 ETH" # reuses session, queues tx-1 if wallet request arrives
294
+ $ npx @aomi-labs/client sign tx-1 # signs tx-1, moves to signedTxs, notifies backend
295
+ $ npx @aomi-labs/client tx # shows all txs
296
+ $ npx @aomi-labs/client close # wipes state file
297
+ ```
298
+
299
+ The state file lives in your OS temp directory and gets cleaned up on reboot.