@mapick/cost-firewall 0.1.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.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +161 -0
  3. package/dist/breaker.d.ts +30 -0
  4. package/dist/breaker.d.ts.map +1 -0
  5. package/dist/breaker.js +131 -0
  6. package/dist/breaker.js.map +1 -0
  7. package/dist/cli/index.d.ts +18 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +244 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/config-warn.d.ts +11 -0
  12. package/dist/config-warn.d.ts.map +1 -0
  13. package/dist/config-warn.js +26 -0
  14. package/dist/config-warn.js.map +1 -0
  15. package/dist/config.d.ts +7 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +32 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/dashboard/html.d.ts +2 -0
  20. package/dist/dashboard/html.d.ts.map +1 -0
  21. package/dist/dashboard/html.js +898 -0
  22. package/dist/dashboard/html.js.map +1 -0
  23. package/dist/dashboard/index.d.ts +8 -0
  24. package/dist/dashboard/index.d.ts.map +1 -0
  25. package/dist/dashboard/index.js +163 -0
  26. package/dist/dashboard/index.js.map +1 -0
  27. package/dist/dashboard/sse.d.ts +9 -0
  28. package/dist/dashboard/sse.d.ts.map +1 -0
  29. package/dist/dashboard/sse.js +22 -0
  30. package/dist/dashboard/sse.js.map +1 -0
  31. package/dist/hooks/agent-end.d.ts +18 -0
  32. package/dist/hooks/agent-end.d.ts.map +1 -0
  33. package/dist/hooks/agent-end.js +25 -0
  34. package/dist/hooks/agent-end.js.map +1 -0
  35. package/dist/hooks/before-agent-reply.d.ts +29 -0
  36. package/dist/hooks/before-agent-reply.d.ts.map +1 -0
  37. package/dist/hooks/before-agent-reply.js +42 -0
  38. package/dist/hooks/before-agent-reply.js.map +1 -0
  39. package/dist/hooks/index.d.ts +7 -0
  40. package/dist/hooks/index.d.ts.map +1 -0
  41. package/dist/hooks/index.js +17 -0
  42. package/dist/hooks/index.js.map +1 -0
  43. package/dist/hooks/model-call.d.ts +39 -0
  44. package/dist/hooks/model-call.d.ts.map +1 -0
  45. package/dist/hooks/model-call.js +120 -0
  46. package/dist/hooks/model-call.js.map +1 -0
  47. package/dist/index.d.ts +13 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +49 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/pricing.d.ts +12 -0
  52. package/dist/pricing.d.ts.map +1 -0
  53. package/dist/pricing.js +43 -0
  54. package/dist/pricing.js.map +1 -0
  55. package/dist/provider/auth.d.ts +14 -0
  56. package/dist/provider/auth.d.ts.map +1 -0
  57. package/dist/provider/auth.js +53 -0
  58. package/dist/provider/auth.js.map +1 -0
  59. package/dist/provider/index.d.ts +12 -0
  60. package/dist/provider/index.d.ts.map +1 -0
  61. package/dist/provider/index.js +134 -0
  62. package/dist/provider/index.js.map +1 -0
  63. package/dist/provider/route.d.ts +10 -0
  64. package/dist/provider/route.d.ts.map +1 -0
  65. package/dist/provider/route.js +19 -0
  66. package/dist/provider/route.js.map +1 -0
  67. package/dist/provider/stream.d.ts +10 -0
  68. package/dist/provider/stream.d.ts.map +1 -0
  69. package/dist/provider/stream.js +120 -0
  70. package/dist/provider/stream.js.map +1 -0
  71. package/dist/provider/synthetic.d.ts +13 -0
  72. package/dist/provider/synthetic.d.ts.map +1 -0
  73. package/dist/provider/synthetic.js +59 -0
  74. package/dist/provider/synthetic.js.map +1 -0
  75. package/dist/provider/upstream/anthropic.d.ts +13 -0
  76. package/dist/provider/upstream/anthropic.d.ts.map +1 -0
  77. package/dist/provider/upstream/anthropic.js +62 -0
  78. package/dist/provider/upstream/anthropic.js.map +1 -0
  79. package/dist/provider/upstream/openai.d.ts +17 -0
  80. package/dist/provider/upstream/openai.d.ts.map +1 -0
  81. package/dist/provider/upstream/openai.js +75 -0
  82. package/dist/provider/upstream/openai.js.map +1 -0
  83. package/dist/source.d.ts +35 -0
  84. package/dist/source.d.ts.map +1 -0
  85. package/dist/source.js +41 -0
  86. package/dist/source.js.map +1 -0
  87. package/dist/state.d.ts +56 -0
  88. package/dist/state.d.ts.map +1 -0
  89. package/dist/state.js +178 -0
  90. package/dist/state.js.map +1 -0
  91. package/dist/store.d.ts +23 -0
  92. package/dist/store.d.ts.map +1 -0
  93. package/dist/store.js +68 -0
  94. package/dist/store.js.map +1 -0
  95. package/dist/tools/index.d.ts +13 -0
  96. package/dist/tools/index.d.ts.map +1 -0
  97. package/dist/tools/index.js +63 -0
  98. package/dist/tools/index.js.map +1 -0
  99. package/dist/types.d.ts +98 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +7 -0
  102. package/dist/types.js.map +1 -0
  103. package/openclaw.plugin.json +44 -0
  104. package/package.json +49 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mapick
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # @mapick/cost-firewall
2
+
3
+ ![Version](https://img.shields.io/github/v/tag/mapick-ai/cost-firewall?label=version&color=2563eb)
4
+ ![License](https://img.shields.io/github/license/mapick-ai/cost-firewall?color=16a34a)
5
+ ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=fff)
6
+ ![OpenClaw Plugin](https://img.shields.io/badge/OpenClaw-Plugin-8B5CF6)
7
+
8
+ AI Call Firewall — real-time monitoring, budget control, automatic circuit breaker.
9
+
10
+ ---
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ openclaw plugins install @mapick/cost-firewall
16
+ openclaw plugins enable mapick-firewall
17
+ openclaw gateway restart
18
+ openclaw firewall status
19
+ ```
20
+
21
+ Dashboard: **http://localhost:18789/mapick/dashboard**
22
+
23
+ ---
24
+
25
+ ## Commands
26
+
27
+ | In Chat | CLI | Action |
28
+ |---|---|---|
29
+ | `/firewall` | `openclaw firewall status` | Status |
30
+ | `/firewall stop` | `openclaw firewall stop` | 🛑 Emergency stop |
31
+ | `/firewall resume` | `openclaw firewall resume` | ▶️ Resume |
32
+ | — | `openclaw firewall mode observe\|protect` | Toggle mode |
33
+ | `/firewall budget` | `openclaw firewall budget set\|reset` | Daily token limit |
34
+ | `/firewall log` | `openclaw firewall log` | Recent events |
35
+ | — | `openclaw firewall reset <source>` | Clear cooldown |
36
+
37
+ ---
38
+
39
+ ## Config
40
+
41
+ ```jsonc
42
+ {
43
+ "plugins": {
44
+ "entries": {
45
+ "mapick-firewall": {
46
+ "enabled": true,
47
+ "config": {
48
+ "dailyTokenLimit": null,
49
+ "breaker": {
50
+ "consecutiveFailures": 3,
51
+ "cooldownSec": 30,
52
+ "tokenVelocityThreshold": 100000,
53
+ "tokenVelocityWindowSec": 60,
54
+ "callFrequencyThreshold": 30,
55
+ "callFrequencyWindowSec": 60
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Defaults
67
+
68
+ | Rule | Threshold | Window | Cooldown |
69
+ |---|---|---|---|
70
+ | Consecutive Failures | 3 | — | 30s |
71
+ | Token Velocity | 100K tokens | 60s | 30s |
72
+ | Call Frequency | 30 calls | 60s | 30s |
73
+ | Daily Token Limit | unlimited | — | — |
74
+
75
+ ---
76
+
77
+ ## AI Installation Checklist
78
+
79
+ Use this checklist when installing the firewall automatically:
80
+
81
+ ```markdown
82
+ ## Installation Steps
83
+
84
+ 1. Install the npm package:
85
+ ```bash
86
+ openclaw plugins install @mapick/cost-firewall
87
+ ```
88
+
89
+ 2. Enable the plugin:
90
+ ```bash
91
+ openclaw plugins enable mapick-firewall
92
+ ```
93
+
94
+ 3. Verify it's registered:
95
+ ```bash
96
+ openclaw plugins list | grep mapick-firewall
97
+ ```
98
+ Expected: should show `mapick-firewall` in the list.
99
+
100
+ 4. Restart gateway:
101
+ ```bash
102
+ openclaw gateway restart
103
+ ```
104
+
105
+ 5. Verify it's working:
106
+ ```bash
107
+ openclaw firewall status
108
+ ```
109
+ Expected: returns JSON with mode, today_tokens, today_blocked, etc.
110
+
111
+ 6. Optionally, set a daily token budget:
112
+ ```bash
113
+ openclaw firewall budget set 500000
114
+ ```
115
+
116
+ ## Routing calls through the firewall
117
+
118
+ To route AI calls through the firewall, configure the model with `mapick/` prefix:
119
+
120
+ ```json
121
+ {
122
+ "agents": {
123
+ "defaults": {
124
+ "model": {
125
+ "primary": "mapick/deepseek/deepseek-chat",
126
+ "fallbacks": ["mapick/anthropic/claude-sonnet-4-20250514"]
127
+ }
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ Format: `mapick/<upstream>/<model-id>`
134
+ Supported upstreams: `openai`, `anthropic`, `deepseek`, `openrouter`, `qwen`
135
+
136
+ ## Validation
137
+
138
+ After installation, the AI should verify:
139
+ - [ ] `openclaw plugins list` shows `mapick-firewall` (enabled)
140
+ - [ ] `openclaw firewall status` returns valid JSON
141
+ - [ ] Dashboard accessible at http://localhost:18789/mapick/dashboard
142
+ - [ ] Model config uses `mapick/` prefix if firewall protection is desired
143
+ - [ ] Fallbacks also use `mapick/` prefix (non-mapick fallbacks bypass the firewall)
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Development
149
+
150
+ ```bash
151
+ pnpm install
152
+ pnpm build
153
+ pnpm test
154
+ pnpm dev # tsc --watch
155
+ ```
156
+
157
+ See [RELEASE.md](./RELEASE.md) for release process.
158
+
159
+ ## License
160
+
161
+ MIT
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Breaker logic
3
+ *
4
+ * Three rules:
5
+ * 1. Consecutive failures (consecutiveFailures)
6
+ * 2. Token velocity (tokenVelocity) — token consumption exceeds threshold within window
7
+ * 3. Call frequency (callFrequency) — call count exceeds threshold within window
8
+ */
9
+ import type { FirewallConfig, SourceKey } from "./types.js";
10
+ export declare class Breaker {
11
+ private states;
12
+ private config;
13
+ constructor(config: FirewallConfig);
14
+ private getState;
15
+ recordFailure(source: SourceKey): void;
16
+ recordSuccess(source: SourceKey): void;
17
+ recordTokens(source: SourceKey, tokens: number): string | undefined;
18
+ recordCall(source: SourceKey): string | undefined;
19
+ isCoolingDown(source: SourceKey): boolean;
20
+ getBlockedReason(source: SourceKey): string | undefined;
21
+ reset(source: SourceKey): void;
22
+ getCooldownRemaining(source: SourceKey): number;
23
+ /** Return list of all cooling sources */
24
+ getCoolingSources(): {
25
+ source: string;
26
+ reason: string;
27
+ remainingSec: number;
28
+ }[];
29
+ }
30
+ //# sourceMappingURL=breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breaker.d.ts","sourceRoot":"","sources":["../src/breaker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAgB,MAAM,YAAY,CAAC;AAoB1E,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,cAAc;IAWlC,OAAO,CAAC,QAAQ;IAchB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAStC,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAOtC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAuBnE,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAqBjD,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO;IAYzC,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS;IAIvD,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAI9B,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM;IAM/C,yCAAyC;IACzC,iBAAiB,IAAI;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,EAAE;CAchF"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Breaker logic
3
+ *
4
+ * Three rules:
5
+ * 1. Consecutive failures (consecutiveFailures)
6
+ * 2. Token velocity (tokenVelocity) — token consumption exceeds threshold within window
7
+ * 3. Call frequency (callFrequency) — call count exceeds threshold within window
8
+ */
9
+ const DEFAULT_BREAKER = {
10
+ consecutiveFailures: 3,
11
+ cooldownSec: 30,
12
+ tokenVelocityWindowSec: 60,
13
+ tokenVelocityThreshold: 100000,
14
+ callFrequencyWindowSec: 60,
15
+ callFrequencyThreshold: 30,
16
+ };
17
+ export class Breaker {
18
+ states = new Map();
19
+ config;
20
+ constructor(config) {
21
+ this.config = {
22
+ consecutiveFailures: config.breaker?.consecutiveFailures ?? DEFAULT_BREAKER.consecutiveFailures,
23
+ cooldownSec: config.breaker?.cooldownSec ?? DEFAULT_BREAKER.cooldownSec,
24
+ tokenVelocityWindowSec: config.breaker?.tokenVelocityWindowSec ?? DEFAULT_BREAKER.tokenVelocityWindowSec,
25
+ tokenVelocityThreshold: config.breaker?.tokenVelocityThreshold ?? DEFAULT_BREAKER.tokenVelocityThreshold,
26
+ callFrequencyWindowSec: config.breaker?.callFrequencyWindowSec ?? DEFAULT_BREAKER.callFrequencyWindowSec,
27
+ callFrequencyThreshold: config.breaker?.callFrequencyThreshold ?? DEFAULT_BREAKER.callFrequencyThreshold,
28
+ };
29
+ }
30
+ getState(source) {
31
+ if (!this.states.has(source)) {
32
+ this.states.set(source, {
33
+ source,
34
+ consecutiveFailures: 0,
35
+ tokenHistory: [],
36
+ callTimestamps: [],
37
+ });
38
+ }
39
+ return this.states.get(source);
40
+ }
41
+ // ----- Consecutive failures -----
42
+ recordFailure(source) {
43
+ const state = this.getState(source);
44
+ state.consecutiveFailures++;
45
+ if (state.consecutiveFailures >= this.config.consecutiveFailures && this.config.consecutiveFailures > 0) {
46
+ state.brokenUntil = Date.now() + this.config.cooldownSec * 1000;
47
+ state.reason = "consecutive_failures";
48
+ }
49
+ }
50
+ recordSuccess(source) {
51
+ const state = this.getState(source);
52
+ state.consecutiveFailures = 0;
53
+ }
54
+ // ----- Token velocity (sliding window) -----
55
+ recordTokens(source, tokens) {
56
+ const state = this.getState(source);
57
+ const now = Date.now();
58
+ const windowMs = this.config.tokenVelocityWindowSec * 1000;
59
+ const threshold = this.config.tokenVelocityThreshold;
60
+ if (threshold <= 0)
61
+ return undefined;
62
+ state.tokenHistory.push({ ts: now, tokens });
63
+ // Purge expired records
64
+ state.tokenHistory = state.tokenHistory.filter((h) => now - h.ts < windowMs);
65
+ const total = state.tokenHistory.reduce((sum, h) => sum + h.tokens, 0);
66
+ if (total >= threshold) {
67
+ state.brokenUntil = now + this.config.cooldownSec * 1000;
68
+ state.reason = "token_velocity";
69
+ return "token_velocity";
70
+ }
71
+ return undefined;
72
+ }
73
+ // ----- Call frequency (sliding window) -----
74
+ recordCall(source) {
75
+ const state = this.getState(source);
76
+ const now = Date.now();
77
+ const windowMs = this.config.callFrequencyWindowSec * 1000;
78
+ const threshold = this.config.callFrequencyThreshold;
79
+ if (threshold <= 0)
80
+ return undefined;
81
+ state.callTimestamps.push(now);
82
+ state.callTimestamps = state.callTimestamps.filter((t) => now - t < windowMs);
83
+ if (state.callTimestamps.length >= threshold) {
84
+ state.brokenUntil = now + this.config.cooldownSec * 1000;
85
+ state.reason = "call_frequency";
86
+ return "call_frequency";
87
+ }
88
+ return undefined;
89
+ }
90
+ // ----- Common -----
91
+ isCoolingDown(source) {
92
+ const state = this.getState(source);
93
+ if (!state.brokenUntil)
94
+ return false;
95
+ if (Date.now() > state.brokenUntil) {
96
+ state.brokenUntil = undefined;
97
+ state.reason = undefined;
98
+ state.consecutiveFailures = 0;
99
+ return false;
100
+ }
101
+ return true;
102
+ }
103
+ getBlockedReason(source) {
104
+ return this.isCoolingDown(source) ? this.getState(source).reason : undefined;
105
+ }
106
+ reset(source) {
107
+ this.states.delete(source);
108
+ }
109
+ getCooldownRemaining(source) {
110
+ const state = this.getState(source);
111
+ if (!state.brokenUntil)
112
+ return 0;
113
+ return Math.max(0, state.brokenUntil - Date.now());
114
+ }
115
+ /** Return list of all cooling sources */
116
+ getCoolingSources() {
117
+ const now = Date.now();
118
+ const result = [];
119
+ for (const [source, state] of this.states) {
120
+ if (state.brokenUntil && now < state.brokenUntil) {
121
+ result.push({
122
+ source,
123
+ reason: state.reason ?? "unknown",
124
+ remainingSec: Math.max(0, Math.round((state.brokenUntil - now) / 1000)),
125
+ });
126
+ }
127
+ }
128
+ return result;
129
+ }
130
+ }
131
+ //# sourceMappingURL=breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"breaker.js","sourceRoot":"","sources":["../src/breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * CLI command implementation
3
+ *
4
+ * Register openclaw mapick <subcommand> command group
5
+ */
6
+ import type { FirewallState } from "../state.js";
7
+ import { EventStore } from "../store.js";
8
+ import type { FirewallEvent } from "../types.js";
9
+ /** Aggregate today's stats from JSONL */
10
+ export declare function aggregateFromJsonl(store: EventStore, memTokens: number, memBlocked: number): Promise<{
11
+ today_tokens: number;
12
+ today_blocked: number;
13
+ events: FirewallEvent[];
14
+ }>;
15
+ export declare function registerCli(api: any, state: FirewallState, store: EventStore): void;
16
+ export declare function getStatus(state: FirewallState, store?: EventStore): Promise<object>;
17
+ export declare function getLog(store: EventStore, count: number): Promise<object[]>;
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAqBjD,yCAAyC;AACzC,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1G,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB,CAAC,CAmBD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAwHnF;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDzF;AAED,wBAAsB,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKhF"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * CLI command implementation
3
+ *
4
+ * Register openclaw mapick <subcommand> command group
5
+ */
6
+ import { readFile } from "node:fs/promises";
7
+ import http from "node:http";
8
+ const API_BASE = "http://127.0.0.1:18789";
9
+ function apiGet(path) {
10
+ return new Promise((resolve) => {
11
+ http.get(`${API_BASE}${path}`, () => resolve()).on("error", () => resolve());
12
+ });
13
+ }
14
+ function apiPost(body) {
15
+ return new Promise((resolve) => {
16
+ const data = JSON.stringify(body);
17
+ const url = new URL(`${API_BASE}/mapick/api/config`);
18
+ const req = http.request(url, { method: "POST", headers: { "Content-Type": "application/json" } }, () => resolve());
19
+ req.on("error", () => resolve());
20
+ req.write(data);
21
+ req.end();
22
+ });
23
+ }
24
+ /** Aggregate today's stats from JSONL */
25
+ export async function aggregateFromJsonl(store, memTokens, memBlocked) {
26
+ const todayStart = new Date();
27
+ todayStart.setHours(0, 0, 0, 0);
28
+ const todayTs = todayStart.getTime();
29
+ const events = [];
30
+ try {
31
+ const raw = await readFile(store.getEventsFilePath(), "utf-8");
32
+ for (const line of raw.trim().split("\n")) {
33
+ try {
34
+ const e = JSON.parse(line);
35
+ if (e.timestamp >= todayTs)
36
+ events.push(e);
37
+ }
38
+ catch { /* skip */ }
39
+ }
40
+ }
41
+ catch { /* file not found */ }
42
+ const jsonlTokens = events.filter((e) => e.type === "model_call_ended").reduce((sum, e) => sum + (e.estimatedCost ?? 0), 0);
43
+ const jsonlBlocked = events.filter((e) => e.type === "blocked").length;
44
+ return { today_tokens: Math.max(memTokens, jsonlTokens), today_blocked: Math.max(memBlocked, jsonlBlocked), events };
45
+ }
46
+ export function registerCli(api, state, store) {
47
+ api.registerCli(({ program }) => {
48
+ const firewall = program.command("firewall").description("Mapick Cost Firewall commands");
49
+ firewall.command("status")
50
+ .description("Show firewall status")
51
+ .action(async () => {
52
+ const agg = await aggregateFromJsonl(store, state.globalStats.todayTokens, state.globalStats.todayBlocked);
53
+ const cooling = state.breaker.getCoolingSources();
54
+ console.log(JSON.stringify({
55
+ mode: state.globalStats.mode,
56
+ emergency_stop: state.globalStats.emergencyStop,
57
+ today_tokens: agg.today_tokens,
58
+ today_blocked: agg.today_blocked,
59
+ daily_token_limit: state.config.dailyTokenLimit,
60
+ cooldown_sec: state.config.breaker?.cooldownSec,
61
+ cooling_sources: cooling,
62
+ }, null, 2));
63
+ });
64
+ firewall.command("reset")
65
+ .description("Reset a source from cooldown")
66
+ .argument("<source>", "Source name to reset")
67
+ .action((source) => {
68
+ state.breaker.reset(source);
69
+ console.log(`Source ${source} reset.`);
70
+ });
71
+ firewall.command("mode")
72
+ .description("Switch mode (observe|protect)")
73
+ .argument("<mode>", "observe or protect")
74
+ .action(async (mode) => {
75
+ if (mode !== "observe" && mode !== "protect") {
76
+ console.error("Invalid mode. Use 'observe' or 'protect'.");
77
+ return;
78
+ }
79
+ state.setMode(mode);
80
+ await apiPost({ mode });
81
+ console.log(`Mode set to ${mode}`);
82
+ });
83
+ firewall.command("stop")
84
+ .description("Emergency stop all AI calls")
85
+ .action(async () => {
86
+ state.setEmergencyStop(true);
87
+ await apiPost({});
88
+ await apiGet("/mapick/api/stop");
89
+ console.log("Emergency stop activated.");
90
+ });
91
+ firewall.command("resume")
92
+ .description("Resume AI calls after emergency stop")
93
+ .action(async () => {
94
+ state.setEmergencyStop(false);
95
+ await apiGet("/mapick/api/resume");
96
+ console.log("Resumed.");
97
+ });
98
+ firewall.command("budget")
99
+ .description("Set or reset daily token limit")
100
+ .argument("<action>", "set <amount> or reset")
101
+ .argument("[amount]", "Token count")
102
+ .action(async (action, amount) => {
103
+ // Update via gateway's /config API (don't write file directly to avoid breaking format)
104
+ const http = await import("node:http");
105
+ let body;
106
+ if (action === "set" && amount) {
107
+ body = JSON.stringify({ dailyTokenLimit: parseInt(amount, 10) });
108
+ state.config.dailyTokenLimit = parseInt(amount, 10);
109
+ }
110
+ else if (action === "reset") {
111
+ body = JSON.stringify({ dailyTokenLimit: null });
112
+ state.config.dailyTokenLimit = null;
113
+ }
114
+ else {
115
+ console.error("Usage: firewall budget set <amount> | firewall budget reset");
116
+ return;
117
+ }
118
+ // Write to memory + notify gateway (fire-and-forget)
119
+ const url = new URL("http://127.0.0.1:18789/mapick/api/config");
120
+ const req = http.request(url, { method: "POST", headers: { "Content-Type": "application/json" } }, (res) => {
121
+ let data = "";
122
+ res.on("data", (c) => data += c);
123
+ res.on("end", () => {
124
+ try {
125
+ const d = JSON.parse(data);
126
+ console.log(d.ok ? "Saved." : "Error: " + (d.error || "unknown"));
127
+ }
128
+ catch {
129
+ console.log("Config updated.");
130
+ }
131
+ });
132
+ });
133
+ req.on("error", () => console.log("Config updated (gateway unreachable, memory only)."));
134
+ req.write(body);
135
+ req.end();
136
+ });
137
+ firewall.command("log")
138
+ .description("Show recent events")
139
+ .option("--last <count>", "Number of events", "10")
140
+ .action(async (opts) => {
141
+ const count = parseInt(opts.last, 10) || 10;
142
+ try {
143
+ const raw = await readFile(store.getEventsFilePath(), "utf-8");
144
+ const lines = raw.trim().split("\n");
145
+ const recent = lines.slice(-count).map((l) => {
146
+ try {
147
+ return JSON.parse(l);
148
+ }
149
+ catch {
150
+ return null;
151
+ }
152
+ }).filter(Boolean);
153
+ for (const e of recent) {
154
+ const t = new Date(e.timestamp).toISOString().slice(11, 19);
155
+ const cost = e.estimatedCost ? `${Math.round(e.estimatedCost ?? 0)}t` : "";
156
+ console.log(`${t} | ${e.type.padEnd(22)} | ${(e.provider ?? "").padEnd(12)} | ${(e.model ?? "").padEnd(30)} | ${(e.outcome ?? "").padEnd(10)} | ${cost}`);
157
+ }
158
+ }
159
+ catch {
160
+ console.log("No events recorded yet.");
161
+ }
162
+ });
163
+ }, {
164
+ descriptors: [
165
+ { name: "firewall", description: "Mapick Cost Firewall commands", hasSubcommands: true },
166
+ ],
167
+ });
168
+ }
169
+ export async function getStatus(state, store) {
170
+ let spent = state.globalStats.todayTokens;
171
+ let blocked = state.globalStats.todayBlocked;
172
+ let coolingSources = state.breaker.getCoolingSources();
173
+ let activeRuns = state.getActiveRuns();
174
+ if (store) {
175
+ const agg = await aggregateFromJsonl(store, spent, blocked);
176
+ spent = agg.today_tokens;
177
+ blocked = agg.today_blocked;
178
+ // Aggregate cooling sources from events (source+reason of recent blocked events)
179
+ const recentBlocks = agg.events
180
+ .filter((e) => e.type === "blocked")
181
+ .slice(-10);
182
+ if (recentBlocks.length > 0 && coolingSources.length === 0) {
183
+ coolingSources = recentBlocks.map((e) => ({
184
+ source: e.source || "unknown",
185
+ reason: e.reason || "unknown",
186
+ remainingSec: 0,
187
+ }));
188
+ }
189
+ // Aggregate active runs from events (runs without corresponding agent_end)
190
+ const runEnded = new Set(agg.events.filter((e) => e.type === "agent_end").map((e) => e.runId));
191
+ const activeRunMap = new Map();
192
+ for (const e of agg.events) {
193
+ if (e.runId && !runEnded.has(e.runId) && (e.type === "model_call_ended" || e.type === "run_status_change")) {
194
+ const r = activeRunMap.get(e.runId) || { runId: e.runId, source: e.source || "", calls: 0, tokens: 0, status: "healthy" };
195
+ if (e.type === "model_call_ended") {
196
+ r.calls++;
197
+ r.tokens += (e.estimatedCost || 0);
198
+ }
199
+ if (e.type === "run_status_change" && e.status) {
200
+ r.status = e.status;
201
+ if (e.reason)
202
+ r.reason = e.reason;
203
+ }
204
+ activeRunMap.set(e.runId, r);
205
+ }
206
+ }
207
+ if (activeRunMap.size > 0 && activeRuns.length === 0) {
208
+ activeRuns = Array.from(activeRunMap.values());
209
+ }
210
+ }
211
+ return {
212
+ mode: state.globalStats.mode,
213
+ emergency_stop: state.globalStats.emergencyStop,
214
+ today_tokens: spent,
215
+ today_blocked: blocked,
216
+ today_saved_estimate: state.globalStats.todaySavedEstimate,
217
+ daily_token_limit: state.config.dailyTokenLimit,
218
+ breaker: {
219
+ consecutive_failures: state.config.breaker?.consecutiveFailures,
220
+ cooldown_sec: state.config.breaker?.cooldownSec,
221
+ token_velocity_threshold: state.config.breaker?.tokenVelocityThreshold,
222
+ token_velocity_window_sec: state.config.breaker?.tokenVelocityWindowSec,
223
+ call_frequency_threshold: state.config.breaker?.callFrequencyThreshold,
224
+ call_frequency_window_sec: state.config.breaker?.callFrequencyWindowSec,
225
+ },
226
+ cooling_sources: coolingSources,
227
+ active_runs: activeRuns,
228
+ };
229
+ }
230
+ export async function getLog(store, count) {
231
+ try {
232
+ const raw = await readFile(store.getEventsFilePath(), "utf-8");
233
+ return raw.trim().split("\n").slice(-count).map((l) => { try {
234
+ return JSON.parse(l);
235
+ }
236
+ catch {
237
+ return null;
238
+ } }).filter(Boolean);
239
+ }
240
+ catch {
241
+ return [];
242
+ }
243
+ }
244
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Config risk detection
3
+ *
4
+ * Check at startup whether fallback config may bypass Mapick
5
+ */
6
+ export interface ConfigWarning {
7
+ level: "warn" | "error";
8
+ message: string;
9
+ }
10
+ export declare function detectConfigRisks(config: any): ConfigWarning[];
11
+ //# sourceMappingURL=config-warn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-warn.d.ts","sourceRoot":"","sources":["../src/config-warn.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,EAAE,CAuB9D"}