opengauge 0.1.5 → 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.
- package/README.md +42 -0
- package/bin/opengauge.js +81 -14
- package/dist/cli/stats.d.ts +17 -0
- package/dist/cli/stats.d.ts.map +1 -0
- package/dist/cli/stats.js +286 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/core/circuit-breaker/index.d.ts +50 -0
- package/dist/core/circuit-breaker/index.d.ts.map +1 -0
- package/dist/core/circuit-breaker/index.js +168 -0
- package/dist/core/circuit-breaker/index.js.map +1 -0
- package/dist/core/cost/index.d.ts +41 -0
- package/dist/core/cost/index.d.ts.map +1 -0
- package/dist/core/cost/index.js +111 -0
- package/dist/core/cost/index.js.map +1 -0
- package/dist/core/index.d.ts +19 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +43 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/insights/index.d.ts +56 -0
- package/dist/core/insights/index.d.ts.map +1 -0
- package/dist/core/insights/index.js +239 -0
- package/dist/core/insights/index.js.map +1 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +87 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/db/session-queries.d.ts +145 -0
- package/dist/db/session-queries.d.ts.map +1 -0
- package/dist/db/session-queries.js +301 -0
- package/dist/db/session-queries.js.map +1 -0
- package/dist/plugins/openclaw/config.d.ts +24 -0
- package/dist/plugins/openclaw/config.d.ts.map +1 -0
- package/dist/plugins/openclaw/config.js +84 -0
- package/dist/plugins/openclaw/config.js.map +1 -0
- package/dist/plugins/openclaw/index.d.ts +39 -0
- package/dist/plugins/openclaw/index.d.ts.map +1 -0
- package/dist/plugins/openclaw/index.js +124 -0
- package/dist/plugins/openclaw/index.js.map +1 -0
- package/dist/plugins/openclaw/wrapped-provider.d.ts +67 -0
- package/dist/plugins/openclaw/wrapped-provider.d.ts.map +1 -0
- package/dist/plugins/openclaw/wrapped-provider.js +324 -0
- package/dist/plugins/openclaw/wrapped-provider.js.map +1 -0
- package/dist/proxy/providers.d.ts +26 -0
- package/dist/proxy/providers.d.ts.map +1 -0
- package/dist/proxy/providers.js +101 -0
- package/dist/proxy/providers.js.map +1 -0
- package/dist/proxy/server.d.ts +18 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +291 -0
- package/dist/proxy/server.js.map +1 -0
- package/dist/proxy/session-manager.d.ts +36 -0
- package/dist/proxy/session-manager.d.ts.map +1 -0
- package/dist/proxy/session-manager.js +117 -0
- package/dist/proxy/session-manager.js.map +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +4 -2
- package/dist/server/routes/index.js.map +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -76,6 +76,48 @@ npm start # Run CLI entry locally
|
|
|
76
76
|
npm pack --dry-run # Preview npm package contents
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
## Competitors and positioning
|
|
80
|
+
|
|
81
|
+
OpenGauge sits between chat UIs and full LLM observability suites.
|
|
82
|
+
|
|
83
|
+
### PromptOps / Observability tools
|
|
84
|
+
|
|
85
|
+
Examples: PromptLayer, Helicone, Langfuse, Humanloop, Arize Phoenix
|
|
86
|
+
|
|
87
|
+
- Great at: traces, eval pipelines, team dashboards, observability depth.
|
|
88
|
+
- OpenGauge advantage: local-first workflow, in-chat prompt improvement, duplicate-risk + token-efficiency feedback in one loop.
|
|
89
|
+
|
|
90
|
+
### Multi-model chat interfaces
|
|
91
|
+
|
|
92
|
+
Examples: LibreChat, Open WebUI, Chatbot UI, AnythingLLM
|
|
93
|
+
|
|
94
|
+
- Great at: broad chat UX and plugin ecosystems.
|
|
95
|
+
- OpenGauge advantage: prompt quality optimization is first-class (Improve + analytics), not only chat.
|
|
96
|
+
|
|
97
|
+
### IDE coding assistants
|
|
98
|
+
|
|
99
|
+
Examples: Continue and other IDE-native AI assistants
|
|
100
|
+
|
|
101
|
+
- Great at: deep coding workflows inside editors.
|
|
102
|
+
- OpenGauge advantage: model-agnostic PromptOps for any user (product, ops, research, support), not just coding.
|
|
103
|
+
|
|
104
|
+
### Cloud model platforms
|
|
105
|
+
|
|
106
|
+
Examples: Azure AI Studio, Vertex AI, Bedrock consoles
|
|
107
|
+
|
|
108
|
+
- Great at: enterprise governance and managed cloud workflows.
|
|
109
|
+
- OpenGauge advantage: fast setup, no cloud lock-in, supports local Ollama and cloud providers together.
|
|
110
|
+
|
|
111
|
+
### Why choose OpenGauge
|
|
112
|
+
|
|
113
|
+
- Improve prompts before send (optional Auto Improve mode)
|
|
114
|
+
- Measure quality, duplicates, and token efficiency after send
|
|
115
|
+
- Keep data local with SQLite and run quickly with `npx opengauge`
|
|
116
|
+
|
|
117
|
+
Positioning line:
|
|
118
|
+
|
|
119
|
+
> OpenGauge is PromptOps in the loop: improve prompt quality before send, measure impact after send, and reduce token waste continuously.
|
|
120
|
+
|
|
79
121
|
## License
|
|
80
122
|
|
|
81
123
|
MIT
|
package/bin/opengauge.js
CHANGED
|
@@ -1,18 +1,69 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* OpenGauge CLI
|
|
4
|
+
* OpenGauge CLI
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* npx opengauge
|
|
8
|
-
* npx opengauge
|
|
9
|
-
* npx opengauge
|
|
6
|
+
* Commands:
|
|
7
|
+
* npx opengauge Start the chat UI server
|
|
8
|
+
* npx opengauge stats Show analytics dashboard
|
|
9
|
+
* npx opengauge watch Start proxy watch mode
|
|
10
|
+
* npx opengauge --help Show help
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
|
-
const { createServer } = require('../dist/server/index');
|
|
13
|
-
|
|
14
13
|
async function main() {
|
|
15
14
|
const args = process.argv.slice(2);
|
|
15
|
+
const command = args[0];
|
|
16
|
+
|
|
17
|
+
// ---- stats command ----
|
|
18
|
+
if (command === 'stats') {
|
|
19
|
+
const { runStats } = require('../dist/cli/stats');
|
|
20
|
+
await runStats(args.slice(1));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ---- watch command ----
|
|
25
|
+
if (command === 'watch') {
|
|
26
|
+
const { startWatchProxy } = require('../dist/proxy/server');
|
|
27
|
+
let port = 4000;
|
|
28
|
+
let optimize = false;
|
|
29
|
+
let aggressiveness = 'conservative';
|
|
30
|
+
|
|
31
|
+
for (let i = 1; i < args.length; i++) {
|
|
32
|
+
if (args[i] === '--port' && args[i + 1]) {
|
|
33
|
+
port = parseInt(args[i + 1], 10);
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
if (args[i] === '--optimize') optimize = true;
|
|
37
|
+
if (args[i] && args[i].startsWith('--aggressiveness=')) {
|
|
38
|
+
aggressiveness = args[i].split('=')[1];
|
|
39
|
+
}
|
|
40
|
+
if (args[i] === '--help' || args[i] === '-h') {
|
|
41
|
+
console.log(`
|
|
42
|
+
OpenGauge Watch — Local proxy for observing LLM API traffic
|
|
43
|
+
|
|
44
|
+
Usage:
|
|
45
|
+
npx opengauge watch [options]
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--port <number> Port to run on (default: 4000)
|
|
49
|
+
--optimize Enable prompt optimization
|
|
50
|
+
--aggressiveness=<level> conservative | medium | aggressive (default: conservative)
|
|
51
|
+
--help, -h Show this help message
|
|
52
|
+
|
|
53
|
+
Examples:
|
|
54
|
+
ANTHROPIC_BASE_URL=http://localhost:4000 claude
|
|
55
|
+
OPENAI_BASE_URL=http://localhost:4000/v1 your-tool
|
|
56
|
+
`);
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
startWatchProxy({ port, optimize, aggressiveness });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---- Default: start chat UI server ----
|
|
66
|
+
const { createServer } = require('../dist/server/index');
|
|
16
67
|
|
|
17
68
|
let port = 3000;
|
|
18
69
|
let shouldOpen = true;
|
|
@@ -27,29 +78,45 @@ async function main() {
|
|
|
27
78
|
}
|
|
28
79
|
if (args[i] === '--help' || args[i] === '-h') {
|
|
29
80
|
console.log(`
|
|
30
|
-
OpenGauge —
|
|
81
|
+
OpenGauge — PromptOps observability platform
|
|
31
82
|
|
|
32
83
|
Usage:
|
|
33
|
-
npx opengauge [options]
|
|
84
|
+
npx opengauge [command] [options]
|
|
34
85
|
|
|
35
|
-
|
|
86
|
+
Commands:
|
|
87
|
+
(default) Start the chat UI server
|
|
88
|
+
stats Show analytics dashboard
|
|
89
|
+
watch Start proxy watch mode for IDE agents
|
|
90
|
+
|
|
91
|
+
Options (chat server):
|
|
36
92
|
--port <number> Port to run on (default: 3000)
|
|
37
93
|
--no-open Don't open browser automatically
|
|
38
94
|
--help, -h Show this help message
|
|
39
95
|
|
|
96
|
+
Stats options:
|
|
97
|
+
--period=<N>d|h|w|m Time period (e.g. 7d, 24h, 4w)
|
|
98
|
+
--model=<name> Filter by model
|
|
99
|
+
--source=<name> Filter by source (chat, openclaw, proxy)
|
|
100
|
+
--alerts Show active alerts only
|
|
101
|
+
--json Machine-readable JSON output
|
|
102
|
+
--compare Show optimization comparison
|
|
103
|
+
|
|
104
|
+
Watch options:
|
|
105
|
+
--port <number> Proxy port (default: 4000)
|
|
106
|
+
--optimize Enable prompt optimization
|
|
107
|
+
--aggressiveness=<l> conservative | medium | aggressive
|
|
108
|
+
|
|
40
109
|
Config:
|
|
41
110
|
~/.opengauge/config.yml Provider configuration
|
|
42
111
|
~/.opengauge/opengauge.db SQLite database
|
|
43
|
-
|
|
44
|
-
Homepage: https://github.com/opengauge/opengauge
|
|
45
112
|
`);
|
|
46
113
|
process.exit(0);
|
|
47
114
|
}
|
|
48
115
|
}
|
|
49
116
|
|
|
50
117
|
console.log(`
|
|
51
|
-
⚡ OpenGauge v0.
|
|
52
|
-
|
|
118
|
+
⚡ OpenGauge v0.2.0
|
|
119
|
+
PromptOps observability platform
|
|
53
120
|
`);
|
|
54
121
|
|
|
55
122
|
await createServer(port);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opengauge stats — Terminal analytics dashboard
|
|
3
|
+
*
|
|
4
|
+
* Reads the SQLite database and renders analytics to the terminal.
|
|
5
|
+
* Supports filtering by period, model, source, and output format.
|
|
6
|
+
*/
|
|
7
|
+
export interface StatsOptions {
|
|
8
|
+
period?: string;
|
|
9
|
+
model?: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
alerts?: boolean;
|
|
12
|
+
json?: boolean;
|
|
13
|
+
compare?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseStatsArgs(args: string[]): StatsOptions;
|
|
16
|
+
export declare function runStats(args: string[]): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/cli/stats.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAW3D;AAmCD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiL5D"}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* opengauge stats — Terminal analytics dashboard
|
|
4
|
+
*
|
|
5
|
+
* Reads the SQLite database and renders analytics to the terminal.
|
|
6
|
+
* Supports filtering by period, model, source, and output format.
|
|
7
|
+
*/
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.parseStatsArgs = parseStatsArgs;
|
|
13
|
+
exports.runStats = runStats;
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
16
|
+
const db_1 = require("../db");
|
|
17
|
+
const session_queries_1 = require("../db/session-queries");
|
|
18
|
+
const queries_1 = require("../db/queries");
|
|
19
|
+
function parseStatsArgs(args) {
|
|
20
|
+
const opts = {};
|
|
21
|
+
for (const arg of args) {
|
|
22
|
+
if (arg.startsWith('--period='))
|
|
23
|
+
opts.period = arg.split('=')[1];
|
|
24
|
+
else if (arg.startsWith('--model='))
|
|
25
|
+
opts.model = arg.split('=')[1];
|
|
26
|
+
else if (arg.startsWith('--source='))
|
|
27
|
+
opts.source = arg.split('=')[1];
|
|
28
|
+
else if (arg === '--alerts')
|
|
29
|
+
opts.alerts = true;
|
|
30
|
+
else if (arg === '--json')
|
|
31
|
+
opts.json = true;
|
|
32
|
+
else if (arg === '--compare')
|
|
33
|
+
opts.compare = true;
|
|
34
|
+
}
|
|
35
|
+
return opts;
|
|
36
|
+
}
|
|
37
|
+
function parsePeriod(period) {
|
|
38
|
+
if (!period)
|
|
39
|
+
return undefined;
|
|
40
|
+
const match = period.match(/^(\d+)(h|d|w|m)$/);
|
|
41
|
+
if (!match)
|
|
42
|
+
return undefined;
|
|
43
|
+
const val = parseInt(match[1], 10);
|
|
44
|
+
const unit = match[2];
|
|
45
|
+
const ms = { h: 3600000, d: 86400000, w: 604800000, m: 2592000000 };
|
|
46
|
+
return Date.now() - val * (ms[unit] || 86400000);
|
|
47
|
+
}
|
|
48
|
+
function formatCost(usd) {
|
|
49
|
+
if (usd < 0.01)
|
|
50
|
+
return `$${usd.toFixed(6)}`;
|
|
51
|
+
if (usd < 1)
|
|
52
|
+
return `$${usd.toFixed(4)}`;
|
|
53
|
+
return `$${usd.toFixed(2)}`;
|
|
54
|
+
}
|
|
55
|
+
function formatTokens(n) {
|
|
56
|
+
if (n >= 1_000_000)
|
|
57
|
+
return `${(n / 1_000_000).toFixed(1)}M`;
|
|
58
|
+
if (n >= 1_000)
|
|
59
|
+
return `${(n / 1_000).toFixed(1)}K`;
|
|
60
|
+
return String(n);
|
|
61
|
+
}
|
|
62
|
+
function formatDuration(startMs, endMs) {
|
|
63
|
+
const duration = (endMs || Date.now()) - startMs;
|
|
64
|
+
const mins = Math.floor(duration / 60000);
|
|
65
|
+
if (mins < 60)
|
|
66
|
+
return `${mins}m`;
|
|
67
|
+
const hours = Math.floor(mins / 60);
|
|
68
|
+
if (hours < 24)
|
|
69
|
+
return `${hours}h ${mins % 60}m`;
|
|
70
|
+
return `${Math.floor(hours / 24)}d ${hours % 24}h`;
|
|
71
|
+
}
|
|
72
|
+
// ---- Main stats command ----
|
|
73
|
+
async function runStats(args) {
|
|
74
|
+
const opts = parseStatsArgs(args);
|
|
75
|
+
const db = (0, db_1.getDb)();
|
|
76
|
+
const sq = new session_queries_1.SessionQueries(db);
|
|
77
|
+
const since = parsePeriod(opts.period);
|
|
78
|
+
if (opts.json) {
|
|
79
|
+
return runStatsJson(sq, opts, since);
|
|
80
|
+
}
|
|
81
|
+
if (opts.alerts) {
|
|
82
|
+
return renderAlerts(sq, since);
|
|
83
|
+
}
|
|
84
|
+
if (opts.compare) {
|
|
85
|
+
return renderComparison(sq, since);
|
|
86
|
+
}
|
|
87
|
+
// ---- Header ----
|
|
88
|
+
console.log();
|
|
89
|
+
console.log(chalk_1.default.bold.cyan(' OpenGauge Stats'));
|
|
90
|
+
console.log(chalk_1.default.dim(` ${opts.period ? `Last ${opts.period}` : 'All time'}${opts.source ? ` · source: ${opts.source}` : ''}${opts.model ? ` · model: ${opts.model}` : ''}`));
|
|
91
|
+
console.log();
|
|
92
|
+
// ---- Total Spend ----
|
|
93
|
+
const summary = sq.getSpendSummary(since, opts.source);
|
|
94
|
+
const spendTable = new cli_table3_1.default({
|
|
95
|
+
head: ['Metric', 'Value'].map(h => chalk_1.default.bold(h)),
|
|
96
|
+
style: { head: [], border: [] },
|
|
97
|
+
});
|
|
98
|
+
spendTable.push(['Total Spend', chalk_1.default.yellow(formatCost(summary.total_cost_usd))], ['Tokens In', formatTokens(summary.total_tokens_in)], ['Tokens Out', formatTokens(summary.total_tokens_out)], ['Tokens Saved', chalk_1.default.green(formatTokens(summary.total_tokens_saved))], ['Cost Saved', chalk_1.default.green(formatCost(summary.total_cost_saved_usd))], ['Sessions', String(summary.session_count)], ['API Calls', String(summary.interaction_count)]);
|
|
99
|
+
console.log(chalk_1.default.bold(' Total Spend'));
|
|
100
|
+
console.log(spendTable.toString());
|
|
101
|
+
console.log();
|
|
102
|
+
// ---- Spend by Source ----
|
|
103
|
+
const sources = ['chat', 'openclaw', 'proxy', 'log_ingest'];
|
|
104
|
+
const sourceRows = [];
|
|
105
|
+
for (const src of sources) {
|
|
106
|
+
const s = sq.getSpendSummary(since, src);
|
|
107
|
+
if (s.session_count > 0) {
|
|
108
|
+
sourceRows.push([src, formatCost(s.total_cost_usd), String(s.session_count), String(s.interaction_count)]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (sourceRows.length > 0) {
|
|
112
|
+
const sourceTable = new cli_table3_1.default({
|
|
113
|
+
head: ['Source', 'Spend', 'Sessions', 'Calls'].map(h => chalk_1.default.bold(h)),
|
|
114
|
+
style: { head: [], border: [] },
|
|
115
|
+
});
|
|
116
|
+
sourceTable.push(...sourceRows);
|
|
117
|
+
console.log(chalk_1.default.bold(' Spend by Source'));
|
|
118
|
+
console.log(sourceTable.toString());
|
|
119
|
+
console.log();
|
|
120
|
+
}
|
|
121
|
+
// ---- Model Distribution ----
|
|
122
|
+
const models = sq.getModelUsage(since);
|
|
123
|
+
if (models.length > 0) {
|
|
124
|
+
const modelTable = new cli_table3_1.default({
|
|
125
|
+
head: ['Provider', 'Model', 'Spend', 'Tokens In', 'Tokens Out', 'Sessions'].map(h => chalk_1.default.bold(h)),
|
|
126
|
+
style: { head: [], border: [] },
|
|
127
|
+
});
|
|
128
|
+
for (const m of models.slice(0, 10)) {
|
|
129
|
+
modelTable.push([
|
|
130
|
+
m.provider, m.model,
|
|
131
|
+
chalk_1.default.yellow(formatCost(m.total_cost_usd)),
|
|
132
|
+
formatTokens(m.total_tokens_in),
|
|
133
|
+
formatTokens(m.total_tokens_out),
|
|
134
|
+
String(m.session_count),
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
console.log(chalk_1.default.bold(' Model Distribution'));
|
|
138
|
+
console.log(modelTable.toString());
|
|
139
|
+
console.log();
|
|
140
|
+
}
|
|
141
|
+
// ---- Daily Spend Trend ----
|
|
142
|
+
const daily = sq.getDailySpend(opts.period ? parseInt(opts.period) || 7 : 7);
|
|
143
|
+
if (daily.length > 0) {
|
|
144
|
+
const dailyTable = new cli_table3_1.default({
|
|
145
|
+
head: ['Date', 'Spend', 'Tokens', 'Sessions'].map(h => chalk_1.default.bold(h)),
|
|
146
|
+
style: { head: [], border: [] },
|
|
147
|
+
});
|
|
148
|
+
for (const d of daily.slice(0, 14)) {
|
|
149
|
+
dailyTable.push([
|
|
150
|
+
d.day,
|
|
151
|
+
chalk_1.default.yellow(formatCost(d.cost_usd)),
|
|
152
|
+
formatTokens(d.tokens_in + d.tokens_out),
|
|
153
|
+
String(d.sessions),
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
156
|
+
console.log(chalk_1.default.bold(' Daily Spend'));
|
|
157
|
+
console.log(dailyTable.toString());
|
|
158
|
+
console.log();
|
|
159
|
+
}
|
|
160
|
+
// ---- Top Sessions by Cost ----
|
|
161
|
+
const topSessions = sq.getTopSessionsByCost(5, since);
|
|
162
|
+
if (topSessions.length > 0) {
|
|
163
|
+
const sessionTable = new cli_table3_1.default({
|
|
164
|
+
head: ['Source', 'Model', 'Cost', 'Calls', 'Duration'].map(h => chalk_1.default.bold(h)),
|
|
165
|
+
style: { head: [], border: [] },
|
|
166
|
+
});
|
|
167
|
+
for (const s of topSessions) {
|
|
168
|
+
sessionTable.push([
|
|
169
|
+
s.source,
|
|
170
|
+
s.model,
|
|
171
|
+
chalk_1.default.yellow(formatCost(s.total_cost_usd)),
|
|
172
|
+
String(s.interaction_count),
|
|
173
|
+
formatDuration(s.started_at, s.ended_at),
|
|
174
|
+
]);
|
|
175
|
+
}
|
|
176
|
+
console.log(chalk_1.default.bold(' Top Sessions by Cost'));
|
|
177
|
+
console.log(sessionTable.toString());
|
|
178
|
+
console.log();
|
|
179
|
+
}
|
|
180
|
+
// ---- Circuit Breaker Activity ----
|
|
181
|
+
const alertSummary = sq.getAlertSummary(since);
|
|
182
|
+
if (alertSummary.length > 0) {
|
|
183
|
+
const alertTable = new cli_table3_1.default({
|
|
184
|
+
head: ['Type', 'Severity', 'Count'].map(h => chalk_1.default.bold(h)),
|
|
185
|
+
style: { head: [], border: [] },
|
|
186
|
+
});
|
|
187
|
+
for (const a of alertSummary) {
|
|
188
|
+
const severityColor = a.severity === 'critical' ? chalk_1.default.red : a.severity === 'warning' ? chalk_1.default.yellow : chalk_1.default.dim;
|
|
189
|
+
alertTable.push([a.alert_type, severityColor(a.severity), String(a.count)]);
|
|
190
|
+
}
|
|
191
|
+
console.log(chalk_1.default.bold(' Circuit Breaker Activity'));
|
|
192
|
+
console.log(alertTable.toString());
|
|
193
|
+
console.log();
|
|
194
|
+
}
|
|
195
|
+
// ---- Active Alerts ----
|
|
196
|
+
const activeAlerts = sq.queryAlerts({ dismissed: false, limit: 5, since });
|
|
197
|
+
if (activeAlerts.length > 0) {
|
|
198
|
+
console.log(chalk_1.default.bold(' Active Alerts'));
|
|
199
|
+
for (const alert of activeAlerts) {
|
|
200
|
+
const icon = alert.severity === 'critical' ? chalk_1.default.red('!!') : alert.severity === 'warning' ? chalk_1.default.yellow('!!') : chalk_1.default.dim('i');
|
|
201
|
+
console.log(` ${icon} [${alert.alert_type}] ${alert.message}`);
|
|
202
|
+
}
|
|
203
|
+
console.log();
|
|
204
|
+
}
|
|
205
|
+
// ---- Also include legacy chat UI stats ----
|
|
206
|
+
try {
|
|
207
|
+
const legacyQueries = new queries_1.Queries(db);
|
|
208
|
+
const legacyUsage = legacyQueries.getAggregatedTokenUsage();
|
|
209
|
+
if (legacyUsage.length > 0) {
|
|
210
|
+
const legacyTable = new cli_table3_1.default({
|
|
211
|
+
head: ['Provider', 'Model', 'Tokens In', 'Tokens Out', 'Saved', 'Requests'].map(h => chalk_1.default.bold(h)),
|
|
212
|
+
style: { head: [], border: [] },
|
|
213
|
+
});
|
|
214
|
+
for (const u of legacyUsage) {
|
|
215
|
+
legacyTable.push([
|
|
216
|
+
u.provider, u.model,
|
|
217
|
+
formatTokens(u.total_tokens_in),
|
|
218
|
+
formatTokens(u.total_tokens_out),
|
|
219
|
+
chalk_1.default.green(formatTokens(u.total_tokens_saved)),
|
|
220
|
+
String(u.request_count),
|
|
221
|
+
]);
|
|
222
|
+
}
|
|
223
|
+
console.log(chalk_1.default.bold(' Chat UI Usage (legacy)'));
|
|
224
|
+
console.log(legacyTable.toString());
|
|
225
|
+
console.log();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
// Legacy tables may not exist
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// ---- JSON output ----
|
|
233
|
+
function runStatsJson(sq, opts, since) {
|
|
234
|
+
const output = {
|
|
235
|
+
summary: sq.getSpendSummary(since, opts.source),
|
|
236
|
+
models: sq.getModelUsage(since),
|
|
237
|
+
daily: sq.getDailySpend(7),
|
|
238
|
+
topSessions: sq.getTopSessionsByCost(5, since),
|
|
239
|
+
alerts: sq.queryAlerts({ dismissed: false, limit: 20, since }),
|
|
240
|
+
alertSummary: sq.getAlertSummary(since),
|
|
241
|
+
};
|
|
242
|
+
console.log(JSON.stringify(output, null, 2));
|
|
243
|
+
}
|
|
244
|
+
// ---- Alerts view ----
|
|
245
|
+
function renderAlerts(sq, since) {
|
|
246
|
+
const alerts = sq.queryAlerts({ dismissed: false, since, limit: 50 });
|
|
247
|
+
console.log();
|
|
248
|
+
console.log(chalk_1.default.bold.cyan(' OpenGauge Alerts'));
|
|
249
|
+
console.log();
|
|
250
|
+
if (alerts.length === 0) {
|
|
251
|
+
console.log(chalk_1.default.green(' No active alerts.'));
|
|
252
|
+
console.log();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
for (const alert of alerts) {
|
|
256
|
+
const icon = alert.severity === 'critical' ? chalk_1.default.red.bold('CRITICAL')
|
|
257
|
+
: alert.severity === 'warning' ? chalk_1.default.yellow.bold('WARNING')
|
|
258
|
+
: chalk_1.default.dim('INFO');
|
|
259
|
+
const time = new Date(alert.created_at).toLocaleString();
|
|
260
|
+
console.log(` ${icon} ${chalk_1.default.bold(alert.alert_type)}`);
|
|
261
|
+
console.log(` ${alert.message}`);
|
|
262
|
+
console.log(chalk_1.default.dim(` ${time} session: ${alert.session_id.slice(0, 8)}...`));
|
|
263
|
+
console.log();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// ---- Comparison view (A/B optimization) ----
|
|
267
|
+
function renderComparison(sq, since) {
|
|
268
|
+
const summary = sq.getSpendSummary(since);
|
|
269
|
+
console.log();
|
|
270
|
+
console.log(chalk_1.default.bold.cyan(' OpenGauge Optimization Comparison'));
|
|
271
|
+
console.log();
|
|
272
|
+
if (summary.interaction_count === 0) {
|
|
273
|
+
console.log(chalk_1.default.dim(' No data available.'));
|
|
274
|
+
console.log();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const actualSpend = summary.total_cost_usd;
|
|
278
|
+
const savedAmount = summary.total_cost_saved_usd;
|
|
279
|
+
const optimizedSpend = actualSpend - savedAmount;
|
|
280
|
+
const savingsPercent = actualSpend > 0 ? (savedAmount / actualSpend) * 100 : 0;
|
|
281
|
+
console.log(` ${chalk_1.default.bold('API calls observed:')} ${summary.interaction_count}`);
|
|
282
|
+
console.log(` ${chalk_1.default.bold('Actual spend:')} ${chalk_1.default.yellow(formatCost(actualSpend))}`);
|
|
283
|
+
console.log(` ${chalk_1.default.bold('Optimized spend:')} ${chalk_1.default.green(formatCost(optimizedSpend))} ${chalk_1.default.green(`(saved ${formatCost(savedAmount)} / ${savingsPercent.toFixed(1)}%)`)}`);
|
|
284
|
+
console.log();
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/cli/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opengauge/core — Circuit Breaker
|
|
3
|
+
*
|
|
4
|
+
* Detects runaway loops in LLM agent interactions using trigram Jaccard similarity.
|
|
5
|
+
* Pure functions — takes an array of recent interactions and returns a verdict.
|
|
6
|
+
* No DB dependency at call time.
|
|
7
|
+
*/
|
|
8
|
+
export interface Interaction {
|
|
9
|
+
role: 'user' | 'assistant' | 'system';
|
|
10
|
+
content: string;
|
|
11
|
+
timestamp?: number;
|
|
12
|
+
}
|
|
13
|
+
export type Verdict = 'ok' | 'warning' | 'trip';
|
|
14
|
+
export interface CircuitBreakerResult {
|
|
15
|
+
verdict: Verdict;
|
|
16
|
+
reason: string;
|
|
17
|
+
/** Highest pairwise similarity found among recent interactions */
|
|
18
|
+
peakSimilarity: number;
|
|
19
|
+
/** Number of near-duplicate pairs detected */
|
|
20
|
+
duplicatePairCount: number;
|
|
21
|
+
/** Cluster size of the largest group of similar messages */
|
|
22
|
+
largestClusterSize: number;
|
|
23
|
+
}
|
|
24
|
+
export interface CircuitBreakerConfig {
|
|
25
|
+
/** Similarity threshold to consider two messages near-duplicates (0-1). Default: 0.85 */
|
|
26
|
+
similarityThreshold?: number;
|
|
27
|
+
/** Number of duplicate pairs that triggers a warning. Default: 3 */
|
|
28
|
+
warningPairCount?: number;
|
|
29
|
+
/** Number of duplicate pairs that trips the breaker. Default: 6 */
|
|
30
|
+
tripPairCount?: number;
|
|
31
|
+
/** Minimum cluster size to trip. Default: 4 */
|
|
32
|
+
tripClusterSize?: number;
|
|
33
|
+
/** Only consider messages within this time window (ms). 0 = no limit. Default: 0 */
|
|
34
|
+
timeWindowMs?: number;
|
|
35
|
+
/** Only analyze assistant messages (typical for runaway agent detection). Default: false */
|
|
36
|
+
assistantOnly?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Jaccard similarity between two trigram sets: |A ∩ B| / |A ∪ B|
|
|
40
|
+
*/
|
|
41
|
+
declare function trigramJaccard(a: string, b: string): number;
|
|
42
|
+
/**
|
|
43
|
+
* Check a sequence of recent interactions for runaway loop patterns.
|
|
44
|
+
*
|
|
45
|
+
* Pure function — no side effects, no DB access.
|
|
46
|
+
* Pass in the most recent N interactions (e.g. last 20-50 messages from an agent session).
|
|
47
|
+
*/
|
|
48
|
+
export declare function checkRunawayLoop(recentInteractions: Interaction[], config?: CircuitBreakerConfig): CircuitBreakerResult;
|
|
49
|
+
export { trigramJaccard };
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/circuit-breaker/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,yFAAyF;IACzF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4FAA4F;IAC5F,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA2BD;;GAEG;AACH,iBAAS,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAepD;AAkDD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,kBAAkB,EAAE,WAAW,EAAE,EACjC,MAAM,CAAC,EAAE,oBAAoB,GAC5B,oBAAoB,CA4EtB;AAGD,OAAO,EAAE,cAAc,EAAE,CAAC"}
|