@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.
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/breaker.d.ts +30 -0
- package/dist/breaker.d.ts.map +1 -0
- package/dist/breaker.js +131 -0
- package/dist/breaker.js.map +1 -0
- package/dist/cli/index.d.ts +18 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +244 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config-warn.d.ts +11 -0
- package/dist/config-warn.d.ts.map +1 -0
- package/dist/config-warn.js +26 -0
- package/dist/config-warn.js.map +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +32 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/html.d.ts +2 -0
- package/dist/dashboard/html.d.ts.map +1 -0
- package/dist/dashboard/html.js +898 -0
- package/dist/dashboard/html.js.map +1 -0
- package/dist/dashboard/index.d.ts +8 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +163 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/sse.d.ts +9 -0
- package/dist/dashboard/sse.d.ts.map +1 -0
- package/dist/dashboard/sse.js +22 -0
- package/dist/dashboard/sse.js.map +1 -0
- package/dist/hooks/agent-end.d.ts +18 -0
- package/dist/hooks/agent-end.d.ts.map +1 -0
- package/dist/hooks/agent-end.js +25 -0
- package/dist/hooks/agent-end.js.map +1 -0
- package/dist/hooks/before-agent-reply.d.ts +29 -0
- package/dist/hooks/before-agent-reply.d.ts.map +1 -0
- package/dist/hooks/before-agent-reply.js +42 -0
- package/dist/hooks/before-agent-reply.js.map +1 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +17 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/model-call.d.ts +39 -0
- package/dist/hooks/model-call.d.ts.map +1 -0
- package/dist/hooks/model-call.js +120 -0
- package/dist/hooks/model-call.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/pricing.d.ts +12 -0
- package/dist/pricing.d.ts.map +1 -0
- package/dist/pricing.js +43 -0
- package/dist/pricing.js.map +1 -0
- package/dist/provider/auth.d.ts +14 -0
- package/dist/provider/auth.d.ts.map +1 -0
- package/dist/provider/auth.js +53 -0
- package/dist/provider/auth.js.map +1 -0
- package/dist/provider/index.d.ts +12 -0
- package/dist/provider/index.d.ts.map +1 -0
- package/dist/provider/index.js +134 -0
- package/dist/provider/index.js.map +1 -0
- package/dist/provider/route.d.ts +10 -0
- package/dist/provider/route.d.ts.map +1 -0
- package/dist/provider/route.js +19 -0
- package/dist/provider/route.js.map +1 -0
- package/dist/provider/stream.d.ts +10 -0
- package/dist/provider/stream.d.ts.map +1 -0
- package/dist/provider/stream.js +120 -0
- package/dist/provider/stream.js.map +1 -0
- package/dist/provider/synthetic.d.ts +13 -0
- package/dist/provider/synthetic.d.ts.map +1 -0
- package/dist/provider/synthetic.js +59 -0
- package/dist/provider/synthetic.js.map +1 -0
- package/dist/provider/upstream/anthropic.d.ts +13 -0
- package/dist/provider/upstream/anthropic.d.ts.map +1 -0
- package/dist/provider/upstream/anthropic.js +62 -0
- package/dist/provider/upstream/anthropic.js.map +1 -0
- package/dist/provider/upstream/openai.d.ts +17 -0
- package/dist/provider/upstream/openai.d.ts.map +1 -0
- package/dist/provider/upstream/openai.js +75 -0
- package/dist/provider/upstream/openai.js.map +1 -0
- package/dist/source.d.ts +35 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +41 -0
- package/dist/source.js.map +1 -0
- package/dist/state.d.ts +56 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +178 -0
- package/dist/state.js.map +1 -0
- package/dist/store.d.ts +23 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +68 -0
- package/dist/store.js.map +1 -0
- package/dist/tools/index.d.ts +13 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +63 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +98 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/openclaw.plugin.json +44 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/provider/upstream/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,wBAAuB,eAAe,CACpC,OAAO,EAAE,sBAAsB,GAC9B,cAAc,CAAC,GAAG,CAAC,CAgErB"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic Messages API upstream transport
|
|
3
|
+
*/
|
|
4
|
+
export async function* streamAnthropic(options) {
|
|
5
|
+
const { apiKey, model, messages, max_tokens = 4096, stream = true, ...rest } = options;
|
|
6
|
+
const url = "https://api.anthropic.com/v1/messages";
|
|
7
|
+
// 30s timeout
|
|
8
|
+
const controller = new AbortController();
|
|
9
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
10
|
+
try {
|
|
11
|
+
const response = await fetch(url, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
headers: {
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
"x-api-key": apiKey,
|
|
16
|
+
"anthropic-version": "2023-06-01",
|
|
17
|
+
},
|
|
18
|
+
body: JSON.stringify({
|
|
19
|
+
model,
|
|
20
|
+
messages,
|
|
21
|
+
max_tokens,
|
|
22
|
+
stream,
|
|
23
|
+
...rest,
|
|
24
|
+
}),
|
|
25
|
+
signal: controller.signal,
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
const errorText = await response.text();
|
|
29
|
+
throw new Error(`Anthropic upstream error ${response.status}: ${errorText}`);
|
|
30
|
+
}
|
|
31
|
+
if (!response.body) {
|
|
32
|
+
throw new Error("Anthropic upstream returned empty body");
|
|
33
|
+
}
|
|
34
|
+
const reader = response.body.getReader();
|
|
35
|
+
const decoder = new TextDecoder();
|
|
36
|
+
let buffer = "";
|
|
37
|
+
while (true) {
|
|
38
|
+
const { done, value } = await reader.read();
|
|
39
|
+
if (done)
|
|
40
|
+
break;
|
|
41
|
+
buffer += decoder.decode(value, { stream: true });
|
|
42
|
+
const lines = buffer.split("\n");
|
|
43
|
+
buffer = lines.pop() ?? "";
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
const trimmed = line.trim();
|
|
46
|
+
if (!trimmed || !trimmed.startsWith("data: "))
|
|
47
|
+
continue;
|
|
48
|
+
const data = trimmed.slice("data: ".length);
|
|
49
|
+
try {
|
|
50
|
+
yield JSON.parse(data);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Skip invalid JSON
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
clearTimeout(timeoutId);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/provider/upstream/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,eAAe,CACpC,OAA+B;IAE/B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAEvF,MAAM,GAAG,GAAG,uCAAuC,CAAC;IAEpD,cAAc;IACd,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IAE/D,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,MAAM;gBACnB,mBAAmB,EAAE,YAAY;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK;gBACL,QAAQ;gBACR,UAAU;gBACV,MAAM;gBACN,GAAG,IAAI;aACR,CAAC;YACF,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAEhB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAExD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAE5C,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;gBAAC,MAAM,CAAC;oBACP,oBAAoB;gBACtB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible upstream transport
|
|
3
|
+
*
|
|
4
|
+
* Supports /v1/chat/completions
|
|
5
|
+
* Compatible with OpenRouter, DeepSeek, Qwen and other OpenAI-compatible providers
|
|
6
|
+
*/
|
|
7
|
+
export interface OpenAiStreamOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
apiKey: string;
|
|
10
|
+
model: string;
|
|
11
|
+
messages: any[];
|
|
12
|
+
stream?: boolean;
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export declare function streamOpenAi(options: OpenAiStreamOptions): AsyncGenerator<any>;
|
|
16
|
+
export declare function getOpenAiBaseUrl(upstream: string): string;
|
|
17
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/provider/upstream/openai.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,wBAAuB,YAAY,CACjC,OAAO,EAAE,mBAAmB,GAC3B,cAAc,CAAC,GAAG,CAAC,CAgErB;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASzD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible upstream transport
|
|
3
|
+
*
|
|
4
|
+
* Supports /v1/chat/completions
|
|
5
|
+
* Compatible with OpenRouter, DeepSeek, Qwen and other OpenAI-compatible providers
|
|
6
|
+
*/
|
|
7
|
+
export async function* streamOpenAi(options) {
|
|
8
|
+
const { baseUrl, apiKey, model, messages, stream = true, ...rest } = options;
|
|
9
|
+
const url = `${baseUrl}/v1/chat/completions`;
|
|
10
|
+
// 30s timeout
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timeoutId = setTimeout(() => controller.abort(), 30_000);
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
Authorization: `Bearer ${apiKey}`,
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({
|
|
21
|
+
model,
|
|
22
|
+
messages,
|
|
23
|
+
stream,
|
|
24
|
+
...rest,
|
|
25
|
+
}),
|
|
26
|
+
signal: controller.signal,
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
const errorText = await response.text();
|
|
30
|
+
throw new Error(`OpenAI upstream error ${response.status}: ${errorText}`);
|
|
31
|
+
}
|
|
32
|
+
if (!response.body) {
|
|
33
|
+
throw new Error("OpenAI upstream returned empty body");
|
|
34
|
+
}
|
|
35
|
+
const reader = response.body.getReader();
|
|
36
|
+
const decoder = new TextDecoder();
|
|
37
|
+
let buffer = "";
|
|
38
|
+
while (true) {
|
|
39
|
+
const { done, value } = await reader.read();
|
|
40
|
+
if (done)
|
|
41
|
+
break;
|
|
42
|
+
buffer += decoder.decode(value, { stream: true });
|
|
43
|
+
const lines = buffer.split("\n");
|
|
44
|
+
buffer = lines.pop() ?? "";
|
|
45
|
+
for (const line of lines) {
|
|
46
|
+
const trimmed = line.trim();
|
|
47
|
+
if (!trimmed || !trimmed.startsWith("data: "))
|
|
48
|
+
continue;
|
|
49
|
+
const data = trimmed.slice("data: ".length);
|
|
50
|
+
if (data === "[DONE]")
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
yield JSON.parse(data);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// Skip invalid JSON
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
// Reader is released in the normal flow, no need to releaseLock here
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function getOpenAiBaseUrl(upstream) {
|
|
67
|
+
const baseUrls = {
|
|
68
|
+
openai: "https://api.openai.com",
|
|
69
|
+
openrouter: "https://openrouter.ai/api",
|
|
70
|
+
deepseek: "https://api.deepseek.com",
|
|
71
|
+
qwen: "https://dashscope.aliyuncs.com/compatible-mode",
|
|
72
|
+
};
|
|
73
|
+
return baseUrls[upstream] ?? `https://api.${upstream}.com`;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/provider/upstream/openai.ts"],"names":[],"mappings":"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"}
|
package/dist/source.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source key resolution
|
|
3
|
+
*
|
|
4
|
+
* Priority:
|
|
5
|
+
* 1. agentId + sessionId
|
|
6
|
+
* 2. sessionKey
|
|
7
|
+
* 3. workspaceDir + provider + model
|
|
8
|
+
* 4. provider + model
|
|
9
|
+
*/
|
|
10
|
+
export interface HookContext {
|
|
11
|
+
agentId?: string;
|
|
12
|
+
sessionId?: string;
|
|
13
|
+
sessionKey?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ModelCallEvent {
|
|
16
|
+
runId?: string;
|
|
17
|
+
callId?: string;
|
|
18
|
+
sessionKey?: string;
|
|
19
|
+
sessionId?: string;
|
|
20
|
+
provider: string;
|
|
21
|
+
model: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ProviderContext {
|
|
24
|
+
workspaceDir?: string;
|
|
25
|
+
provider?: string;
|
|
26
|
+
modelId?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface RouteInfo {
|
|
29
|
+
upstream: string;
|
|
30
|
+
model: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function sourceFromHookContext(event: Partial<HookContext>, ctx: Partial<HookContext>): string;
|
|
33
|
+
export declare function sourceFromModelCall(event: ModelCallEvent, ctx: Partial<HookContext>): string;
|
|
34
|
+
export declare function sourceFromProviderContext(ctx: ProviderContext, route: RouteInfo): string;
|
|
35
|
+
//# sourceMappingURL=source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,EAC3B,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,GACxB,MAAM,CAcR;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,GACxB,MAAM,CAWR;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,SAAS,GACf,MAAM,CAQR"}
|
package/dist/source.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source key resolution
|
|
3
|
+
*
|
|
4
|
+
* Priority:
|
|
5
|
+
* 1. agentId + sessionId
|
|
6
|
+
* 2. sessionKey
|
|
7
|
+
* 3. workspaceDir + provider + model
|
|
8
|
+
* 4. provider + model
|
|
9
|
+
*/
|
|
10
|
+
export function sourceFromHookContext(event, ctx) {
|
|
11
|
+
const agentId = event.agentId ?? ctx.agentId;
|
|
12
|
+
const sessionId = event.sessionId ?? ctx.sessionId;
|
|
13
|
+
if (agentId && sessionId) {
|
|
14
|
+
return `${agentId}/${sessionId}`;
|
|
15
|
+
}
|
|
16
|
+
const sessionKey = event.sessionKey ?? ctx.sessionKey;
|
|
17
|
+
if (sessionKey) {
|
|
18
|
+
return sessionKey;
|
|
19
|
+
}
|
|
20
|
+
return "unknown";
|
|
21
|
+
}
|
|
22
|
+
export function sourceFromModelCall(event, ctx) {
|
|
23
|
+
if (event.sessionId) {
|
|
24
|
+
const agentId = ctx.agentId ?? "unknown";
|
|
25
|
+
return `${agentId}/${event.sessionId}`;
|
|
26
|
+
}
|
|
27
|
+
if (event.sessionKey) {
|
|
28
|
+
return event.sessionKey;
|
|
29
|
+
}
|
|
30
|
+
return `${event.provider}/${event.model}`;
|
|
31
|
+
}
|
|
32
|
+
export function sourceFromProviderContext(ctx, route) {
|
|
33
|
+
if (ctx.workspaceDir) {
|
|
34
|
+
// Use last-level directory name instead of full path to avoid leaking user file paths
|
|
35
|
+
const parts = ctx.workspaceDir.replace(/\\/g, "/").split("/").filter(Boolean);
|
|
36
|
+
const basename = parts[parts.length - 1] || "ws";
|
|
37
|
+
return `${basename}/${route.upstream}/${route.model}`;
|
|
38
|
+
}
|
|
39
|
+
return `${route.upstream}/${route.model}`;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA4BH,MAAM,UAAU,qBAAqB,CACnC,KAA2B,EAC3B,GAAyB;IAEzB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC;IAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC;IAEnD,IAAI,OAAO,IAAI,SAAS,EAAE,CAAC;QACzB,OAAO,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC;IACtD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAqB,EACrB,GAAyB;IAEzB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;QACzC,OAAO,GAAG,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC,UAAU,CAAC;IAC1B,CAAC;IAED,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,GAAoB,EACpB,KAAgB;IAEhB,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC;QACrB,sFAAsF;QACtF,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC;QACjD,OAAO,GAAG,QAAQ,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;AAC5C,CAAC"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global state management (in-memory)
|
|
3
|
+
*/
|
|
4
|
+
import type { RunState, CallState, GlobalStats, SourceKey, FirewallConfig, PrecheckResult } from "./types.js";
|
|
5
|
+
import { Breaker } from "./breaker.js";
|
|
6
|
+
export declare class FirewallState {
|
|
7
|
+
readonly config: FirewallConfig;
|
|
8
|
+
readonly breaker: Breaker;
|
|
9
|
+
readonly globalStats: GlobalStats;
|
|
10
|
+
private runs;
|
|
11
|
+
private sourceStats;
|
|
12
|
+
private today;
|
|
13
|
+
private cleanupTimer;
|
|
14
|
+
private static readonly MAX_RUNS;
|
|
15
|
+
private static readonly CLEANUP_INTERVAL_MS;
|
|
16
|
+
private static readonly RUN_EXPIRY_MS;
|
|
17
|
+
private checkDayReset;
|
|
18
|
+
constructor(config?: Partial<FirewallConfig>);
|
|
19
|
+
private startCleanupTimer;
|
|
20
|
+
/**
|
|
21
|
+
* Purge runs older than RUN_EXPIRY_MS and enforce maxSize limit
|
|
22
|
+
*/
|
|
23
|
+
private purgeOldRuns;
|
|
24
|
+
/**
|
|
25
|
+
* Stop cleanup timer (for graceful shutdown)
|
|
26
|
+
*/
|
|
27
|
+
stopCleanupTimer(): void;
|
|
28
|
+
getRun(runId: string): RunState | undefined;
|
|
29
|
+
getOrCreateRun(runId: string, source: SourceKey, sessionId?: string, sessionKey?: string): RunState;
|
|
30
|
+
addCallToRun(runId: string, callId: string, call: CallState): void;
|
|
31
|
+
updateRunCost(runId: string, cost: number): void;
|
|
32
|
+
updateSourceStats(source: SourceKey, tokens: number): void;
|
|
33
|
+
/**
|
|
34
|
+
* Mark a run for cleanup (actual deletion happens via scheduled purgeOldRuns)
|
|
35
|
+
* This method is kept for compatibility with existing callers
|
|
36
|
+
*/
|
|
37
|
+
cleanupRun(runId: string): void;
|
|
38
|
+
setEmergencyStop(enabled: boolean): void;
|
|
39
|
+
setMode(mode: "observe" | "protect"): void;
|
|
40
|
+
isLimitExceeded(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Unified precheck for hook and provider layers
|
|
43
|
+
* Returns { allow: true } if all checks pass, otherwise { allow: false, reason, layer }
|
|
44
|
+
*/
|
|
45
|
+
precheck(source: SourceKey): PrecheckResult;
|
|
46
|
+
getTodayTokens(): number;
|
|
47
|
+
/** Active run summary */
|
|
48
|
+
getActiveRuns(): {
|
|
49
|
+
runId: string;
|
|
50
|
+
source: string;
|
|
51
|
+
calls: number;
|
|
52
|
+
tokens: number;
|
|
53
|
+
status: string;
|
|
54
|
+
}[];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,WAAW,EACX,SAAS,EACT,cAAc,EACd,cAAc,EACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,qBAAa,aAAa;IACxB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,WAAW,CAAiD;IACpE,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,YAAY,CAA+C;IAEnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAO;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAU;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAc;IAEnD,OAAO,CAAC,aAAa;gBAUT,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM;IAahD,OAAO,CAAC,iBAAiB;IAUzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAqBpB;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAOxB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI3C,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,QAAQ;IAkBX,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAOlE,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAOhD,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAS1D;;;OAGG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAQ/B,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIxC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,IAAI;IAI1C,eAAe,IAAI,OAAO;IAK1B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,cAAc;IAsB3C,cAAc,IAAI,MAAM;IAIxB,yBAAyB;IACzB,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE;CAcpG"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global state management (in-memory)
|
|
3
|
+
*/
|
|
4
|
+
import { Breaker } from "./breaker.js";
|
|
5
|
+
import { resolveConfig } from "./config.js";
|
|
6
|
+
export class FirewallState {
|
|
7
|
+
config;
|
|
8
|
+
breaker;
|
|
9
|
+
globalStats;
|
|
10
|
+
runs = new Map();
|
|
11
|
+
sourceStats = new Map();
|
|
12
|
+
today = new Date().toDateString();
|
|
13
|
+
cleanupTimer = null;
|
|
14
|
+
static MAX_RUNS = 100;
|
|
15
|
+
static CLEANUP_INTERVAL_MS = 10_000;
|
|
16
|
+
static RUN_EXPIRY_MS = 5 * 60_000; // 5 minutes
|
|
17
|
+
checkDayReset() {
|
|
18
|
+
const now = new Date().toDateString();
|
|
19
|
+
if (now !== this.today) {
|
|
20
|
+
this.today = now;
|
|
21
|
+
this.globalStats.todayTokens = 0;
|
|
22
|
+
this.globalStats.todayBlocked = 0;
|
|
23
|
+
this.sourceStats.clear();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
constructor(config = {}) {
|
|
27
|
+
this.config = resolveConfig(config);
|
|
28
|
+
this.breaker = new Breaker(this.config);
|
|
29
|
+
this.globalStats = {
|
|
30
|
+
emergencyStop: false,
|
|
31
|
+
mode: "observe",
|
|
32
|
+
todayTokens: 0,
|
|
33
|
+
todayBlocked: 0,
|
|
34
|
+
todaySavedEstimate: 0,
|
|
35
|
+
};
|
|
36
|
+
this.startCleanupTimer();
|
|
37
|
+
}
|
|
38
|
+
startCleanupTimer() {
|
|
39
|
+
this.cleanupTimer = setInterval(() => {
|
|
40
|
+
this.purgeOldRuns();
|
|
41
|
+
}, FirewallState.CLEANUP_INTERVAL_MS);
|
|
42
|
+
if (this.cleanupTimer.unref) {
|
|
43
|
+
this.cleanupTimer.unref();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Purge runs older than RUN_EXPIRY_MS and enforce maxSize limit
|
|
48
|
+
*/
|
|
49
|
+
purgeOldRuns() {
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
// Delete runs older than 5 minutes
|
|
52
|
+
for (const [runId, run] of this.runs) {
|
|
53
|
+
if (now - run.startedAt > FirewallState.RUN_EXPIRY_MS) {
|
|
54
|
+
this.runs.delete(runId);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Enforce maxSize limit: delete oldest runs if exceeds limit
|
|
58
|
+
if (this.runs.size > FirewallState.MAX_RUNS) {
|
|
59
|
+
const sortedRuns = [...this.runs.entries()]
|
|
60
|
+
.sort((a, b) => a[1].startedAt - b[1].startedAt);
|
|
61
|
+
const toDelete = sortedRuns.slice(0, this.runs.size - FirewallState.MAX_RUNS);
|
|
62
|
+
for (const [runId] of toDelete) {
|
|
63
|
+
this.runs.delete(runId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Stop cleanup timer (for graceful shutdown)
|
|
69
|
+
*/
|
|
70
|
+
stopCleanupTimer() {
|
|
71
|
+
if (this.cleanupTimer) {
|
|
72
|
+
clearInterval(this.cleanupTimer);
|
|
73
|
+
this.cleanupTimer = null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
getRun(runId) {
|
|
77
|
+
return this.runs.get(runId);
|
|
78
|
+
}
|
|
79
|
+
getOrCreateRun(runId, source, sessionId, sessionKey) {
|
|
80
|
+
if (!this.runs.has(runId)) {
|
|
81
|
+
this.runs.set(runId, {
|
|
82
|
+
runId,
|
|
83
|
+
sessionId,
|
|
84
|
+
sessionKey,
|
|
85
|
+
source,
|
|
86
|
+
startedAt: Date.now(),
|
|
87
|
+
calls: new Map(),
|
|
88
|
+
llmCallTimestamps: [],
|
|
89
|
+
cumulativeCost: 0,
|
|
90
|
+
promptHashCounts: new Map(),
|
|
91
|
+
status: "healthy",
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return this.runs.get(runId);
|
|
95
|
+
}
|
|
96
|
+
addCallToRun(runId, callId, call) {
|
|
97
|
+
const run = this.runs.get(runId);
|
|
98
|
+
if (run) {
|
|
99
|
+
run.calls.set(callId, call);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
updateRunCost(runId, cost) {
|
|
103
|
+
const run = this.runs.get(runId);
|
|
104
|
+
if (run) {
|
|
105
|
+
run.cumulativeCost += cost;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
updateSourceStats(source, tokens) {
|
|
109
|
+
this.checkDayReset();
|
|
110
|
+
if (!this.sourceStats.has(source)) {
|
|
111
|
+
this.sourceStats.set(source, { todayTokens: 0 });
|
|
112
|
+
}
|
|
113
|
+
this.sourceStats.get(source).todayTokens += tokens;
|
|
114
|
+
this.globalStats.todayTokens += tokens;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Mark a run for cleanup (actual deletion happens via scheduled purgeOldRuns)
|
|
118
|
+
* This method is kept for compatibility with existing callers
|
|
119
|
+
*/
|
|
120
|
+
cleanupRun(runId) {
|
|
121
|
+
// No immediate deletion - scheduled cleanup will handle it
|
|
122
|
+
// Optionally force delete if runs exceeds maxSize
|
|
123
|
+
if (this.runs.size > FirewallState.MAX_RUNS) {
|
|
124
|
+
this.runs.delete(runId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
setEmergencyStop(enabled) {
|
|
128
|
+
this.globalStats.emergencyStop = enabled;
|
|
129
|
+
}
|
|
130
|
+
setMode(mode) {
|
|
131
|
+
this.globalStats.mode = mode;
|
|
132
|
+
}
|
|
133
|
+
isLimitExceeded() {
|
|
134
|
+
if (this.config.dailyTokenLimit == null)
|
|
135
|
+
return false;
|
|
136
|
+
return this.globalStats.todayTokens >= this.config.dailyTokenLimit;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Unified precheck for hook and provider layers
|
|
140
|
+
* Returns { allow: true } if all checks pass, otherwise { allow: false, reason, layer }
|
|
141
|
+
*/
|
|
142
|
+
precheck(source) {
|
|
143
|
+
// Emergency stop is a global override - always blocks regardless of mode
|
|
144
|
+
if (this.globalStats.emergencyStop) {
|
|
145
|
+
return { allow: false, reason: "emergency_stop", layer: "hook" };
|
|
146
|
+
}
|
|
147
|
+
// Observe mode bypasses all other checks
|
|
148
|
+
if (this.globalStats.mode === "observe") {
|
|
149
|
+
return { allow: true, layer: "hook" };
|
|
150
|
+
}
|
|
151
|
+
if (this.isLimitExceeded()) {
|
|
152
|
+
return { allow: false, reason: "daily_token_limit", layer: "hook" };
|
|
153
|
+
}
|
|
154
|
+
if (this.breaker.isCoolingDown(source)) {
|
|
155
|
+
return { allow: false, reason: this.breaker.getBlockedReason(source) ?? "source_cooldown", layer: "provider" };
|
|
156
|
+
}
|
|
157
|
+
return { allow: true, layer: "hook" };
|
|
158
|
+
}
|
|
159
|
+
getTodayTokens() {
|
|
160
|
+
return this.globalStats.todayTokens;
|
|
161
|
+
}
|
|
162
|
+
/** Active run summary */
|
|
163
|
+
getActiveRuns() {
|
|
164
|
+
const result = [];
|
|
165
|
+
for (const [id, run] of this.runs) {
|
|
166
|
+
result.push({
|
|
167
|
+
runId: id,
|
|
168
|
+
source: run.source,
|
|
169
|
+
calls: run.calls.size,
|
|
170
|
+
tokens: run.cumulativeCost,
|
|
171
|
+
status: run.status,
|
|
172
|
+
reason: run.reason,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSONL event storage (async, non-blocking hook)
|
|
3
|
+
*/
|
|
4
|
+
import type { FirewallEvent } from "./types.js";
|
|
5
|
+
export type { FirewallEvent };
|
|
6
|
+
export declare class EventStore {
|
|
7
|
+
private buffer;
|
|
8
|
+
private flushTimer;
|
|
9
|
+
private dirReady;
|
|
10
|
+
constructor();
|
|
11
|
+
private ensureDir;
|
|
12
|
+
append(event: Omit<FirewallEvent, "timestamp">): void;
|
|
13
|
+
private startFlushTimer;
|
|
14
|
+
/**
|
|
15
|
+
* Flush buffer to disk (synchronous, copy-and-replace pattern)
|
|
16
|
+
* This prevents concurrent flushes from double-writing or interleaving events
|
|
17
|
+
*/
|
|
18
|
+
flush(): void;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
getStateDir(): string;
|
|
21
|
+
getEventsFilePath(): string;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,CAAC;AAQ9B,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAAS;;IAMzB,OAAO,CAAC,SAAS;IAMjB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,IAAI;IAQrD,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAYP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,WAAW,IAAI,MAAM;IAIrB,iBAAiB,IAAI,MAAM;CAG5B"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSONL event storage (async, non-blocking hook)
|
|
3
|
+
*/
|
|
4
|
+
import { writeFileSync, mkdirSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
const FLUSH_INTERVAL_MS = 1000;
|
|
8
|
+
const STATE_DIR = process.env.OPENCLAW_STATE_DIR
|
|
9
|
+
? join(process.env.OPENCLAW_STATE_DIR, "plugins", "mapick-firewall")
|
|
10
|
+
: join(homedir(), ".openclaw", "plugins", "mapick-firewall");
|
|
11
|
+
const EVENTS_FILE = join(STATE_DIR, "events.jsonl");
|
|
12
|
+
export class EventStore {
|
|
13
|
+
buffer = [];
|
|
14
|
+
flushTimer = null;
|
|
15
|
+
dirReady = false;
|
|
16
|
+
constructor() {
|
|
17
|
+
this.startFlushTimer();
|
|
18
|
+
}
|
|
19
|
+
ensureDir() {
|
|
20
|
+
if (this.dirReady)
|
|
21
|
+
return;
|
|
22
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
23
|
+
this.dirReady = true;
|
|
24
|
+
}
|
|
25
|
+
append(event) {
|
|
26
|
+
const fullEvent = {
|
|
27
|
+
...event,
|
|
28
|
+
timestamp: Date.now(),
|
|
29
|
+
};
|
|
30
|
+
this.buffer.push(fullEvent);
|
|
31
|
+
}
|
|
32
|
+
startFlushTimer() {
|
|
33
|
+
this.flushTimer = setInterval(() => {
|
|
34
|
+
this.flush();
|
|
35
|
+
}, FLUSH_INTERVAL_MS);
|
|
36
|
+
if (this.flushTimer.unref) {
|
|
37
|
+
this.flushTimer.unref();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Flush buffer to disk (synchronous, copy-and-replace pattern)
|
|
42
|
+
* This prevents concurrent flushes from double-writing or interleaving events
|
|
43
|
+
*/
|
|
44
|
+
flush() {
|
|
45
|
+
if (this.buffer.length === 0)
|
|
46
|
+
return;
|
|
47
|
+
// Copy-and-replace: grab current buffer and clear it atomically
|
|
48
|
+
const batch = this.buffer;
|
|
49
|
+
this.buffer = [];
|
|
50
|
+
this.ensureDir();
|
|
51
|
+
const lines = batch.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
52
|
+
writeFileSync(EVENTS_FILE, lines, "utf-8");
|
|
53
|
+
}
|
|
54
|
+
async close() {
|
|
55
|
+
if (this.flushTimer) {
|
|
56
|
+
clearInterval(this.flushTimer);
|
|
57
|
+
this.flushTimer = null;
|
|
58
|
+
}
|
|
59
|
+
this.flush();
|
|
60
|
+
}
|
|
61
|
+
getStateDir() {
|
|
62
|
+
return STATE_DIR;
|
|
63
|
+
}
|
|
64
|
+
getEventsFilePath() {
|
|
65
|
+
return EVENTS_FILE;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAKlC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB;IAC9C,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,SAAS,EAAE,iBAAiB,CAAC;IACpE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAEpD,MAAM,OAAO,UAAU;IACb,MAAM,GAAoB,EAAE,CAAC;IAC7B,UAAU,GAA0C,IAAI,CAAC;IACzD,QAAQ,GAAG,KAAK,CAAC;IAEzB;QACE,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEO,SAAS;QACf,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,KAAuC;QAC5C,MAAM,SAAS,GAAkB;YAC/B,GAAG,KAAK;YACR,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,iBAAiB,CAAC,CAAC;QAEtB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAC1B,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAErC,gEAAgE;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACpE,aAAa,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED,WAAW;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iBAAiB;QACf,OAAO,WAAW,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Tools registration — users control Cost Firewall via conversation
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* /firewall status → view status
|
|
6
|
+
* /firewall stop → emergency breaker
|
|
7
|
+
* /firewall resume → resume
|
|
8
|
+
* /firewall log → view recent events
|
|
9
|
+
*/
|
|
10
|
+
import type { FirewallState } from "../state.js";
|
|
11
|
+
import type { EventStore } from "../store.js";
|
|
12
|
+
export declare function registerTools(api: any, state: FirewallState, store: EventStore): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CA+CrF"}
|