usertrust-openclaw 1.2.5 → 1.3.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/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -2
- package/dist/index.js.map +1 -1
- package/dist/stream-governor.d.ts.map +1 -1
- package/dist/stream-governor.js +13 -2
- package/dist/stream-governor.js.map +1 -1
- package/dist/token-extractor.d.ts +38 -4
- package/dist/token-extractor.d.ts.map +1 -1
- package/dist/token-extractor.js +140 -5
- package/dist/token-extractor.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Governor } from "usertrust";
|
|
2
|
-
import type { OpenClawPluginApi, StreamFn, UsertrustPluginConfig } from "./types.js";
|
|
2
|
+
import type { OpenClawPluginApi, ProviderPlugin, StreamFn, UsertrustPluginConfig } from "./types.js";
|
|
3
3
|
export { wrapStreamWithGovernance, wrapCompleteWithGovernance } from "./stream-governor.js";
|
|
4
|
-
export { createAccumulator, extractUsageFromEvent } from "./token-extractor.js";
|
|
5
|
-
export type { StreamEvent, StreamFn, StreamContext, StreamUsage, UsertrustPluginConfig, GovernedStreamMeta, } from "./types.js";
|
|
4
|
+
export { createAccumulator, extractUsageFromEvent, extractUsageFromProviderChunk, extractTextDeltaLength, } from "./token-extractor.js";
|
|
5
|
+
export type { StreamEvent, StreamFn, StreamContext, StreamUsage, UsertrustPluginConfig, GovernedStreamMeta, ProviderPlugin, } from "./types.js";
|
|
6
6
|
/**
|
|
7
7
|
* OpenClaw plugin entry point.
|
|
8
8
|
*
|
|
@@ -10,6 +10,27 @@ export type { StreamEvent, StreamFn, StreamContext, StreamUsage, UsertrustPlugin
|
|
|
10
10
|
* governance engine and registers the stream wrapper.
|
|
11
11
|
*/
|
|
12
12
|
export default function register(api: OpenClawPluginApi): void;
|
|
13
|
+
/**
|
|
14
|
+
* Factory: build an OpenClaw `ProviderPlugin` bound to a usertrust config.
|
|
15
|
+
*
|
|
16
|
+
* Use this when programmatically wiring usertrust into an OpenClaw runtime
|
|
17
|
+
* (rather than going through the auto-discovery `register()` default).
|
|
18
|
+
* The returned plugin's `wrapStreamFn` follows OpenClaw's middleware shape:
|
|
19
|
+
* `(next: StreamFn) => StreamFn`.
|
|
20
|
+
*
|
|
21
|
+
* Init is lazy — the governor is created on the first wrapped call, not
|
|
22
|
+
* at plugin construction time. This matches OpenClaw's lifecycle (plugins
|
|
23
|
+
* register synchronously; governance needs async init).
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* import { createUsertrustPlugin } from "usertrust-openclaw";
|
|
27
|
+
*
|
|
28
|
+
* const plugin = createUsertrustPlugin({ budget: 100_000, dryRun: true });
|
|
29
|
+
* const wrapped = plugin.wrapStreamFn!(rawStreamFn);
|
|
30
|
+
* for await (const event of wrapped(model, context)) { ... }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare function createUsertrustPlugin(config: UsertrustPluginConfig): ProviderPlugin;
|
|
13
34
|
/**
|
|
14
35
|
* Programmatic API for non-OpenClaw usage.
|
|
15
36
|
*
|
|
@@ -17,7 +38,7 @@ export default function register(api: OpenClawPluginApi): void;
|
|
|
17
38
|
* pi-ai setup without the full OpenClaw plugin system.
|
|
18
39
|
*
|
|
19
40
|
* ```ts
|
|
20
|
-
* import { createGovernedStreamFn } from "
|
|
41
|
+
* import { createGovernedStreamFn } from "usertrust-openclaw";
|
|
21
42
|
*
|
|
22
43
|
* const governed = await createGovernedStreamFn(myStreamFn, {
|
|
23
44
|
* budget: 100_000,
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,KAAK,EACX,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,KAAK,EACX,iBAAiB,EACjB,cAAc,EAGd,QAAQ,EACR,qBAAqB,EACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EACN,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACX,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,GACd,MAAM,YAAY,CAAC;AAKpB;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA0B7D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,cAAc,CAWnF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,sBAAsB,CAC3C,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,qBAAqB,GAC3B,OAAO,CAAC;IAAE,gBAAgB,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,CAI7D;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,QAAQ,GAAG,IAAI,CAE7C;AAED;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAM9C"}
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ import { createGovernor } from "usertrust";
|
|
|
34
34
|
import { wrapStreamWithGovernance } from "./stream-governor.js";
|
|
35
35
|
// Re-export for consumers
|
|
36
36
|
export { wrapStreamWithGovernance, wrapCompleteWithGovernance } from "./stream-governor.js";
|
|
37
|
-
export { createAccumulator, extractUsageFromEvent } from "./token-extractor.js";
|
|
37
|
+
export { createAccumulator, extractUsageFromEvent, extractUsageFromProviderChunk, extractTextDeltaLength, } from "./token-extractor.js";
|
|
38
38
|
/** Active governor instance — singleton per plugin lifecycle. */
|
|
39
39
|
let governor = null;
|
|
40
40
|
/**
|
|
@@ -66,6 +66,36 @@ export default function register(api) {
|
|
|
66
66
|
};
|
|
67
67
|
api.registerProvider(plugin);
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Factory: build an OpenClaw `ProviderPlugin` bound to a usertrust config.
|
|
71
|
+
*
|
|
72
|
+
* Use this when programmatically wiring usertrust into an OpenClaw runtime
|
|
73
|
+
* (rather than going through the auto-discovery `register()` default).
|
|
74
|
+
* The returned plugin's `wrapStreamFn` follows OpenClaw's middleware shape:
|
|
75
|
+
* `(next: StreamFn) => StreamFn`.
|
|
76
|
+
*
|
|
77
|
+
* Init is lazy — the governor is created on the first wrapped call, not
|
|
78
|
+
* at plugin construction time. This matches OpenClaw's lifecycle (plugins
|
|
79
|
+
* register synchronously; governance needs async init).
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* import { createUsertrustPlugin } from "usertrust-openclaw";
|
|
83
|
+
*
|
|
84
|
+
* const plugin = createUsertrustPlugin({ budget: 100_000, dryRun: true });
|
|
85
|
+
* const wrapped = plugin.wrapStreamFn!(rawStreamFn);
|
|
86
|
+
* for await (const event of wrapped(model, context)) { ... }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export function createUsertrustPlugin(config) {
|
|
90
|
+
const getGovernor = lazyGovernor(config);
|
|
91
|
+
return {
|
|
92
|
+
id: "usertrust",
|
|
93
|
+
label: "usertrust Governance",
|
|
94
|
+
wrapStreamFn(next) {
|
|
95
|
+
return (model, context, options) => governedStreamLazy(getGovernor, next, model, context, options);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
69
99
|
/**
|
|
70
100
|
* Programmatic API for non-OpenClaw usage.
|
|
71
101
|
*
|
|
@@ -73,7 +103,7 @@ export default function register(api) {
|
|
|
73
103
|
* pi-ai setup without the full OpenClaw plugin system.
|
|
74
104
|
*
|
|
75
105
|
* ```ts
|
|
76
|
-
* import { createGovernedStreamFn } from "
|
|
106
|
+
* import { createGovernedStreamFn } from "usertrust-openclaw";
|
|
77
107
|
*
|
|
78
108
|
* const governed = await createGovernedStreamFn(myStreamFn, {
|
|
79
109
|
* budget: 100_000,
|
|
@@ -124,6 +154,7 @@ function initGovernor(config) {
|
|
|
124
154
|
...(config.configPath != null ? { configPath: config.configPath } : {}),
|
|
125
155
|
...(config.proxy != null ? { proxy: config.proxy } : {}),
|
|
126
156
|
...(config.proxyKey != null ? { key: config.proxyKey } : {}),
|
|
157
|
+
...(config.vaultBase != null ? { vaultBase: config.vaultBase } : {}),
|
|
127
158
|
}).then((gov) => {
|
|
128
159
|
governor = gov;
|
|
129
160
|
return gov;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAA8B,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-governor.d.ts","sourceRoot":"","sources":["../src/stream-governor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAiB,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAQzF;
|
|
1
|
+
{"version":3,"file":"stream-governor.d.ts","sourceRoot":"","sources":["../src/stream-governor.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAiB,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAe,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAQzF;AAyDD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACzC,CAAC,SAAS;IAAE,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAEnE,UAAU,EAAE,CACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC7B,OAAO,CAAC,CAAC,CAAC,EACf,QAAQ,EAAE,QAAQ,GAChB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CA6C1F"}
|
package/dist/stream-governor.js
CHANGED
|
@@ -19,7 +19,14 @@ export function wrapStreamWithGovernance(streamFn, governor) {
|
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
21
|
async function* governedStream(streamFn, governor, model, context, options) {
|
|
22
|
-
//
|
|
22
|
+
// 1a. Pre-flight budget check.
|
|
23
|
+
// In dry-run mode (no TigerBeetle) the engine cannot enforce balance,
|
|
24
|
+
// so we explicitly refuse calls when budget_remaining ≤ 0. This matches
|
|
25
|
+
// the behaviour users expect from a "budget" config: hit zero, get cut off.
|
|
26
|
+
if (governor.budgetRemaining() <= 0) {
|
|
27
|
+
throw new Error(`usertrust: budget exhausted (${governor.budgetRemaining()} remaining); call denied`);
|
|
28
|
+
}
|
|
29
|
+
// 1b. Authorize — policy gate, PENDING hold
|
|
23
30
|
const auth = await governor.authorize({
|
|
24
31
|
model,
|
|
25
32
|
messages: context.messages,
|
|
@@ -60,7 +67,11 @@ async function* governedStream(streamFn, governor, model, context, options) {
|
|
|
60
67
|
*/
|
|
61
68
|
export function wrapCompleteWithGovernance(completeFn, governor) {
|
|
62
69
|
return async (model, context, options) => {
|
|
63
|
-
//
|
|
70
|
+
// 1a. Pre-flight budget check (see governedStream for rationale).
|
|
71
|
+
if (governor.budgetRemaining() <= 0) {
|
|
72
|
+
throw new Error(`usertrust: budget exhausted (${governor.budgetRemaining()} remaining); call denied`);
|
|
73
|
+
}
|
|
74
|
+
// 1b. Authorize
|
|
64
75
|
const auth = await governor.authorize({
|
|
65
76
|
model,
|
|
66
77
|
messages: context.messages,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-governor.js","sourceRoot":"","sources":["../src/stream-governor.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAgBjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAkB,EAAE,QAAkB;IAC9E,OAAO,CACN,KAAa,EACb,OAAsB,EACtB,OAAiC,EACJ,EAAE;QAC/B,OAAO,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC;AACH,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,cAAc,CAC7B,QAAkB,EAClB,QAAkB,EAClB,KAAa,EACb,OAAsB,EACtB,OAAiC;IAEjC,
|
|
1
|
+
{"version":3,"file":"stream-governor.js","sourceRoot":"","sources":["../src/stream-governor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* token-extractor.ts —
|
|
2
|
+
* token-extractor.ts — Stream Token Extraction
|
|
3
3
|
*
|
|
4
|
-
* Extracts token usage from pi-ai's normalized stream events
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Extracts token usage from pi-ai's normalized stream events AND from
|
|
5
|
+
* raw provider chunk shapes (Anthropic, OpenAI, Gemini) via duck-typing.
|
|
6
|
+
*
|
|
7
|
+
* pi-ai reports usage on `done` / `error` events. Raw provider chunks
|
|
8
|
+
* scatter usage across multiple shapes — we duck-type each one.
|
|
7
9
|
*/
|
|
8
10
|
import type { StreamEvent, StreamUsage } from "./types.js";
|
|
9
11
|
/** Accumulated usage from a pi-ai stream. */
|
|
@@ -13,6 +15,38 @@ export interface AccumulatedUsage {
|
|
|
13
15
|
chunksDelivered: number;
|
|
14
16
|
usageReported: boolean;
|
|
15
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Duck-type chunks from raw provider streams. We support:
|
|
20
|
+
*
|
|
21
|
+
* Anthropic:
|
|
22
|
+
* { type: "message_start", message: { usage: { input_tokens, output_tokens } } }
|
|
23
|
+
* { type: "message_delta", usage: { output_tokens } }
|
|
24
|
+
* { type: "content_block_delta", delta: { text } }
|
|
25
|
+
*
|
|
26
|
+
* OpenAI:
|
|
27
|
+
* { choices: [{ delta: { content } }], usage: { prompt_tokens, completion_tokens } }
|
|
28
|
+
*
|
|
29
|
+
* Gemini:
|
|
30
|
+
* { candidates: [{ content: { parts: [...] } }], usageMetadata: { promptTokenCount, candidatesTokenCount } }
|
|
31
|
+
*
|
|
32
|
+
* Returns null if the chunk is not a recognized usage-bearing shape.
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractUsageFromProviderChunk(chunk: unknown): StreamUsage | null;
|
|
35
|
+
/**
|
|
36
|
+
* Estimate output tokens from a streaming chunk's text delta.
|
|
37
|
+
* Used as a fallback when usage isn't reported. ~4 chars per token.
|
|
38
|
+
*
|
|
39
|
+
* Duck-types each provider's text delta shape:
|
|
40
|
+
* Anthropic: chunk.delta.text (content_block_delta)
|
|
41
|
+
* OpenAI: chunk.choices[0].delta.content
|
|
42
|
+
* Gemini: chunk.candidates[0].content.parts[0].text
|
|
43
|
+
* pi-ai: chunk.text (text_delta event)
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractTextDeltaLength(chunk: unknown): number;
|
|
46
|
+
/**
|
|
47
|
+
* Extract token usage from a pi-ai stream event.
|
|
48
|
+
* Returns non-zero usage only for `done` and `error` events.
|
|
49
|
+
*/
|
|
16
50
|
export declare function extractUsageFromEvent(event: StreamEvent): StreamUsage | null;
|
|
17
51
|
/**
|
|
18
52
|
* Creates a token accumulator for tracking usage across a stream.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-extractor.d.ts","sourceRoot":"","sources":["../src/token-extractor.ts"],"names":[],"mappings":"AAGA
|
|
1
|
+
{"version":3,"file":"token-extractor.d.ts","sourceRoot":"","sources":["../src/token-extractor.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACvB;AAUD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAqEhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsC7D;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAgB5E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI;IACpC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,MAAM,IAAI,gBAAgB,CAAC;CAC3B,CAsBA"}
|
package/dist/token-extractor.js
CHANGED
|
@@ -1,14 +1,149 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// Copyright 2026 Usertools, Inc.
|
|
3
|
-
/**
|
|
4
|
-
* Extract token usage from a pi-ai stream event.
|
|
5
|
-
* Returns non-zero usage only for `done` and `error` events.
|
|
6
|
-
*/
|
|
7
3
|
/** Max tokens to accept from a provider (prevents Infinity/overflow in cost math). */
|
|
8
4
|
const MAX_TOKENS = 2_000_000;
|
|
9
5
|
function clampTokens(n) {
|
|
10
|
-
|
|
6
|
+
if (!Number.isFinite(n))
|
|
7
|
+
return 0;
|
|
8
|
+
return Math.min(Math.max(0, Math.trunc(n)), MAX_TOKENS);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Duck-type chunks from raw provider streams. We support:
|
|
12
|
+
*
|
|
13
|
+
* Anthropic:
|
|
14
|
+
* { type: "message_start", message: { usage: { input_tokens, output_tokens } } }
|
|
15
|
+
* { type: "message_delta", usage: { output_tokens } }
|
|
16
|
+
* { type: "content_block_delta", delta: { text } }
|
|
17
|
+
*
|
|
18
|
+
* OpenAI:
|
|
19
|
+
* { choices: [{ delta: { content } }], usage: { prompt_tokens, completion_tokens } }
|
|
20
|
+
*
|
|
21
|
+
* Gemini:
|
|
22
|
+
* { candidates: [{ content: { parts: [...] } }], usageMetadata: { promptTokenCount, candidatesTokenCount } }
|
|
23
|
+
*
|
|
24
|
+
* Returns null if the chunk is not a recognized usage-bearing shape.
|
|
25
|
+
*/
|
|
26
|
+
export function extractUsageFromProviderChunk(chunk) {
|
|
27
|
+
if (chunk == null || typeof chunk !== "object")
|
|
28
|
+
return null;
|
|
29
|
+
const c = chunk;
|
|
30
|
+
// ── Anthropic message_start ──
|
|
31
|
+
if (c.type === "message_start" && typeof c.message === "object" && c.message != null) {
|
|
32
|
+
const msg = c.message;
|
|
33
|
+
const usage = msg.usage;
|
|
34
|
+
if (usage != null) {
|
|
35
|
+
const input = readNum(usage.input_tokens);
|
|
36
|
+
const output = readNum(usage.output_tokens);
|
|
37
|
+
if (input != null || output != null) {
|
|
38
|
+
return {
|
|
39
|
+
inputTokens: clampTokens(input ?? 0),
|
|
40
|
+
outputTokens: clampTokens(output ?? 0),
|
|
41
|
+
...(typeof usage.cache_read_input_tokens === "number"
|
|
42
|
+
? { cacheReadTokens: clampTokens(usage.cache_read_input_tokens) }
|
|
43
|
+
: {}),
|
|
44
|
+
...(typeof usage.cache_creation_input_tokens === "number"
|
|
45
|
+
? { cacheWriteTokens: clampTokens(usage.cache_creation_input_tokens) }
|
|
46
|
+
: {}),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// ── Anthropic message_delta (final usage) ──
|
|
52
|
+
if (c.type === "message_delta" && typeof c.usage === "object" && c.usage != null) {
|
|
53
|
+
const usage = c.usage;
|
|
54
|
+
const output = readNum(usage.output_tokens);
|
|
55
|
+
const input = readNum(usage.input_tokens);
|
|
56
|
+
if (output != null || input != null) {
|
|
57
|
+
return {
|
|
58
|
+
inputTokens: clampTokens(input ?? 0),
|
|
59
|
+
outputTokens: clampTokens(output ?? 0),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ── OpenAI usage (final chunk on stream_options.include_usage=true) ──
|
|
64
|
+
if (typeof c.usage === "object" && c.usage != null && Array.isArray(c.choices)) {
|
|
65
|
+
const usage = c.usage;
|
|
66
|
+
const prompt = readNum(usage.prompt_tokens);
|
|
67
|
+
const completion = readNum(usage.completion_tokens);
|
|
68
|
+
if (prompt != null || completion != null) {
|
|
69
|
+
return {
|
|
70
|
+
inputTokens: clampTokens(prompt ?? 0),
|
|
71
|
+
outputTokens: clampTokens(completion ?? 0),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// ── Gemini usageMetadata ──
|
|
76
|
+
if (typeof c.usageMetadata === "object" && c.usageMetadata != null) {
|
|
77
|
+
const meta = c.usageMetadata;
|
|
78
|
+
const prompt = readNum(meta.promptTokenCount);
|
|
79
|
+
const candidates = readNum(meta.candidatesTokenCount);
|
|
80
|
+
if (prompt != null || candidates != null) {
|
|
81
|
+
return {
|
|
82
|
+
inputTokens: clampTokens(prompt ?? 0),
|
|
83
|
+
outputTokens: clampTokens(candidates ?? 0),
|
|
84
|
+
...(typeof meta.cachedContentTokenCount === "number"
|
|
85
|
+
? { cacheReadTokens: clampTokens(meta.cachedContentTokenCount) }
|
|
86
|
+
: {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
11
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Estimate output tokens from a streaming chunk's text delta.
|
|
94
|
+
* Used as a fallback when usage isn't reported. ~4 chars per token.
|
|
95
|
+
*
|
|
96
|
+
* Duck-types each provider's text delta shape:
|
|
97
|
+
* Anthropic: chunk.delta.text (content_block_delta)
|
|
98
|
+
* OpenAI: chunk.choices[0].delta.content
|
|
99
|
+
* Gemini: chunk.candidates[0].content.parts[0].text
|
|
100
|
+
* pi-ai: chunk.text (text_delta event)
|
|
101
|
+
*/
|
|
102
|
+
export function extractTextDeltaLength(chunk) {
|
|
103
|
+
if (chunk == null || typeof chunk !== "object")
|
|
104
|
+
return 0;
|
|
105
|
+
const c = chunk;
|
|
106
|
+
// pi-ai text_delta
|
|
107
|
+
if (c.type === "text_delta" && typeof c.text === "string") {
|
|
108
|
+
return c.text.length;
|
|
109
|
+
}
|
|
110
|
+
// Anthropic content_block_delta
|
|
111
|
+
if (c.type === "content_block_delta" && typeof c.delta === "object" && c.delta != null) {
|
|
112
|
+
const delta = c.delta;
|
|
113
|
+
if (typeof delta.text === "string")
|
|
114
|
+
return delta.text.length;
|
|
115
|
+
}
|
|
116
|
+
// OpenAI choices[].delta.content
|
|
117
|
+
if (Array.isArray(c.choices) && c.choices.length > 0) {
|
|
118
|
+
const first = c.choices[0];
|
|
119
|
+
const delta = first?.delta;
|
|
120
|
+
if (typeof delta?.content === "string")
|
|
121
|
+
return delta.content.length;
|
|
122
|
+
}
|
|
123
|
+
// Gemini candidates[].content.parts[].text
|
|
124
|
+
if (Array.isArray(c.candidates) && c.candidates.length > 0) {
|
|
125
|
+
const first = c.candidates[0];
|
|
126
|
+
const content = first?.content;
|
|
127
|
+
const parts = content?.parts;
|
|
128
|
+
if (Array.isArray(parts)) {
|
|
129
|
+
let len = 0;
|
|
130
|
+
for (const part of parts) {
|
|
131
|
+
const p = part;
|
|
132
|
+
if (typeof p?.text === "string")
|
|
133
|
+
len += p.text.length;
|
|
134
|
+
}
|
|
135
|
+
return len;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return 0;
|
|
139
|
+
}
|
|
140
|
+
function readNum(v) {
|
|
141
|
+
return typeof v === "number" && Number.isFinite(v) ? v : null;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Extract token usage from a pi-ai stream event.
|
|
145
|
+
* Returns non-zero usage only for `done` and `error` events.
|
|
146
|
+
*/
|
|
12
147
|
export function extractUsageFromEvent(event) {
|
|
13
148
|
if (event.type === "done" && event.usage != null) {
|
|
14
149
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-extractor.js","sourceRoot":"","sources":["../src/token-extractor.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;
|
|
1
|
+
{"version":3,"file":"token-extractor.js","sourceRoot":"","sources":["../src/token-extractor.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -71,6 +71,8 @@ export interface UsertrustPluginConfig {
|
|
|
71
71
|
configPath?: string;
|
|
72
72
|
proxy?: string;
|
|
73
73
|
proxyKey?: string;
|
|
74
|
+
/** Vault directory (audit chain, spend ledger). Defaults to cwd. */
|
|
75
|
+
vaultBase?: string;
|
|
74
76
|
}
|
|
75
77
|
export interface StreamContext {
|
|
76
78
|
messages: unknown[];
|
|
@@ -86,4 +88,22 @@ export interface GovernedStreamMeta {
|
|
|
86
88
|
estimatedCost: number;
|
|
87
89
|
model: string;
|
|
88
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* The plugin shape that OpenClaw's plugin loader expects.
|
|
93
|
+
*
|
|
94
|
+
* Mirrors `ProviderPlugin` from openclaw/src/plugins/types.ts. The two
|
|
95
|
+
* primary integration hooks are `wrapStreamFn` (middleware-style wrap of
|
|
96
|
+
* an existing stream function) and `createStreamFn` (custom factory).
|
|
97
|
+
*
|
|
98
|
+
* We only implement `wrapStreamFn` — middleware is the path of least
|
|
99
|
+
* surprise for governance: budget check → forward → settle.
|
|
100
|
+
*/
|
|
101
|
+
export interface ProviderPlugin {
|
|
102
|
+
id: string;
|
|
103
|
+
label: string;
|
|
104
|
+
/** Middleware: receives an existing stream fn, returns a wrapped one. */
|
|
105
|
+
wrapStreamFn?: (next: StreamFn) => StreamFn;
|
|
106
|
+
/** Optional: provide a fully custom stream fn. We do not use this. */
|
|
107
|
+
createStreamFn?: () => StreamFn;
|
|
108
|
+
}
|
|
89
109
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAIH,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,YAAY,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAChE,KAAK,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GACpB,UAAU,GACV,cAAc,GACd,cAAc,GACd,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,SAAS,GACT,UAAU,CAAC;AAId,MAAM,WAAW,iBAAiB;IACjC,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACxC;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AAIH,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,YAAY,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAChE,KAAK,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,GACpB,UAAU,GACV,cAAc,GACd,cAAc,GACd,YAAY,GACZ,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,gBAAgB,GAChB,SAAS,GACT,UAAU,CAAC;AAId,MAAM,WAAW,iBAAiB;IACjC,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACxC;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IAClD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,QAAQ,GAAG,CACtB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC7B,aAAa,CAAC,WAAW,CAAC,CAAC;AAEhC,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACd;AAID;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC;IAC5C,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,QAAQ,CAAC;CAChC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "usertrust-openclaw",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "usertrust governance plugin for OpenClaw. Budget enforcement, audit trails, and policy gates for every LLM call — zero code changes.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Usertools, Inc. <hello@usertools.ai> (https://usertrust.ai)",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "tsc",
|
|
35
|
-
"prepublishOnly": "tsc"
|
|
35
|
+
"prepublishOnly": "tsc",
|
|
36
|
+
"demo": "tsx demo/runaway-agent.ts"
|
|
36
37
|
},
|
|
37
38
|
"files": [
|
|
38
39
|
"dist",
|