@opengauge/openclaw-plugin 0.1.2 → 0.1.4

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/index.d.ts CHANGED
@@ -1,30 +1,29 @@
1
1
  /**
2
2
  * @opengauge/openclaw-plugin
3
3
  *
4
- * OpenClaw plugin that wraps every LLM provider call via registerProvider,
4
+ * OpenClaw plugin that observes every LLM call via hooks (llm_input / llm_output),
5
5
  * logging every individual API call to @opengauge/core's SQLite database.
6
6
  *
7
7
  * Features:
8
8
  * - Per-call cost tracking
9
- * - Runaway loop detection (circuit breaker)
10
- * - Budget enforcement (session/daily/monthly)
9
+ * - Runaway loop detection (circuit breaker alerts)
10
+ * - Budget enforcement alerts (session/daily/monthly)
11
11
  * - Fail-safe: never crashes the agent
12
12
  *
13
13
  * Install: openclaw plugins install @opengauge/openclaw-plugin
14
14
  */
15
- import { type OpenClawProvider } from './wrapped-provider';
16
- /**
17
- * OpenClaw plugin API interface (minimal — matches registerProvider + registerCommand).
18
- */
19
15
  interface OpenClawPluginAPI {
20
- registerProvider(provider: any): void;
21
- registerCommand?(name: string, handler: (args: string[]) => Promise<string | void>): void;
22
- getProvider?(): OpenClawProvider;
23
- on?(event: string, handler: (...args: any[]) => void): void;
16
+ on(hookName: string, handler: (...args: any[]) => void | Promise<void>, opts?: any): void;
17
+ registerCommand?(command: any): void;
18
+ registerProvider?(provider: any): void;
19
+ logger?: {
20
+ info(msg: string): void;
21
+ warn(msg: string): void;
22
+ error(msg: string): void;
23
+ debug(msg: string): void;
24
+ };
25
+ [key: string]: any;
24
26
  }
25
- /**
26
- * Plugin entry point — called by OpenClaw when the plugin is loaded.
27
- */
28
27
  export declare function register(api: OpenClawPluginAPI): void;
