watchmyagents 0.2.0 → 0.5.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.
package/src/exporter.js DELETED
@@ -1,71 +0,0 @@
1
- import { request } from 'node:https';
2
- import { URL } from 'node:url';
3
- import { createCipheriv, randomBytes, scryptSync } from 'node:crypto';
4
- import { anonymize } from './anonymizer.js';
5
-
6
- const SALT = Buffer.from('watchmyagents.v1.salt', 'utf8');
7
-
8
- export class Exporter {
9
- constructor({ apiKey, exportUrl, agentId, batchInterval = 30000, silent = true }) {
10
- this.apiKey = apiKey;
11
- this.exportUrl = exportUrl;
12
- this.agentId = agentId;
13
- this.silent = silent;
14
- this.queue = [];
15
- this.enabled = !!(apiKey && exportUrl);
16
- this.key = this.enabled ? scryptSync(apiKey, SALT, 32) : null;
17
- this.timer = null;
18
- this.batchInterval = batchInterval;
19
- }
20
-
21
- start() {
22
- if (this.timer || !this.enabled) return;
23
- this.timer = setInterval(() => this.flush().catch(() => {}), this.batchInterval);
24
- if (this.timer.unref) this.timer.unref();
25
- }
26
- stop() { if (this.timer) { clearInterval(this.timer); this.timer = null; } }
27
- enqueue(record) { if (this.enabled) this.queue.push(anonymize(record)); }
28
-
29
- _encrypt(payload) {
30
- const iv = randomBytes(16);
31
- const c = createCipheriv('aes-256-gcm', this.key, iv);
32
- const data = Buffer.concat([c.update(payload, 'utf8'), c.final()]);
33
- return { iv: iv.toString('base64'), tag: c.getAuthTag().toString('base64'), data: data.toString('base64') };
34
- }
35
-
36
- async flush() {
37
- if (!this.exportUrl || !this.apiKey || this.queue.length === 0) return;
38
- const batch = this.queue.splice(0, this.queue.length);
39
- const body = JSON.stringify({ agent_id: this.agentId, count: batch.length, records: batch });
40
- const payload = JSON.stringify({ v: 1, agent_id: this.agentId, ...this._encrypt(body) });
41
- for (let attempt = 1; attempt <= 3; attempt++) {
42
- try { await this._post(payload); return; }
43
- catch (e) {
44
- if (attempt === 3) {
45
- this.queue.unshift(...batch);
46
- if (!this.silent) process.stderr.write(`[wma] export failed: ${e.message}\n`);
47
- return;
48
- }
49
- await new Promise(r => setTimeout(r, 1000 * 2 ** attempt));
50
- }
51
- }
52
- }
53
-
54
- _post(payload) {
55
- return new Promise((resolve, reject) => {
56
- let u; try { u = new URL(this.exportUrl); } catch (e) { return reject(e); }
57
- if (u.protocol !== 'https:') return reject(new Error('HTTPS only'));
58
- const req = request({
59
- host: u.hostname, port: u.port || 443, path: u.pathname + u.search,
60
- method: 'POST', rejectUnauthorized: true,
61
- headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload), 'X-WMA-Key': this.apiKey },
62
- }, res => {
63
- res.resume();
64
- if (res.statusCode >= 200 && res.statusCode < 300) resolve();
65
- else reject(new Error(`HTTP ${res.statusCode}`));
66
- });
67
- req.on('error', reject);
68
- req.write(payload); req.end();
69
- });
70
- }
71
- }
package/src/index.cjs DELETED
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- // CommonJS entrypoint — re-exports the ESM build via dynamic import.
4
- // All consumers receive the same singleton-backed API.
5
-
6
- const esmPromise = import('./index.js');
7
-
8
- function bind(name) {
9
- return async function (...args) {
10
- const mod = await esmPromise;
11
- return mod[name](...args);
12
- };
13
- }
14
-
15
- class WatchMyAgentsLazy {
16
- constructor(opts) {
17
- this._ready = esmPromise.then(mod => new mod.WatchMyAgents(opts));
18
- }
19
- async watch(...args) { return (await this._ready).watch(...args); }
20
- async logAction(...args) { return (await this._ready).logAction(...args); }
21
- async flush() { return (await this._ready).flush(); }
22
- async shutdown() { return (await this._ready).shutdown(); }
23
- get instance() { return this._ready; }
24
- }
25
-
26
- module.exports = WatchMyAgentsLazy;
27
- module.exports.default = WatchMyAgentsLazy;
28
- module.exports.WatchMyAgents = WatchMyAgentsLazy;
29
- module.exports.watch = bind('watch');
30
- module.exports.createGenericMonitor = bind('createGenericMonitor');
31
- module.exports.createClaudeMonitor = bind('createClaudeMonitor');
32
- module.exports.createOpenAIMonitor = bind('createOpenAIMonitor');
33
- module.exports.createLangChainHandler = bind('createLangChainHandler');
34
- module.exports.anonymize = bind('anonymize');
35
- module.exports.scrubString = bind('scrubString');
36
- module.exports.hashId = bind('hashId');
package/src/index.js DELETED
@@ -1,26 +0,0 @@
1
- import { WatchMyAgents } from './collector.js';
2
- import { watch, createGenericMonitor } from './adapters/generic.js';
3
- import { createClaudeMonitor } from './adapters/claude.js';
4
- import { createOpenAIMonitor } from './adapters/openai.js';
5
- import { createLangChainHandler } from './adapters/langchain.js';
6
- import { anonymize, scrubString, hashId } from './anonymizer.js';
7
- import { DEFAULT_PRICING, estimateCost, TokenTracker } from './tokens.js';
8
- import * as anthropicManaged from './sources/anthropic-managed.js';
9
-
10
- export {
11
- WatchMyAgents,
12
- watch,
13
- createGenericMonitor,
14
- createClaudeMonitor,
15
- createOpenAIMonitor,
16
- createLangChainHandler,
17
- anonymize,
18
- scrubString,
19
- hashId,
20
- DEFAULT_PRICING,
21
- estimateCost,
22
- TokenTracker,
23
- anthropicManaged,
24
- };
25
-
26
- export default WatchMyAgents;