clawmoney 0.15.31 → 0.15.32
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/dist/commands/relay-setup.js +27 -28
- package/dist/commands/relay.d.ts +4 -0
- package/dist/commands/relay.js +39 -0
- package/dist/index.js +15 -1
- package/package.json +1 -1
|
@@ -195,7 +195,7 @@ export async function relaySetupCommand() {
|
|
|
195
195
|
log.warn(`${cli}: no recommended models found — skipping`);
|
|
196
196
|
continue;
|
|
197
197
|
}
|
|
198
|
-
log.
|
|
198
|
+
log.success(`${chalk.bold(cli)}: ${recommended.length} models ${chalk.dim("— " + recommended.join(", "))}`);
|
|
199
199
|
for (const model of recommended) {
|
|
200
200
|
const p = API_PRICES[model];
|
|
201
201
|
registrations.push({
|
|
@@ -285,18 +285,18 @@ export async function relaySetupCommand() {
|
|
|
285
285
|
15: "~25%", 30: "~50%", 45: "~75%", 60: "~100%",
|
|
286
286
|
};
|
|
287
287
|
const earnPct = Math.round((1 - PLATFORM_FEE) * 100);
|
|
288
|
+
// Single batch POST — one round-trip, one DB session, no
|
|
289
|
+
// client-side fan-out. The earlier sequential loop paid 7× the
|
|
290
|
+
// TLS/bcrypt/CF overhead, and parallelizing with Promise.all
|
|
291
|
+
// tripped over client- or proxy-level concurrency limits on some
|
|
292
|
+
// machines. Batch endpoint is the right architecture.
|
|
288
293
|
let succeeded = 0;
|
|
289
294
|
let failed = 0;
|
|
290
295
|
const failures = [];
|
|
291
296
|
const regSpin = spinner();
|
|
292
297
|
regSpin.start(`Registering ${registrations.length} providers...`);
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
// idempotent on (agent_id, cli_type, model). Sequential registration
|
|
296
|
-
// was costing ~1 RTT per row, which on a high-latency link (e.g. from
|
|
297
|
-
// China) added up to 7-10s of visible wait for 7 providers.
|
|
298
|
-
await Promise.all(registrations.map(async (r) => {
|
|
299
|
-
const body = {
|
|
298
|
+
const batchBody = {
|
|
299
|
+
providers: registrations.map((r) => ({
|
|
300
300
|
cli_type: r.cli,
|
|
301
301
|
model: r.model,
|
|
302
302
|
mode: "chat",
|
|
@@ -304,32 +304,31 @@ export async function relaySetupCommand() {
|
|
|
304
304
|
daily_limit_usd: dailyLimit,
|
|
305
305
|
price_input_per_m: r.input,
|
|
306
306
|
price_output_per_m: r.output,
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
307
|
+
})),
|
|
308
|
+
};
|
|
309
|
+
try {
|
|
310
|
+
const resp = await apiPost("/api/v1/relay/providers/batch", batchBody, config.api_key);
|
|
311
|
+
if (!resp.ok) {
|
|
314
312
|
const raw = resp.data && typeof resp.data === "object" && "detail" in resp.data
|
|
315
313
|
? resp.data.detail
|
|
316
314
|
: resp.data;
|
|
317
315
|
const detail = typeof raw === "string" ? raw : JSON.stringify(raw);
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
failed++;
|
|
324
|
-
failures.push({ cli: r.cli, model: r.model, error: detail });
|
|
325
|
-
}
|
|
316
|
+
regSpin.stop(chalk.red(`✗ Batch registration failed: ${detail}`));
|
|
317
|
+
cancel("Setup aborted");
|
|
318
|
+
process.exit(1);
|
|
326
319
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
320
|
+
// Per-row counts from the batch result.
|
|
321
|
+
succeeded = (resp.data.created?.length ?? 0) + (resp.data.skipped?.length ?? 0);
|
|
322
|
+
failed = resp.data.failed?.length ?? 0;
|
|
323
|
+
for (const f of resp.data.failed ?? []) {
|
|
324
|
+
failures.push({ cli: f.cli_type, model: f.model, error: f.error });
|
|
331
325
|
}
|
|
332
|
-
}
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
regSpin.stop(chalk.red(`✗ Batch registration failed: ${err.message}`));
|
|
329
|
+
cancel("Setup aborted");
|
|
330
|
+
process.exit(1);
|
|
331
|
+
}
|
|
333
332
|
if (failed === 0) {
|
|
334
333
|
regSpin.stop(`${chalk.green(`✓ ${succeeded} providers registered`)} ` +
|
|
335
334
|
chalk.dim(`(${limitLabel[dailyLimit] ?? `$${dailyLimit}`} quota share · you earn ~${earnPct}%)`));
|
package/dist/commands/relay.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ export declare function relayStartCommand(options: {
|
|
|
12
12
|
cli?: string;
|
|
13
13
|
}): Promise<void>;
|
|
14
14
|
export declare function relayStopCommand(): Promise<void>;
|
|
15
|
+
export declare function relayLogsCommand(options: {
|
|
16
|
+
follow?: boolean;
|
|
17
|
+
lines?: string;
|
|
18
|
+
}): Promise<void>;
|
|
15
19
|
export declare function relayStatusCommand(): Promise<void>;
|
|
16
20
|
export declare function relayModelsCommand(): Promise<void>;
|
|
17
21
|
export declare function relayCreditsCommand(): Promise<void>;
|
package/dist/commands/relay.js
CHANGED
|
@@ -192,6 +192,32 @@ export async function relayStopCommand() {
|
|
|
192
192
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
193
193
|
removeRelayPid();
|
|
194
194
|
}
|
|
195
|
+
// ── relay logs ──
|
|
196
|
+
export async function relayLogsCommand(options) {
|
|
197
|
+
const { existsSync } = await import("node:fs");
|
|
198
|
+
const { spawn } = await import("node:child_process");
|
|
199
|
+
if (!existsSync(LOG_FILE)) {
|
|
200
|
+
console.log(chalk.dim(`No log file yet at ${LOG_FILE}`));
|
|
201
|
+
console.log(chalk.dim("Start the daemon first: clawmoney relay start"));
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Default: tail -f the last 50 lines. Use system `tail` rather than
|
|
205
|
+
// reimplementing it in Node — it's just a debug helper, not worth
|
|
206
|
+
// a pure-JS reinvention.
|
|
207
|
+
const nLines = options.lines ?? "50";
|
|
208
|
+
const args = ["-n", nLines];
|
|
209
|
+
if (options.follow !== false) {
|
|
210
|
+
args.push("-f");
|
|
211
|
+
}
|
|
212
|
+
args.push(LOG_FILE);
|
|
213
|
+
const child = spawn("tail", args, { stdio: "inherit" });
|
|
214
|
+
child.on("exit", (code) => {
|
|
215
|
+
process.exit(code ?? 0);
|
|
216
|
+
});
|
|
217
|
+
// Ctrl-C inside `tail -f` kills tail but returns us here; propagate
|
|
218
|
+
// the exit code so the wrapper looks transparent.
|
|
219
|
+
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
220
|
+
}
|
|
195
221
|
export async function relayStatusCommand() {
|
|
196
222
|
const config = requireConfig();
|
|
197
223
|
// Local process status
|
|
@@ -237,6 +263,19 @@ export async function relayStatusCommand() {
|
|
|
237
263
|
console.log(chalk.dim(` Run "clawmoney relay setup" to get started.`));
|
|
238
264
|
return;
|
|
239
265
|
}
|
|
266
|
+
// Group rows by cli_type so `claude-*` lines stay together, then
|
|
267
|
+
// `codex-*`, then `gemini-*`, then `antigravity-*`. Within a family
|
|
268
|
+
// we sort by model name so the ordering is stable across calls.
|
|
269
|
+
const CLI_ORDER = ["claude", "codex", "gemini", "antigravity"];
|
|
270
|
+
providers.sort((a, b) => {
|
|
271
|
+
const ai = CLI_ORDER.indexOf(a.cli_type ?? "");
|
|
272
|
+
const bi = CLI_ORDER.indexOf(b.cli_type ?? "");
|
|
273
|
+
const aRank = ai === -1 ? CLI_ORDER.length : ai;
|
|
274
|
+
const bRank = bi === -1 ? CLI_ORDER.length : bi;
|
|
275
|
+
if (aRank !== bRank)
|
|
276
|
+
return aRank - bRank;
|
|
277
|
+
return (a.model ?? "").localeCompare(b.model ?? "");
|
|
278
|
+
});
|
|
240
279
|
spinner.succeed(`Relay Providers (${providers.length})`);
|
|
241
280
|
console.log("");
|
|
242
281
|
// Aggregate stats across all rows since users think of earnings /
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { walletStatusCommand, walletBalanceCommand, walletAddressCommand, wallet
|
|
|
8
8
|
import { tweetCommand } from './commands/tweet.js';
|
|
9
9
|
import { gigCreateCommand, gigBrowseCommand, gigDetailCommand, gigAcceptCommand, gigDeliverCommand, gigApproveCommand, gigDisputeCommand, } from './commands/gig.js';
|
|
10
10
|
import { hubStartCommand, hubStopCommand, hubStatusCommand, hubSearchCommand, hubCallCommand, hubRegisterCommand, hubSkillsCommand, hubOrderCommand, hubHistoryCommand, } from './commands/hub.js';
|
|
11
|
-
import { relayRegisterCommand, relayStartCommand, relayStopCommand, relayStatusCommand, relayModelsCommand, relayCreditsCommand, } from './commands/relay.js';
|
|
11
|
+
import { relayRegisterCommand, relayStartCommand, relayStopCommand, relayStatusCommand, relayModelsCommand, relayCreditsCommand, relayLogsCommand, } from './commands/relay.js';
|
|
12
12
|
import { antigravityLoginCommand, antigravityStatusCommand, } from './commands/antigravity.js';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
14
|
const require = createRequire(import.meta.url);
|
|
@@ -527,6 +527,20 @@ relay
|
|
|
527
527
|
process.exit(1);
|
|
528
528
|
}
|
|
529
529
|
});
|
|
530
|
+
relay
|
|
531
|
+
.command('logs')
|
|
532
|
+
.description('Tail the daemon log in real time (like `tail -f ~/.clawmoney/relay.log`)')
|
|
533
|
+
.option('-n, --lines <n>', 'Lines of history to show before following', '50')
|
|
534
|
+
.option('--no-follow', "Print and exit instead of following")
|
|
535
|
+
.action(async (options) => {
|
|
536
|
+
try {
|
|
537
|
+
await relayLogsCommand(options);
|
|
538
|
+
}
|
|
539
|
+
catch (err) {
|
|
540
|
+
console.error(err.message);
|
|
541
|
+
process.exit(1);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
530
544
|
relay
|
|
531
545
|
.command('models')
|
|
532
546
|
.description('List available relay models')
|