@web42/w42 0.1.15 → 0.1.16

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.
@@ -4,7 +4,7 @@ import { Command } from "commander";
4
4
  import ora from "ora";
5
5
  import { v4 as uuidv4 } from "uuid";
6
6
  import { apiPost } from "../utils/api.js";
7
- import { getConfigValue, requireAuth, setConfigValue } from "../utils/config.js";
7
+ import { getConfig, getConfigValue, isTelemetryEnabled, requireAuth, setConfigValue } from "../utils/config.js";
8
8
  function isUrl(s) {
9
9
  return s.startsWith("http://") || s.startsWith("https://");
10
10
  }
@@ -42,6 +42,24 @@ function handleTaskState(state, taskId) {
42
42
  process.exit(1);
43
43
  }
44
44
  }
45
+ function submitMetric(slug, responseTimeMs, success) {
46
+ const cfg = getConfig();
47
+ fetch(`${cfg.apiUrl}/api/agents/metrics`, {
48
+ method: "POST",
49
+ headers: {
50
+ "Content-Type": "application/json",
51
+ ...(cfg.token ? { Authorization: `Bearer ${cfg.token}` } : {}),
52
+ },
53
+ body: JSON.stringify({
54
+ slug,
55
+ response_time_ms: responseTimeMs ?? null,
56
+ success,
57
+ }),
58
+ signal: AbortSignal.timeout(5000),
59
+ }).catch(() => {
60
+ // intentionally swallowed — telemetry must never affect UX
61
+ });
62
+ }
45
63
  function getCachedToken(slug) {
46
64
  const raw = getConfigValue(`agentTokens.${slug}`);
47
65
  if (!raw)
@@ -171,6 +189,8 @@ export const sendCommand = new Command("send")
171
189
  console.error(chalk.dim("Is the agent server running?"));
172
190
  process.exit(1);
173
191
  }
192
+ const startTime = Date.now();
193
+ let firstTokenMs;
174
194
  try {
175
195
  const stream = client.sendMessageStream({
176
196
  message: {
@@ -184,10 +204,14 @@ export const sendCommand = new Command("send")
184
204
  });
185
205
  for await (const event of stream) {
186
206
  if (event.kind === "message" && event.role === "agent") {
207
+ if (firstTokenMs === undefined)
208
+ firstTokenMs = Date.now() - startTime;
187
209
  for (const part of event.parts)
188
210
  printPart(part);
189
211
  }
190
212
  else if (event.kind === "artifact-update") {
213
+ if (firstTokenMs === undefined)
214
+ firstTokenMs = Date.now() - startTime;
191
215
  // When append is true we're receiving streaming chunks — write inline.
192
216
  // When it's a new artifact (append falsy), separate from prior output.
193
217
  if (!event.append)
@@ -203,6 +227,8 @@ export const sendCommand = new Command("send")
203
227
  handleTaskState(event.status?.state, event.taskId);
204
228
  }
205
229
  else if (event.kind === "task") {
230
+ if (firstTokenMs === undefined)
231
+ firstTokenMs = Date.now() - startTime;
206
232
  // Non-streaming fallback: server returned the full task object.
207
233
  // Print accumulated artifacts and handle terminal state.
208
234
  for (const artifact of event.artifacts ?? []) {
@@ -218,8 +244,14 @@ export const sendCommand = new Command("send")
218
244
  }
219
245
  }
220
246
  process.stdout.write("\n");
247
+ if (isTelemetryEnabled() && !isUrl(agent)) {
248
+ submitMetric(agent, firstTokenMs, true);
249
+ }
221
250
  }
222
251
  catch (err) {
252
+ if (isTelemetryEnabled() && !isUrl(agent)) {
253
+ submitMetric(agent, firstTokenMs, false);
254
+ }
223
255
  console.error(chalk.red("\nConnection lost."), chalk.dim(String(err)));
224
256
  process.exit(1);
225
257
  }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const telemetryCommand: Command;
@@ -0,0 +1,27 @@
1
+ import chalk from "chalk";
2
+ import { Command } from "commander";
3
+ import { isTelemetryEnabled, setTelemetry } from "../utils/config.js";
4
+ export const telemetryCommand = new Command("telemetry")
5
+ .description("Manage telemetry settings")
6
+ .argument("[state]", "on | off")
7
+ .action((state) => {
8
+ if (!state) {
9
+ const enabled = isTelemetryEnabled();
10
+ console.log(enabled
11
+ ? chalk.green("Telemetry is enabled.")
12
+ : chalk.yellow("Telemetry is disabled."));
13
+ return;
14
+ }
15
+ if (state === "on") {
16
+ setTelemetry(true);
17
+ console.log(chalk.green("Telemetry enabled."));
18
+ }
19
+ else if (state === "off") {
20
+ setTelemetry(false);
21
+ console.log(chalk.yellow("Telemetry disabled."));
22
+ }
23
+ else {
24
+ console.error(chalk.red(`Unknown state "${state}". Use "on" or "off".`));
25
+ process.exit(1);
26
+ }
27
+ });
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { registerCommand } from "./commands/register.js";
5
5
  import { searchCommand } from "./commands/search.js";
6
6
  import { sendCommand } from "./commands/send.js";
7
7
  import { serveCommand } from "./commands/serve.js";
8
+ import { telemetryCommand } from "./commands/telemetry.js";
8
9
  import { setApiUrl } from "./utils/config.js";
9
10
  import { CLI_VERSION } from "./version.js";
10
11
  const program = new Command();
@@ -24,4 +25,5 @@ program.addCommand(registerCommand);
24
25
  program.addCommand(searchCommand);
25
26
  program.addCommand(sendCommand);
26
27
  program.addCommand(serveCommand);
28
+ program.addCommand(telemetryCommand);
27
29
  program.parse();
@@ -6,6 +6,7 @@ interface W42Config {
6
6
  avatarUrl?: string;
7
7
  token?: string;
8
8
  authenticated: boolean;
9
+ telemetry?: boolean;
9
10
  }
10
11
  export declare function getConfig(): W42Config;
11
12
  export declare function setAuth(data: {
@@ -21,4 +22,6 @@ export declare function isAuthenticated(): boolean;
21
22
  export declare function requireAuth(): W42Config;
22
23
  export declare function setConfigValue(key: string, value: string): void;
23
24
  export declare function getConfigValue(key: string): string | undefined;
25
+ export declare function isTelemetryEnabled(): boolean;
26
+ export declare function setTelemetry(enabled: boolean): void;
24
27
  export {};
@@ -4,6 +4,7 @@ const config = new Conf({
4
4
  defaults: {
5
5
  apiUrl: "https://web42-network.vercel.app",
6
6
  authenticated: false,
7
+ telemetry: true,
7
8
  },
8
9
  });
9
10
  export function getConfig() {
@@ -58,3 +59,9 @@ export function getConfigValue(key) {
58
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
60
  return config.get(key);
60
61
  }
62
+ export function isTelemetryEnabled() {
63
+ return config.get("telemetry") !== false;
64
+ }
65
+ export function setTelemetry(enabled) {
66
+ config.set("telemetry", enabled);
67
+ }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const CLI_VERSION = "0.1.15";
1
+ export declare const CLI_VERSION = "0.1.16";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = "0.1.15";
1
+ export const CLI_VERSION = "0.1.16";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@web42/w42",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "CLI for the Web42 Agent Network — discover, register, and communicate with A2A agents",
5
5
  "type": "module",
6
6
  "bin": {