29
28
  /**
30
29
  * Plugin metadata for OpenClaw's plugin system.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG5E;;GAEG;AACH,UAAU,iBAAiB;IACzB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,eAAe,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1F,WAAW,CAAC,IAAI,gBAAgB,CAAC;IACjC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CAC7D;AAID;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA8DrD;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;CAMpB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA8CH,UAAU,iBAAiB;IACzB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAC1F,eAAe,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;IACrC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC;IACvC,MAAM,CAAC,EAAE;QACP,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AA8HD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA6FrD;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;CAMpB,CAAC"}
package/dist/index.js CHANGED
@@ -2,13 +2,13 @@
2
2
  /**
3
3
  * @opengauge/openclaw-plugin
4
4
  *
5
- * OpenClaw plugin that wraps every LLM provider call via registerProvider,
5
+ * OpenClaw plugin that observes every LLM call via hooks (llm_input / llm_output),
6
6
  * logging every individual API call to @opengauge/core's SQLite database.
7
7
  *
8
8
  * Features:
9
9
  * - Per-call cost tracking
10
- * - Runaway loop detection (circuit breaker)
11
- * - Budget enforcement (session/daily/monthly)
10
+ * - Runaway loop detection (circuit breaker alerts)
11
+ * - Budget enforcement alerts (session/daily/monthly)
12
12
  * - Fail-safe: never crashes the agent
13
13
  *
14
14
  * Install: openclaw plugins install @opengauge/openclaw-plugin
@@ -17,61 +17,184 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.metadata = void 0;
18
18
  exports.register = register;
19
19
  const core_1 = require("opengauge/core");
20
- const wrapped_provider_1 = require("./wrapped-provider");
21
20
  const config_1 = require("./config");
22
- let wrappedProvider = null;
23
- /**
24
- * Plugin entry point — called by OpenClaw when the plugin is loaded.
25
- */
21
+ /* ------------------------------------------------------------------ */
22
+ /* Plugin core */
23
+ /* ------------------------------------------------------------------ */
24
+ let queries = null;
25
+ let config;
26
+ let session = null;
27
+ const inFlight = new Map();
28
+ function ensureSession(model, provider) {
29
+ const now = Date.now();
30
+ if (session && (now - session.lastCallTimestamp) > config.session_timeout_ms) {
31
+ try {
32
+ queries?.finalizeSession(session.sessionId);
33
+ }
34
+ catch (e) {
35
+ (0, config_1.logError)(e);
36
+ }
37
+ session = null;
38
+ }
39
+ if (!session) {
40
+ try {
41
+ const record = queries.createSession('openclaw', model, provider);
42
+ session = {
43
+ sessionId: record.id,
44
+ interactionCount: 0,
45
+ runningCostUsd: 0,
46
+ lastCallTimestamp: now,
47
+ recentInteractions: [],
48
+ contextDepthTokens: 0,
49
+ };
50
+ }
51
+ catch (e) {
52
+ (0, config_1.logError)(e);
53
+ session = {
54
+ sessionId: `fallback-${now}`,
55
+ interactionCount: 0,
56
+ runningCostUsd: 0,
57
+ lastCallTimestamp: now,
58
+ recentInteractions: [],
59
+ contextDepthTokens: 0,
60
+ };
61
+ }
62
+ }
63
+ return session;
64
+ }
65
+ function runChecks(sess, logger) {
66
+ // Circuit breaker (warn only — hooks can't block calls)
67
+ if (config.circuit_breaker.enabled) {
68
+ try {
69
+ const verdict = (0, core_1.checkRunawayLoop)(sess.recentInteractions, {
70
+ similarityThreshold: config.circuit_breaker.similarity_threshold,
71
+ tripPairCount: config.circuit_breaker.max_similar_calls,
72
+ warningPairCount: Math.max(2, config.circuit_breaker.max_similar_calls - 2),
73
+ });
74
+ if (verdict.verdict === 'trip' || verdict.verdict === 'warning') {
75
+ const severity = verdict.verdict === 'trip' ? 'critical' : 'warning';
76
+ const msg = verdict.verdict === 'trip'
77
+ ? `OpenGauge circuit breaker: ${verdict.reason}. Session cost: $${sess.runningCostUsd.toFixed(2)}.`
78
+ : `OpenGauge warning: ${verdict.reason}`;
79
+ queries?.writeAlert(sess.sessionId, 'runaway_loop', severity, msg, {
80
+ ...verdict,
81
+ sessionCost: sess.runningCostUsd,
82
+ });
83
+ if (logger)
84
+ logger.warn(msg);
85
+ }
86
+ }
87
+ catch (e) {
88
+ (0, config_1.logError)(e);
89
+ }
90
+ }
91
+ // Budget checks
92
+ try {
93
+ if (sess.runningCostUsd >= config.budget.session_limit_usd) {
94
+ const msg = `OpenGauge budget: Session cost ($${sess.runningCostUsd.toFixed(2)}) exceeds limit ($${config.budget.session_limit_usd.toFixed(2)}).`;
95
+ queries?.writeAlert(sess.sessionId, 'budget_breach', 'critical', msg, {
96
+ sessionCost: sess.runningCostUsd,
97
+ limit: config.budget.session_limit_usd,
98
+ });
99
+ if (logger)
100
+ logger.warn(msg);
101
+ }
102
+ const todayStart = new Date();
103
+ todayStart.setHours(0, 0, 0, 0);
104
+ const summary = queries?.getSpendSummary(todayStart.getTime(), 'openclaw');
105
+ if (summary && summary.total_cost_usd >= config.budget.daily_limit_usd) {
106
+ const msg = `OpenGauge budget: Daily spend ($${summary.total_cost_usd.toFixed(2)}) exceeds limit ($${config.budget.daily_limit_usd.toFixed(2)}).`;
107
+ queries?.writeAlert(sess.sessionId, 'budget_breach', 'critical', msg, {
108
+ dailyCost: summary.total_cost_usd,
109
+ limit: config.budget.daily_limit_usd,
110
+ });
111
+ if (logger)
112
+ logger.warn(msg);
113
+ }
114
+ }
115
+ catch (e) {
116
+ (0, config_1.logError)(e);
117
+ }
118
+ }
119
+ /* ------------------------------------------------------------------ */
120
+ /* Plugin entry point */
121
+ /* ------------------------------------------------------------------ */
26
122
  function register(api) {
27
123
  try {
28
- // Initialize database
29
124
  const db = (0, core_1.getDb)();
30
125
  (0, core_1.initSchema)(db);
31
- const config = (0, config_1.loadPluginConfig)();
32
- // Get the current provider and wrap it
33
- const realProvider = api.getProvider?.();
34
- if (!realProvider) {
35
- (0, config_1.logError)(new Error('OpenGauge: Could not get current provider from OpenClaw API'));
36
- return;
37
- }
38
- wrappedProvider = new wrapped_provider_1.WrappedProvider(realProvider, config);
39
- // Register the wrapped provider
40
- api.registerProvider(wrappedProvider);
41
- // Register optional stats command
42
- if (api.registerCommand) {
43
- api.registerCommand('opengauge-stats', async (args) => {
126
+ queries = new core_1.SessionQueries(db);
127
+ config = (0, config_1.loadPluginConfig)();
128
+ // --- llm_input: track when a call starts ---
129
+ api.on('llm_input', (event, _ctx) => {
130
+ try {
131
+ inFlight.set(event.runId, {
132
+ runId: event.runId,
133
+ provider: event.provider,
134
+ model: event.model,
135
+ prompt: event.prompt || '',
136
+ startTime: Date.now(),
137
+ });
138
+ }
139
+ catch (e) {
140
+ (0, config_1.logError)(e);
141
+ }
142
+ });
143
+ // --- llm_output: log the completed call ---
144
+ api.on('llm_output', (event, _ctx) => {
145
+ try {
146
+ const call = inFlight.get(event.runId);
147
+ inFlight.delete(event.runId);
148
+ const provider = event.provider || call?.provider || 'unknown';
149
+ const model = event.model || call?.model || 'unknown';
150
+ const prompt = call?.prompt || '';
151
+ const startTime = call?.startTime || Date.now();
152
+ const latencyMs = Date.now() - startTime;
153
+ const tokensIn = event.usage?.input_tokens || event.usage?.prompt_tokens || 0;
154
+ const tokensOut = event.usage?.output_tokens || event.usage?.completion_tokens || 0;
155
+ const costEstimate = (0, core_1.calculateCost)(provider, model, tokensIn, tokensOut);
156
+ const sess = ensureSession(model, provider);
157
+ sess.interactionCount++;
158
+ sess.runningCostUsd += costEstimate.totalCost;
159
+ sess.lastCallTimestamp = Date.now();
160
+ sess.contextDepthTokens += tokensIn;
161
+ const responseText = event.assistantTexts?.join('\n') || '';
162
+ sess.recentInteractions.push({ role: 'user', content: prompt, timestamp: startTime }, { role: 'assistant', content: responseText, timestamp: Date.now() });
163
+ if (sess.recentInteractions.length > 40) {
164
+ sess.recentInteractions = sess.recentInteractions.slice(-40);
165
+ }
166
+ // Write interaction
167
+ queries?.writeInteraction(sess.sessionId, sess.interactionCount, model, {
168
+ originalPrompt: prompt,
169
+ responseText: config.log_response_text ? responseText : undefined,
170
+ tokensIn,
171
+ tokensOut,
172
+ costUsd: costEstimate.totalCost,
173
+ latencyMs,
174
+ contextDepthTokens: sess.contextDepthTokens,
175
+ });
176
+ // Update session aggregates
177
+ queries?.updateSessionAggregates(sess.sessionId, tokensIn, tokensOut, costEstimate.totalCost);
178
+ // Run circuit breaker + budget checks
179
+ runChecks(sess, api.logger);
180
+ }
181
+ catch (e) {
182
+ (0, config_1.logError)(e);
183
+ }
184
+ });
185
+ // --- gateway_stop: finalize session ---
186
+ api.on('gateway_stop', () => {
187
+ if (session) {
44
188
  try {
45
- const queries = new core_1.SessionQueries((0, core_1.getDb)());
46
- const summary = queries.getSpendSummary();
47
- const alerts = queries.queryAlerts({ dismissed: false, limit: 5 });
48
- const lines = [
49
- '--- OpenGauge Stats ---',
50
- `Sessions: ${summary.session_count}`,
51
- `Total spend: $${summary.total_cost_usd.toFixed(4)}`,
52
- `Tokens: ${summary.total_tokens_in.toLocaleString()} in / ${summary.total_tokens_out.toLocaleString()} out`,
53
- `Tokens saved: ${summary.total_tokens_saved.toLocaleString()}`,
54
- ];
55
- if (alerts.length > 0) {
56
- lines.push('', '--- Active Alerts ---');
57
- for (const alert of alerts) {
58
- lines.push(`[${alert.severity.toUpperCase()}] ${alert.alert_type}: ${alert.message}`);
59
- }
60
- }
61
- return lines.join('\n');
189
+ queries?.finalizeSession(session.sessionId);
62
190
  }
63
191
  catch (e) {
64
192
  (0, config_1.logError)(e);
65
- return 'OpenGauge: Failed to fetch stats. Check ~/.opengauge/error.log';
66
193
  }
67
- });
68
- }
69
- // Listen for shutdown to finalize session
70
- if (api.on) {
71
- api.on('gateway_stop', () => {
72
- wrappedProvider?.shutdown();
73
- });
74
- }
194
+ session = null;
195
+ }
196
+ });
197
+ api.logger?.info('OpenGauge plugin loaded — observing LLM calls');
75
198
  }
76
199
  catch (error) {
77
200
  // Fail-safe: plugin must never crash OpenClaw
@@ -84,7 +207,7 @@ function register(api) {
84
207
  exports.metadata = {
85
208
  name: '@opengauge/openclaw-plugin',
86
209
  npm: '@opengauge/openclaw-plugin',
87
- version: '0.1.0',
210
+ version: '0.1.4',
88
211
  description: 'Cost tracking, runaway loop detection, and budget enforcement for OpenClaw agents',
89
212
  author: 'OpenGauge',
90
213
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAqBH,4BA8DC;AAjFD,yCAAmE;AACnE,yDAA4E;AAC5E,qCAAsD;AAYtD,IAAI,eAAe,GAA2B,IAAI,CAAC;AAEnD;;GAEG;AACH,SAAgB,QAAQ,CAAC,GAAsB;IAC7C,IAAI,CAAC;QACH,sBAAsB;QACtB,MAAM,EAAE,GAAG,IAAA,YAAK,GAAE,CAAC;QACnB,IAAA,iBAAU,EAAC,EAAE,CAAC,CAAC;QAEf,MAAM,MAAM,GAAG,IAAA,yBAAgB,GAAE,CAAC;QAElC,uCAAuC;QACvC,MAAM,YAAY,GAAG,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,IAAA,iBAAQ,EAAC,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC,CAAC;YACnF,OAAO;QACT,CAAC;QAED,eAAe,GAAG,IAAI,kCAAe,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAE5D,gCAAgC;QAChC,GAAG,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;QAEtC,kCAAkC;QAClC,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;YACxB,GAAG,CAAC,eAAe,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAAc,EAAE,EAAE;gBAC9D,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,IAAI,qBAAc,CAAC,IAAA,YAAK,GAAE,CAAC,CAAC;oBAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;oBAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;oBAEnE,MAAM,KAAK,GAAa;wBACtB,yBAAyB;wBACzB,aAAa,OAAO,CAAC,aAAa,EAAE;wBACpC,iBAAiB,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;wBACpD,WAAW,OAAO,CAAC,eAAe,CAAC,cAAc,EAAE,SAAS,OAAO,CAAC,gBAAgB,CAAC,cAAc,EAAE,MAAM;wBAC3G,iBAAiB,OAAO,CAAC,kBAAkB,CAAC,cAAc,EAAE,EAAE;qBAC/D,CAAC;oBAEF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACtB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC;wBACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;4BAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;wBACxF,CAAC;oBACH,CAAC;oBAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAA,iBAAQ,EAAC,CAAC,CAAC,CAAC;oBACZ,OAAO,gEAAgE,CAAC;gBAC1E,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,0CAA0C;QAC1C,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,GAAG,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;gBAC1B,eAAe,EAAE,QAAQ,EAAE,CAAC;YAC9B,CAAC,CAAC,CAAC;QACL,CAAC;IAEH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,8CAA8C;QAC9C,IAAA,iBAAQ,EAAC,KAAK,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACU,QAAA,QAAQ,GAAG;IACtB,IAAI,EAAE,4BAA4B;IAClC,GAAG,EAAE,4BAA4B;IACjC,OAAO,EAAE,OAAO;IAChB,WAAW,EAAE,mFAAmF;IAChG,MAAM,EAAE,WAAW;CACpB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,20 @@
1
1
  {
2
- "name": "@opengauge/openclaw-plugin",
3
- "version": "0.1.0",
4
- "description": "PromptOps observability for OpenClaw: per-call cost tracking, runaway loop detection, circuit breaker, and budget enforcement",
5
- "author": "OpenGauge / Vega IoT",
6
- "license": "MIT",
7
- "entry": "dist/index.js",
8
- "capabilities": ["registerProvider", "registerCommand"],
9
- "config_schema": {
10
- "circuit_breaker.enabled": { "type": "boolean", "default": true },
11
- "circuit_breaker.similarity_threshold": { "type": "number", "default": 0.8 },
12
- "circuit_breaker.max_similar_calls": { "type": "number", "default": 5 },
13
- "circuit_breaker.action": { "type": "string", "enum": ["warn", "block"], "default": "warn" },
14
- "budget.session_limit_usd": { "type": "number", "default": 5.0 },
15
- "budget.daily_limit_usd": { "type": "number", "default": 20.0 },
16
- "budget.monthly_limit_usd": { "type": "number", "default": 400.0 },
17
- "optimize": { "type": "boolean", "default": false }
18
- },
19
- "keywords": ["observability", "cost-tracking", "circuit-breaker", "promptops"]
2
+ "id": "opengauge",
3
+ "name": "OpenGauge",
4
+ "description": "PromptOps observability: per-call cost tracking, runaway loop detection, circuit breaker, and budget enforcement",
5
+ "version": "0.1.2",
6
+ "configSchema": {
7
+ "type": "object",
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "circuit_breaker_enabled": { "type": "boolean" },
11
+ "circuit_breaker_similarity_threshold": { "type": "number" },
12
+ "circuit_breaker_max_similar_calls": { "type": "number" },
13
+ "circuit_breaker_action": { "type": "string", "enum": ["warn", "block"] },
14
+ "budget_session_limit_usd": { "type": "number" },
15
+ "budget_daily_limit_usd": { "type": "number" },
16
+ "budget_monthly_limit_usd": { "type": "number" },
17
+ "optimize": { "type": "boolean" }
18
+ }
19
+ }
20
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengauge/openclaw-plugin",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "PromptOps observability for OpenClaw: per-call cost tracking, runaway loop detection, circuit breaker, and budget enforcement",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,66 +0,0 @@
1
- import { OpenClawPluginConfig } from './config';
2
- /**
3
- * OpenClaw provider interface (minimal — matches what registerProvider expects).
4
- */
5
- export interface OpenClawProviderRequest {
6
- messages: Array<{
7
- role: string;
8
- content: string;
9
- }>;
10
- model?: string;
11
- max_tokens?: number;
12
- temperature?: number;
13
- stream?: boolean;
14
- [key: string]: any;
15
- }
16
- export interface OpenClawProviderResponse {
17
- content: string;
18
- model: string;
19
- usage?: {
20
- input_tokens?: number;
21
- output_tokens?: number;
22
- prompt_tokens?: number;
23
- completion_tokens?: number;
24
- };
25
- [key: string]: any;
26
- }
27
- export interface OpenClawProvider {
28
- name: string;
29
- defaultModel?: string;
30
- chat(request: OpenClawProviderRequest): Promise<OpenClawProviderResponse>;
31
- chatStream?(request: OpenClawProviderRequest): AsyncIterable<any>;
32
- }
33
- export declare class WrappedProvider {
34
- private realProvider;
35
- private config;
36
- private queries;
37
- private session;
38
- constructor(realProvider: OpenClawProvider, config: OpenClawPluginConfig);
39
- get name(): string;
40
- get defaultModel(): string | undefined;
41
- /**
42
- * Ensure we have an active session, creating one if needed or if timed out.
43
- */
44
- private ensureSession;
45
- /**
46
- * Run circuit breaker checks. Returns a block message if the call should be stopped.
47
- */
48
- private runCircuitBreaker;
49
- /**
50
- * Check budget thresholds. Returns a block message if budget is breached.
51
- */
52
- private checkBudget;
53
- /**
54
- * Main chat wrapper — intercepts every LLM call.
55
- */
56
- chat(request: OpenClawProviderRequest): Promise<OpenClawProviderResponse>;
57
- /**
58
- * Stream wrapper — logs the complete interaction after stream completes.
59
- */
60
- chatStream(request: OpenClawProviderRequest): AsyncIterable<any>;
61
- /**
62
- * Finalize the current session (called on plugin shutdown).
63
- */
64
- shutdown(): void;
65
- }
66
- //# sourceMappingURL=wrapped-provider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapped-provider.d.ts","sourceRoot":"","sources":["../src/wrapped-provider.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAY,MAAM,UAAU,CAAC;AAc1D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC1E,UAAU,CAAC,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;CACnE;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAAmB;IACvC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,OAAO,CAA6B;gBAEhC,YAAY,EAAE,gBAAgB,EAAE,MAAM,EAAE,oBAAoB;IAMxE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,YAAY,IAAI,MAAM,GAAG,SAAS,CAErC;IAED;;OAEG;IACH,OAAO,CAAC,aAAa;IAyCrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwCzB;;OAEG;IACH,OAAO,CAAC,WAAW;IA8BnB;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA4F/E;;OAEG;IACI,UAAU,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa,CAAC,GAAG,CAAC;IA+EvE;;OAEG;IACH,QAAQ,IAAI,IAAI;CAQjB"}
@@ -1,304 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WrappedProvider = void 0;
4
- const core_1 = require("opengauge/core");
5
- const config_1 = require("./config");
6
- class WrappedProvider {
7
- realProvider;
8
- config;
9
- queries;
10
- session = null;
11
- constructor(realProvider, config) {
12
- this.realProvider = realProvider;
13
- this.config = config;
14
- this.queries = new core_1.SessionQueries((0, core_1.getDb)());
15
- }
16
- get name() {
17
- return this.realProvider.name;
18
- }
19
- get defaultModel() {
20
- return this.realProvider.defaultModel;
21
- }
22
- /**
23
- * Ensure we have an active session, creating one if needed or if timed out.
24
- */
25
- ensureSession(model) {
26
- const now = Date.now();
27
- if (this.session && (now - this.session.lastCallTimestamp) > this.config.session_timeout_ms) {
28
- try {
29
- this.queries.finalizeSession(this.session.sessionId);
30
- }
31
- catch (e) {
32
- (0, config_1.logError)(e);
33
- }
34
- this.session = null;
35
- }
36
- if (!this.session) {
37
- try {
38
- const record = this.queries.createSession('openclaw', model, this.realProvider.name);
39
- this.session = {
40
- sessionId: record.id,
41
- interactionCount: 0,
42
- runningCostUsd: 0,
43
- lastCallTimestamp: now,
44
- recentInteractions: [],
45
- contextDepthTokens: 0,
46
- };
47
- }
48
- catch (e) {
49
- (0, config_1.logError)(e);
50
- this.session = {
51
- sessionId: `fallback-${now}`,
52
- interactionCount: 0,
53
- runningCostUsd: 0,
54
- lastCallTimestamp: now,
55
- recentInteractions: [],
56
- contextDepthTokens: 0,
57
- };
58
- }
59
- }
60
- return this.session;
61
- }
62
- /**
63
- * Run circuit breaker checks. Returns a block message if the call should be stopped.
64
- */
65
- runCircuitBreaker(session) {
66
- if (!this.config.circuit_breaker.enabled)
67
- return null;
68
- const verdict = (0, core_1.checkRunawayLoop)(session.recentInteractions, {
69
- similarityThreshold: this.config.circuit_breaker.similarity_threshold,
70
- tripPairCount: this.config.circuit_breaker.max_similar_calls,
71
- warningPairCount: Math.max(2, this.config.circuit_breaker.max_similar_calls - 2),
72
- });
73
- if (verdict.verdict === 'trip') {
74
- const msg = `OpenGauge circuit breaker: ${verdict.reason}. Session cost: $${session.runningCostUsd.toFixed(2)}. Stopping to prevent runaway spend.`;
75
- try {
76
- this.queries.writeAlert(session.sessionId, 'runaway_loop', 'critical', msg, { ...verdict, sessionCost: session.runningCostUsd });
77
- }
78
- catch (e) {
79
- (0, config_1.logError)(e);
80
- }
81
- if (this.config.circuit_breaker.action === 'block') {
82
- return msg;
83
- }
84
- }
85
- else if (verdict.verdict === 'warning') {
86
- try {
87
- this.queries.writeAlert(session.sessionId, 'runaway_loop', 'warning', verdict.reason, verdict);
88
- }
89
- catch (e) {
90
- (0, config_1.logError)(e);
91
- }
92
- }
93
- return null;
94
- }
95
- /**
96
- * Check budget thresholds. Returns a block message if budget is breached.
97
- */
98
- checkBudget(session) {
99
- if (session.runningCostUsd >= this.config.budget.session_limit_usd) {
100
- const msg = `OpenGauge budget: Session cost ($${session.runningCostUsd.toFixed(2)}) exceeds limit ($${this.config.budget.session_limit_usd.toFixed(2)}).`;
101
- try {
102
- this.queries.writeAlert(session.sessionId, 'budget_breach', 'critical', msg, {
103
- sessionCost: session.runningCostUsd,
104
- limit: this.config.budget.session_limit_usd,
105
- });
106
- }
107
- catch (e) {
108
- (0, config_1.logError)(e);
109
- }
110
- if (this.config.circuit_breaker.action === 'block')
111
- return msg;
112
- }
113
- try {
114
- const todayStart = new Date();
115
- todayStart.setHours(0, 0, 0, 0);
116
- const summary = this.queries.getSpendSummary(todayStart.getTime(), 'openclaw');
117
- if (summary.total_cost_usd >= this.config.budget.daily_limit_usd) {
118
- const msg = `OpenGauge budget: Daily spend ($${summary.total_cost_usd.toFixed(2)}) exceeds limit ($${this.config.budget.daily_limit_usd.toFixed(2)}).`;
119
- this.queries.writeAlert(session.sessionId, 'budget_breach', 'critical', msg, {
120
- dailyCost: summary.total_cost_usd,
121
- limit: this.config.budget.daily_limit_usd,
122
- });
123
- if (this.config.circuit_breaker.action === 'block')
124
- return msg;
125
- }
126
- }
127
- catch (e) {
128
- (0, config_1.logError)(e);
129
- }
130
- return null;
131
- }
132
- /**
133
- * Main chat wrapper — intercepts every LLM call.
134
- */
135
- async chat(request) {
136
- const model = request.model || this.realProvider.defaultModel || 'unknown';
137
- const session = this.ensureSession(model);
138
- const startTime = Date.now();
139
- try {
140
- const lastUserMsg = [...request.messages].reverse().find(m => m.role === 'user');
141
- const originalPrompt = lastUserMsg?.content || '';
142
- const blockMsg = this.runCircuitBreaker(session);
143
- if (blockMsg) {
144
- return {
145
- content: blockMsg,
146
- model,
147
- usage: { input_tokens: 0, output_tokens: 0 },
148
- };
149
- }
150
- const budgetMsg = this.checkBudget(session);
151
- if (budgetMsg) {
152
- return {
153
- content: budgetMsg,
154
- model,
155
- usage: { input_tokens: 0, output_tokens: 0 },
156
- };
157
- }
158
- const response = await this.realProvider.chat(request);
159
- const latencyMs = Date.now() - startTime;
160
- const tokensIn = response.usage?.input_tokens || response.usage?.prompt_tokens || 0;
161
- const tokensOut = response.usage?.output_tokens || response.usage?.completion_tokens || 0;
162
- const costEstimate = (0, core_1.calculateCost)(this.realProvider.name, model, tokensIn, tokensOut);
163
- session.interactionCount++;
164
- session.runningCostUsd += costEstimate.totalCost;
165
- session.lastCallTimestamp = Date.now();
166
- session.contextDepthTokens += tokensIn;
167
- session.recentInteractions.push({
168
- role: 'user',
169
- content: originalPrompt,
170
- timestamp: startTime,
171
- });
172
- session.recentInteractions.push({
173
- role: 'assistant',
174
- content: response.content,
175
- timestamp: Date.now(),
176
- });
177
- if (session.recentInteractions.length > 40) {
178
- session.recentInteractions = session.recentInteractions.slice(-40);
179
- }
180
- try {
181
- this.queries.writeInteraction(session.sessionId, session.interactionCount, model, {
182
- originalPrompt,
183
- responseText: this.config.log_response_text ? response.content : undefined,
184
- tokensIn,
185
- tokensOut,
186
- costUsd: costEstimate.totalCost,
187
- latencyMs,
188
- contextDepthTokens: session.contextDepthTokens,
189
- metadata: this.config.log_full_request ? { messages: request.messages } : undefined,
190
- });
191
- }
192
- catch (e) {
193
- (0, config_1.logError)(e);
194
- }
195
- try {
196
- this.queries.updateSessionAggregates(session.sessionId, tokensIn, tokensOut, costEstimate.totalCost);
197
- }
198
- catch (e) {
199
- (0, config_1.logError)(e);
200
- }
201
- return response;
202
- }
203
- catch (error) {
204
- (0, config_1.logError)(error);
205
- try {
206
- return await this.realProvider.chat(request);
207
- }
208
- catch (providerError) {
209
- throw providerError;
210
- }
211
- }
212
- }
213
- /**
214
- * Stream wrapper — logs the complete interaction after stream completes.
215
- */
216
- async *chatStream(request) {
217
- if (!this.realProvider.chatStream) {
218
- const response = await this.chat(request);
219
- yield { content: response.content, done: true, ...response.usage };
220
- return;
221
- }
222
- const model = request.model || this.realProvider.defaultModel || 'unknown';
223
- const session = this.ensureSession(model);
224
- const startTime = Date.now();
225
- const lastUserMsg = [...request.messages].reverse().find(m => m.role === 'user');
226
- const originalPrompt = lastUserMsg?.content || '';
227
- try {
228
- const blockMsg = this.runCircuitBreaker(session);
229
- if (blockMsg) {
230
- yield { content: blockMsg, done: true };
231
- return;
232
- }
233
- const budgetMsg = this.checkBudget(session);
234
- if (budgetMsg) {
235
- yield { content: budgetMsg, done: true };
236
- return;
237
- }
238
- }
239
- catch (e) {
240
- (0, config_1.logError)(e);
241
- }
242
- let fullContent = '';
243
- let finalTokensIn = 0;
244
- let finalTokensOut = 0;
245
- try {
246
- for await (const chunk of this.realProvider.chatStream(request)) {
247
- if (chunk.content)
248
- fullContent += chunk.content;
249
- if (chunk.input_tokens || chunk.prompt_tokens) {
250
- finalTokensIn = chunk.input_tokens || chunk.prompt_tokens || finalTokensIn;
251
- }
252
- if (chunk.output_tokens || chunk.completion_tokens) {
253
- finalTokensOut = chunk.output_tokens || chunk.completion_tokens || finalTokensOut;
254
- }
255
- yield chunk;
256
- }
257
- }
258
- catch (error) {
259
- (0, config_1.logError)(error);
260
- throw error;
261
- }
262
- try {
263
- const latencyMs = Date.now() - startTime;
264
- const costEstimate = (0, core_1.calculateCost)(this.realProvider.name, model, finalTokensIn, finalTokensOut);
265
- session.interactionCount++;
266
- session.runningCostUsd += costEstimate.totalCost;
267
- session.lastCallTimestamp = Date.now();
268
- session.contextDepthTokens += finalTokensIn;
269
- session.recentInteractions.push({ role: 'user', content: originalPrompt, timestamp: startTime }, { role: 'assistant', content: fullContent, timestamp: Date.now() });
270
- if (session.recentInteractions.length > 40) {
271
- session.recentInteractions = session.recentInteractions.slice(-40);
272
- }
273
- this.queries.writeInteraction(session.sessionId, session.interactionCount, model, {
274
- originalPrompt,
275
- responseText: this.config.log_response_text ? fullContent : undefined,
276
- tokensIn: finalTokensIn,
277
- tokensOut: finalTokensOut,
278
- costUsd: costEstimate.totalCost,
279
- latencyMs,
280
- contextDepthTokens: session.contextDepthTokens,
281
- });
282
- this.queries.updateSessionAggregates(session.sessionId, finalTokensIn, finalTokensOut, costEstimate.totalCost);
283
- }
284
- catch (e) {
285
- (0, config_1.logError)(e);
286
- }
287
- }
288
- /**
289
- * Finalize the current session (called on plugin shutdown).
290
- */
291
- shutdown() {
292
- if (this.session) {
293
- try {
294
- this.queries.finalizeSession(this.session.sessionId);
295
- }
296
- catch (e) {
297
- (0, config_1.logError)(e);
298
- }
299
- this.session = null;
300
- }
301
- }
302
- }
303
- exports.WrappedProvider = WrappedProvider;
304
- //# sourceMappingURL=wrapped-provider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapped-provider.js","sourceRoot":"","sources":["../src/wrapped-provider.ts"],"names":[],"mappings":"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"}