@bowenqt/qiniu-ai-sdk 0.10.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -0
- package/dist/ai/agent-graph.d.ts +101 -0
- package/dist/ai/agent-graph.d.ts.map +1 -0
- package/dist/ai/agent-graph.js +322 -0
- package/dist/ai/agent-graph.js.map +1 -0
- package/dist/ai/agent-graph.mjs +318 -0
- package/dist/ai/generate-text.d.ts +58 -0
- package/dist/ai/generate-text.d.ts.map +1 -1
- package/dist/ai/generate-text.js +157 -0
- package/dist/ai/generate-text.js.map +1 -1
- package/dist/ai/generate-text.mjs +156 -0
- package/dist/ai/graph/checkpointer.d.ts +112 -0
- package/dist/ai/graph/checkpointer.d.ts.map +1 -0
- package/dist/ai/graph/checkpointer.js +131 -0
- package/dist/ai/graph/checkpointer.js.map +1 -0
- package/dist/ai/graph/checkpointer.mjs +126 -0
- package/dist/ai/graph/index.d.ts +13 -0
- package/dist/ai/graph/index.d.ts.map +1 -0
- package/dist/ai/graph/index.js +22 -0
- package/dist/ai/graph/index.js.map +1 -0
- package/dist/ai/graph/index.mjs +12 -0
- package/dist/ai/graph/postgres-checkpointer.d.ts +54 -0
- package/dist/ai/graph/postgres-checkpointer.d.ts.map +1 -0
- package/dist/ai/graph/postgres-checkpointer.js +134 -0
- package/dist/ai/graph/postgres-checkpointer.js.map +1 -0
- package/dist/ai/graph/postgres-checkpointer.mjs +130 -0
- package/dist/ai/graph/redis-checkpointer.d.ts +51 -0
- package/dist/ai/graph/redis-checkpointer.d.ts.map +1 -0
- package/dist/ai/graph/redis-checkpointer.js +124 -0
- package/dist/ai/graph/redis-checkpointer.js.map +1 -0
- package/dist/ai/graph/redis-checkpointer.mjs +120 -0
- package/dist/ai/graph/state-graph.d.ts +41 -0
- package/dist/ai/graph/state-graph.d.ts.map +1 -0
- package/dist/ai/graph/state-graph.js +149 -0
- package/dist/ai/graph/state-graph.js.map +1 -0
- package/dist/ai/graph/state-graph.mjs +144 -0
- package/dist/ai/graph/types.d.ts +41 -0
- package/dist/ai/graph/types.d.ts.map +1 -0
- package/dist/ai/graph/types.js +10 -0
- package/dist/ai/graph/types.js.map +1 -0
- package/dist/ai/graph/types.mjs +7 -0
- package/dist/ai/internal-types.d.ts +109 -0
- package/dist/ai/internal-types.d.ts.map +1 -0
- package/dist/ai/internal-types.js +28 -0
- package/dist/ai/internal-types.js.map +1 -0
- package/dist/ai/internal-types.mjs +23 -0
- package/dist/ai/nodes/execute-node.d.ts +27 -0
- package/dist/ai/nodes/execute-node.d.ts.map +1 -0
- package/dist/ai/nodes/execute-node.js +118 -0
- package/dist/ai/nodes/execute-node.js.map +1 -0
- package/dist/ai/nodes/execute-node.mjs +114 -0
- package/dist/ai/nodes/index.d.ts +8 -0
- package/dist/ai/nodes/index.d.ts.map +1 -0
- package/dist/ai/nodes/index.js +16 -0
- package/dist/ai/nodes/index.js.map +1 -0
- package/dist/ai/nodes/index.mjs +7 -0
- package/dist/ai/nodes/memory-node.d.ts +34 -0
- package/dist/ai/nodes/memory-node.d.ts.map +1 -0
- package/dist/ai/nodes/memory-node.js +164 -0
- package/dist/ai/nodes/memory-node.js.map +1 -0
- package/dist/ai/nodes/memory-node.mjs +158 -0
- package/dist/ai/nodes/predict-node.d.ts +42 -0
- package/dist/ai/nodes/predict-node.d.ts.map +1 -0
- package/dist/ai/nodes/predict-node.js +89 -0
- package/dist/ai/nodes/predict-node.js.map +1 -0
- package/dist/ai/nodes/predict-node.mjs +86 -0
- package/dist/ai/nodes/types.d.ts +44 -0
- package/dist/ai/nodes/types.d.ts.map +1 -0
- package/dist/ai/nodes/types.js +6 -0
- package/dist/ai/nodes/types.js.map +1 -0
- package/dist/ai/nodes/types.mjs +5 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +80 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +34 -0
- package/dist/lib/otel-tracer.d.ts +47 -0
- package/dist/lib/otel-tracer.d.ts.map +1 -0
- package/dist/lib/otel-tracer.js +79 -0
- package/dist/lib/otel-tracer.js.map +1 -0
- package/dist/lib/otel-tracer.mjs +75 -0
- package/dist/lib/token-estimator.d.ts +62 -0
- package/dist/lib/token-estimator.d.ts.map +1 -0
- package/dist/lib/token-estimator.js +106 -0
- package/dist/lib/token-estimator.js.map +1 -0
- package/dist/lib/token-estimator.mjs +100 -0
- package/dist/lib/tool-registry.d.ts +103 -0
- package/dist/lib/tool-registry.d.ts.map +1 -0
- package/dist/lib/tool-registry.js +159 -0
- package/dist/lib/tool-registry.js.map +1 -0
- package/dist/lib/tool-registry.mjs +154 -0
- package/dist/lib/tracer.d.ts +85 -0
- package/dist/lib/tracer.d.ts.map +1 -0
- package/dist/lib/tracer.js +170 -0
- package/dist/lib/tracer.js.map +1 -0
- package/dist/lib/tracer.mjs +161 -0
- package/dist/lib/types.d.ts +11 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/modules/mcp/adapter.d.ts +23 -0
- package/dist/modules/mcp/adapter.d.ts.map +1 -0
- package/dist/modules/mcp/adapter.js +63 -0
- package/dist/modules/mcp/adapter.js.map +1 -0
- package/dist/modules/mcp/adapter.mjs +58 -0
- package/dist/modules/mcp/client.d.ts +75 -0
- package/dist/modules/mcp/client.d.ts.map +1 -0
- package/dist/modules/mcp/client.js +300 -0
- package/dist/modules/mcp/client.js.map +1 -0
- package/dist/modules/mcp/client.mjs +295 -0
- package/dist/modules/mcp/http-transport.d.ts +51 -0
- package/dist/modules/mcp/http-transport.d.ts.map +1 -0
- package/dist/modules/mcp/http-transport.js +146 -0
- package/dist/modules/mcp/http-transport.js.map +1 -0
- package/dist/modules/mcp/http-transport.mjs +141 -0
- package/dist/modules/mcp/index.d.ts +11 -0
- package/dist/modules/mcp/index.d.ts.map +1 -0
- package/dist/modules/mcp/index.js +34 -0
- package/dist/modules/mcp/index.js.map +1 -0
- package/dist/modules/mcp/index.mjs +14 -0
- package/dist/modules/mcp/oauth.d.ts +101 -0
- package/dist/modules/mcp/oauth.d.ts.map +1 -0
- package/dist/modules/mcp/oauth.js +347 -0
- package/dist/modules/mcp/oauth.js.map +1 -0
- package/dist/modules/mcp/oauth.mjs +304 -0
- package/dist/modules/mcp/token-store.d.ts +69 -0
- package/dist/modules/mcp/token-store.d.ts.map +1 -0
- package/dist/modules/mcp/token-store.js +174 -0
- package/dist/modules/mcp/token-store.js.map +1 -0
- package/dist/modules/mcp/token-store.mjs +135 -0
- package/dist/modules/mcp/types.d.ts +91 -0
- package/dist/modules/mcp/types.d.ts.map +1 -0
- package/dist/modules/mcp/types.js +14 -0
- package/dist/modules/mcp/types.js.map +1 -0
- package/dist/modules/mcp/types.mjs +11 -0
- package/dist/modules/skills/index.d.ts +7 -0
- package/dist/modules/skills/index.d.ts.map +1 -0
- package/dist/modules/skills/index.js +14 -0
- package/dist/modules/skills/index.js.map +1 -0
- package/dist/modules/skills/index.mjs +6 -0
- package/dist/modules/skills/loader.d.ts +51 -0
- package/dist/modules/skills/loader.d.ts.map +1 -0
- package/dist/modules/skills/loader.js +237 -0
- package/dist/modules/skills/loader.js.map +1 -0
- package/dist/modules/skills/loader.mjs +198 -0
- package/dist/modules/skills/types.d.ts +60 -0
- package/dist/modules/skills/types.d.ts.map +1 -0
- package/dist/modules/skills/types.js +20 -0
- package/dist/modules/skills/types.js.map +1 -0
- package/dist/modules/skills/types.mjs +17 -0
- package/package.json +4 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenTelemetry Tracer adapter.
|
|
3
|
+
* Wraps @opentelemetry/api for seamless integration.
|
|
4
|
+
*
|
|
5
|
+
* @optional - This file only works if @opentelemetry/api is installed.
|
|
6
|
+
*/
|
|
7
|
+
import { DEFAULT_TRACER_CONFIG, redactAttributes } from './tracer.mjs';
|
|
8
|
+
/**
|
|
9
|
+
* Span wrapper around OTel span.
|
|
10
|
+
*/
|
|
11
|
+
class OTelSpanWrapper {
|
|
12
|
+
constructor(otelSpan, config) {
|
|
13
|
+
this.otelSpan = otelSpan;
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
setAttribute(key, value) {
|
|
17
|
+
this.otelSpan.setAttribute(key, value);
|
|
18
|
+
}
|
|
19
|
+
setAttributes(attributes) {
|
|
20
|
+
this.otelSpan.setAttributes(redactAttributes(attributes, this.config));
|
|
21
|
+
}
|
|
22
|
+
recordException(error) {
|
|
23
|
+
this.otelSpan.recordException(error);
|
|
24
|
+
}
|
|
25
|
+
addEvent(name, attributes) {
|
|
26
|
+
this.otelSpan.addEvent(name, attributes ? redactAttributes(attributes, this.config) : undefined);
|
|
27
|
+
}
|
|
28
|
+
end() {
|
|
29
|
+
this.otelSpan.end();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* OpenTelemetry Tracer implementation.
|
|
34
|
+
* Requires @opentelemetry/api as a peer dependency.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { trace } from '@opentelemetry/api';
|
|
39
|
+
* import { OTelTracer, setGlobalTracer } from '@bowenqt/qiniu-ai-sdk';
|
|
40
|
+
*
|
|
41
|
+
* const provider = trace.getTracerProvider();
|
|
42
|
+
* const tracer = new OTelTracer(provider, { recordPrompts: false });
|
|
43
|
+
* setGlobalTracer(tracer);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class OTelTracer {
|
|
47
|
+
constructor(provider, config = {}) {
|
|
48
|
+
this.otelTracer = provider.getTracer('qiniu-ai-sdk', '0.13.0');
|
|
49
|
+
this.config = { ...DEFAULT_TRACER_CONFIG, ...config };
|
|
50
|
+
}
|
|
51
|
+
startSpan(name, attributes) {
|
|
52
|
+
const otelSpan = this.otelTracer.startSpan(name, {
|
|
53
|
+
attributes: attributes ? redactAttributes(attributes, this.config) : undefined,
|
|
54
|
+
});
|
|
55
|
+
return new OTelSpanWrapper(otelSpan, this.config);
|
|
56
|
+
}
|
|
57
|
+
async withSpan(name, fn) {
|
|
58
|
+
const span = this.startSpan(name);
|
|
59
|
+
try {
|
|
60
|
+
const result = await fn(span);
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
span.recordException(error);
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
span.end();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
getConfig() {
|
|
72
|
+
return this.config;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=otel-tracer.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Estimator for LLM context management.
|
|
3
|
+
* Supports CJK character-level weighting and ContentPart[].
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: All compaction paths MUST use estimateMessageTokens,
|
|
6
|
+
* NOT estimator(message.content) directly.
|
|
7
|
+
*/
|
|
8
|
+
import type { ContentPart } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Token estimator configuration.
|
|
11
|
+
*/
|
|
12
|
+
export interface TokenEstimatorConfig {
|
|
13
|
+
/** Characters per token for Latin text (default: 4) */
|
|
14
|
+
charsPerToken?: number;
|
|
15
|
+
/** Multiplier for CJK characters (default: 1.5) */
|
|
16
|
+
cjkMultiplier?: number;
|
|
17
|
+
/** Fixed overhead per message for role/metadata (default: 10) */
|
|
18
|
+
messageOverhead?: number;
|
|
19
|
+
/** Token cost per image (default: 85) */
|
|
20
|
+
imageTokenCost?: number;
|
|
21
|
+
/** Token cost per tool_call (default: 50) */
|
|
22
|
+
toolCallCost?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Token estimator function type.
|
|
26
|
+
*/
|
|
27
|
+
export type ContentEstimator = (content: string | ContentPart[]) => number;
|
|
28
|
+
/**
|
|
29
|
+
* Create a token estimator with the given configuration.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createTokenEstimator(config?: TokenEstimatorConfig): ContentEstimator;
|
|
32
|
+
/**
|
|
33
|
+
* Default content estimator.
|
|
34
|
+
*/
|
|
35
|
+
export declare const defaultContentEstimator: ContentEstimator;
|
|
36
|
+
/**
|
|
37
|
+
* Message interface for estimation.
|
|
38
|
+
*/
|
|
39
|
+
export interface EstimableMessage {
|
|
40
|
+
content: string | ContentPart[];
|
|
41
|
+
tool_calls?: unknown[];
|
|
42
|
+
role?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Estimate tokens for a complete message.
|
|
46
|
+
* This is the PRIMARY function for compaction - use this, not content-only estimation.
|
|
47
|
+
*
|
|
48
|
+
* @param message - The message to estimate
|
|
49
|
+
* @param config - Optional configuration
|
|
50
|
+
* @returns Estimated token count
|
|
51
|
+
*/
|
|
52
|
+
export declare function estimateMessageTokens(message: EstimableMessage, config?: TokenEstimatorConfig): number;
|
|
53
|
+
/**
|
|
54
|
+
* Estimate tokens for an array of messages.
|
|
55
|
+
* This is the function to use in compaction config.
|
|
56
|
+
*/
|
|
57
|
+
export declare function estimateMessagesTokens(messages: EstimableMessage[], config?: TokenEstimatorConfig): number;
|
|
58
|
+
/**
|
|
59
|
+
* Default configuration values (exported for documentation).
|
|
60
|
+
*/
|
|
61
|
+
export declare const DEFAULT_ESTIMATOR_CONFIG: Required<TokenEstimatorConfig>;
|
|
62
|
+
//# sourceMappingURL=token-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../../src/lib/token-estimator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAmB3C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,KAAK,MAAM,CAAC;AAE3E;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,oBAAyB,GAAG,gBAAgB,CAsBxF;AAaD;;GAEG;AACH,eAAO,MAAM,uBAAuB,kBAAyB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,gBAAgB,EACzB,MAAM,GAAE,oBAAyB,GAClC,MAAM,CAgBR;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,MAAM,GAAE,oBAAyB,GAClC,MAAM,CAER;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,oBAAoB,CAMnE,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Token Estimator for LLM context management.
|
|
4
|
+
* Supports CJK character-level weighting and ContentPart[].
|
|
5
|
+
*
|
|
6
|
+
* IMPORTANT: All compaction paths MUST use estimateMessageTokens,
|
|
7
|
+
* NOT estimator(message.content) directly.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DEFAULT_ESTIMATOR_CONFIG = exports.defaultContentEstimator = void 0;
|
|
11
|
+
exports.createTokenEstimator = createTokenEstimator;
|
|
12
|
+
exports.estimateMessageTokens = estimateMessageTokens;
|
|
13
|
+
exports.estimateMessagesTokens = estimateMessagesTokens;
|
|
14
|
+
/** CJK Unicode ranges */
|
|
15
|
+
const CJK_RANGES = [
|
|
16
|
+
[0x4e00, 0x9fff], // CJK Unified Ideographs
|
|
17
|
+
[0x3400, 0x4dbf], // CJK Extension A
|
|
18
|
+
[0xac00, 0xd7af], // Hangul Syllables
|
|
19
|
+
[0x3040, 0x30ff], // Hiragana + Katakana
|
|
20
|
+
[0xff00, 0xffef], // Fullwidth Forms
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Check if a character is CJK.
|
|
24
|
+
*/
|
|
25
|
+
function isCJK(char) {
|
|
26
|
+
const code = char.charCodeAt(0);
|
|
27
|
+
return CJK_RANGES.some(([start, end]) => code >= start && code <= end);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a token estimator with the given configuration.
|
|
31
|
+
*/
|
|
32
|
+
function createTokenEstimator(config = {}) {
|
|
33
|
+
const charsPerToken = config.charsPerToken ?? 4;
|
|
34
|
+
const cjkMultiplier = config.cjkMultiplier ?? 1.5;
|
|
35
|
+
const imageTokenCost = config.imageTokenCost ?? 85;
|
|
36
|
+
return (content) => {
|
|
37
|
+
// Handle ContentPart[]
|
|
38
|
+
if (Array.isArray(content)) {
|
|
39
|
+
let total = 0;
|
|
40
|
+
for (const part of content) {
|
|
41
|
+
if (part.type === 'text' && part.text) {
|
|
42
|
+
total += estimateText(part.text, charsPerToken, cjkMultiplier);
|
|
43
|
+
}
|
|
44
|
+
else if (part.type === 'image_url') {
|
|
45
|
+
total += imageTokenCost;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return total;
|
|
49
|
+
}
|
|
50
|
+
// Handle plain string
|
|
51
|
+
return estimateText(content, charsPerToken, cjkMultiplier);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Estimate tokens for text content.
|
|
56
|
+
*/
|
|
57
|
+
function estimateText(text, charsPerToken, cjkMultiplier) {
|
|
58
|
+
let weightedChars = 0;
|
|
59
|
+
for (const char of text) {
|
|
60
|
+
weightedChars += isCJK(char) ? cjkMultiplier : 1;
|
|
61
|
+
}
|
|
62
|
+
return Math.ceil(weightedChars / charsPerToken);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Default content estimator.
|
|
66
|
+
*/
|
|
67
|
+
exports.defaultContentEstimator = createTokenEstimator();
|
|
68
|
+
/**
|
|
69
|
+
* Estimate tokens for a complete message.
|
|
70
|
+
* This is the PRIMARY function for compaction - use this, not content-only estimation.
|
|
71
|
+
*
|
|
72
|
+
* @param message - The message to estimate
|
|
73
|
+
* @param config - Optional configuration
|
|
74
|
+
* @returns Estimated token count
|
|
75
|
+
*/
|
|
76
|
+
function estimateMessageTokens(message, config = {}) {
|
|
77
|
+
const messageOverhead = config.messageOverhead ?? 10;
|
|
78
|
+
const toolCallCost = config.toolCallCost ?? 50;
|
|
79
|
+
const estimator = createTokenEstimator(config);
|
|
80
|
+
let tokens = messageOverhead;
|
|
81
|
+
// Content tokens
|
|
82
|
+
tokens += estimator(message.content);
|
|
83
|
+
// Tool call tokens
|
|
84
|
+
if (message.tool_calls?.length) {
|
|
85
|
+
tokens += message.tool_calls.length * toolCallCost;
|
|
86
|
+
}
|
|
87
|
+
return tokens;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Estimate tokens for an array of messages.
|
|
91
|
+
* This is the function to use in compaction config.
|
|
92
|
+
*/
|
|
93
|
+
function estimateMessagesTokens(messages, config = {}) {
|
|
94
|
+
return messages.reduce((sum, msg) => sum + estimateMessageTokens(msg, config), 0);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Default configuration values (exported for documentation).
|
|
98
|
+
*/
|
|
99
|
+
exports.DEFAULT_ESTIMATOR_CONFIG = {
|
|
100
|
+
charsPerToken: 4,
|
|
101
|
+
cjkMultiplier: 1.5,
|
|
102
|
+
messageOverhead: 10,
|
|
103
|
+
imageTokenCost: 85,
|
|
104
|
+
toolCallCost: 50,
|
|
105
|
+
};
|
|
106
|
+
//# sourceMappingURL=token-estimator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.js","sourceRoot":"","sources":["../../src/lib/token-estimator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token Estimator for LLM context management.
|
|
3
|
+
* Supports CJK character-level weighting and ContentPart[].
|
|
4
|
+
*
|
|
5
|
+
* IMPORTANT: All compaction paths MUST use estimateMessageTokens,
|
|
6
|
+
* NOT estimator(message.content) directly.
|
|
7
|
+
*/
|
|
8
|
+
/** CJK Unicode ranges */
|
|
9
|
+
const CJK_RANGES = [
|
|
10
|
+
[0x4e00, 0x9fff], // CJK Unified Ideographs
|
|
11
|
+
[0x3400, 0x4dbf], // CJK Extension A
|
|
12
|
+
[0xac00, 0xd7af], // Hangul Syllables
|
|
13
|
+
[0x3040, 0x30ff], // Hiragana + Katakana
|
|
14
|
+
[0xff00, 0xffef], // Fullwidth Forms
|
|
15
|
+
];
|
|
16
|
+
/**
|
|
17
|
+
* Check if a character is CJK.
|
|
18
|
+
*/
|
|
19
|
+
function isCJK(char) {
|
|
20
|
+
const code = char.charCodeAt(0);
|
|
21
|
+
return CJK_RANGES.some(([start, end]) => code >= start && code <= end);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a token estimator with the given configuration.
|
|
25
|
+
*/
|
|
26
|
+
export function createTokenEstimator(config = {}) {
|
|
27
|
+
const charsPerToken = config.charsPerToken ?? 4;
|
|
28
|
+
const cjkMultiplier = config.cjkMultiplier ?? 1.5;
|
|
29
|
+
const imageTokenCost = config.imageTokenCost ?? 85;
|
|
30
|
+
return (content) => {
|
|
31
|
+
// Handle ContentPart[]
|
|
32
|
+
if (Array.isArray(content)) {
|
|
33
|
+
let total = 0;
|
|
34
|
+
for (const part of content) {
|
|
35
|
+
if (part.type === 'text' && part.text) {
|
|
36
|
+
total += estimateText(part.text, charsPerToken, cjkMultiplier);
|
|
37
|
+
}
|
|
38
|
+
else if (part.type === 'image_url') {
|
|
39
|
+
total += imageTokenCost;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return total;
|
|
43
|
+
}
|
|
44
|
+
// Handle plain string
|
|
45
|
+
return estimateText(content, charsPerToken, cjkMultiplier);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Estimate tokens for text content.
|
|
50
|
+
*/
|
|
51
|
+
function estimateText(text, charsPerToken, cjkMultiplier) {
|
|
52
|
+
let weightedChars = 0;
|
|
53
|
+
for (const char of text) {
|
|
54
|
+
weightedChars += isCJK(char) ? cjkMultiplier : 1;
|
|
55
|
+
}
|
|
56
|
+
return Math.ceil(weightedChars / charsPerToken);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Default content estimator.
|
|
60
|
+
*/
|
|
61
|
+
export const defaultContentEstimator = createTokenEstimator();
|
|
62
|
+
/**
|
|
63
|
+
* Estimate tokens for a complete message.
|
|
64
|
+
* This is the PRIMARY function for compaction - use this, not content-only estimation.
|
|
65
|
+
*
|
|
66
|
+
* @param message - The message to estimate
|
|
67
|
+
* @param config - Optional configuration
|
|
68
|
+
* @returns Estimated token count
|
|
69
|
+
*/
|
|
70
|
+
export function estimateMessageTokens(message, config = {}) {
|
|
71
|
+
const messageOverhead = config.messageOverhead ?? 10;
|
|
72
|
+
const toolCallCost = config.toolCallCost ?? 50;
|
|
73
|
+
const estimator = createTokenEstimator(config);
|
|
74
|
+
let tokens = messageOverhead;
|
|
75
|
+
// Content tokens
|
|
76
|
+
tokens += estimator(message.content);
|
|
77
|
+
// Tool call tokens
|
|
78
|
+
if (message.tool_calls?.length) {
|
|
79
|
+
tokens += message.tool_calls.length * toolCallCost;
|
|
80
|
+
}
|
|
81
|
+
return tokens;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Estimate tokens for an array of messages.
|
|
85
|
+
* This is the function to use in compaction config.
|
|
86
|
+
*/
|
|
87
|
+
export function estimateMessagesTokens(messages, config = {}) {
|
|
88
|
+
return messages.reduce((sum, msg) => sum + estimateMessageTokens(msg, config), 0);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Default configuration values (exported for documentation).
|
|
92
|
+
*/
|
|
93
|
+
export const DEFAULT_ESTIMATOR_CONFIG = {
|
|
94
|
+
charsPerToken: 4,
|
|
95
|
+
cjkMultiplier: 1.5,
|
|
96
|
+
messageOverhead: 10,
|
|
97
|
+
imageTokenCost: 85,
|
|
98
|
+
toolCallCost: 50,
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=token-estimator.js.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry for managing tool registration with conflict resolution.
|
|
3
|
+
* Implements priority-based registration: user > skill > mcp > builtin
|
|
4
|
+
*/
|
|
5
|
+
import type { Logger } from './logger';
|
|
6
|
+
/** Tool source types in priority order */
|
|
7
|
+
export type ToolSourceType = 'user' | 'skill' | 'mcp' | 'builtin';
|
|
8
|
+
/** Tool source metadata */
|
|
9
|
+
export interface ToolSource {
|
|
10
|
+
type: ToolSourceType;
|
|
11
|
+
namespace: string;
|
|
12
|
+
}
|
|
13
|
+
/** JSON Schema for tool parameters */
|
|
14
|
+
export interface ToolParameters {
|
|
15
|
+
type: 'object';
|
|
16
|
+
properties: Record<string, unknown>;
|
|
17
|
+
required?: string[];
|
|
18
|
+
}
|
|
19
|
+
/** Tool execution context for registered tools */
|
|
20
|
+
export interface RegisteredToolContext {
|
|
21
|
+
toolCallId: string;
|
|
22
|
+
messages: Array<{
|
|
23
|
+
role: string;
|
|
24
|
+
content: unknown;
|
|
25
|
+
}>;
|
|
26
|
+
abortSignal?: AbortSignal;
|
|
27
|
+
}
|
|
28
|
+
/** Registered tool definition */
|
|
29
|
+
export interface RegisteredTool {
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
parameters: ToolParameters;
|
|
33
|
+
source: ToolSource;
|
|
34
|
+
execute?: (args: Record<string, unknown>, context?: RegisteredToolContext) => Promise<unknown>;
|
|
35
|
+
}
|
|
36
|
+
/** Conflict resolution strategy */
|
|
37
|
+
export type ConflictStrategy = 'first-wins' | 'error';
|
|
38
|
+
/** Tool registry configuration */
|
|
39
|
+
export interface ToolRegistryConfig {
|
|
40
|
+
/** Sources to exclude from registration */
|
|
41
|
+
excludeSources?: string[];
|
|
42
|
+
/** Conflict resolution strategy (default: first-wins) */
|
|
43
|
+
conflictStrategy?: ConflictStrategy;
|
|
44
|
+
/** Logger instance */
|
|
45
|
+
logger?: Logger;
|
|
46
|
+
}
|
|
47
|
+
/** Tool conflict error */
|
|
48
|
+
export declare class ToolConflictError extends Error {
|
|
49
|
+
readonly toolName: string;
|
|
50
|
+
readonly existingSource: string;
|
|
51
|
+
readonly newSource: string;
|
|
52
|
+
constructor(toolName: string, existingSource: string, newSource: string);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Tool Registry manages tool registration with deterministic conflict resolution.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ToolRegistry {
|
|
58
|
+
private tools;
|
|
59
|
+
private readonly config;
|
|
60
|
+
private readonly logger;
|
|
61
|
+
constructor(config?: ToolRegistryConfig);
|
|
62
|
+
/**
|
|
63
|
+
* Register a tool with conflict detection.
|
|
64
|
+
* Tools are registered in priority order: user > skill > mcp > builtin
|
|
65
|
+
*/
|
|
66
|
+
register(tool: RegisteredTool): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Register multiple tools from a source.
|
|
69
|
+
* Tools are sorted by name for deterministic order.
|
|
70
|
+
*/
|
|
71
|
+
registerAll(tools: RegisteredTool[]): {
|
|
72
|
+
registered: number;
|
|
73
|
+
skipped: number;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Get a tool by name.
|
|
77
|
+
*/
|
|
78
|
+
get(name: string): RegisteredTool | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Get all registered tools.
|
|
81
|
+
*/
|
|
82
|
+
getAll(): RegisteredTool[];
|
|
83
|
+
/**
|
|
84
|
+
* Get tools as OpenAI-compatible format.
|
|
85
|
+
*/
|
|
86
|
+
toOpenAITools(): Array<{
|
|
87
|
+
type: 'function';
|
|
88
|
+
function: {
|
|
89
|
+
name: string;
|
|
90
|
+
description: string;
|
|
91
|
+
parameters: ToolParameters;
|
|
92
|
+
};
|
|
93
|
+
}>;
|
|
94
|
+
/**
|
|
95
|
+
* Clear all registered tools.
|
|
96
|
+
*/
|
|
97
|
+
clear(): void;
|
|
98
|
+
/**
|
|
99
|
+
* Check if a source should be excluded.
|
|
100
|
+
*/
|
|
101
|
+
private isSourceExcluded;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/lib/tool-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,0CAA0C;AAC1C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;AAKlE,2BAA2B;AAC3B,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACpD,WAAW,CAAC,EAAE,WAAW,CAAC;CAC7B;AAED,iCAAiC;AACjC,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAClG;AAED,mCAAmC;AACnC,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG,OAAO,CAAC;AAEtD,kCAAkC;AAClC,MAAM,WAAW,kBAAkB;IAC/B,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,yDAAyD;IACzD,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,0BAA0B;AAC1B,qBAAa,iBAAkB,SAAQ,KAAK;aAEpB,QAAQ,EAAE,MAAM;aAChB,cAAc,EAAE,MAAM;aACtB,SAAS,EAAE,MAAM;gBAFjB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM;CAQxC;AAED;;GAEG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,KAAK,CAAqC;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA+B;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,GAAE,kBAAuB;IAS3C;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO;IA0DvC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAkB7E;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7C;;OAEG;IACH,MAAM,IAAI,cAAc,EAAE;IAI1B;;OAEG;IACH,aAAa,IAAI,KAAK,CAAC;QACnB,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACN,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,cAAc,CAAC;SAC9B,CAAC;KACL,CAAC;IAWF;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAW3B"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tool Registry for managing tool registration with conflict resolution.
|
|
4
|
+
* Implements priority-based registration: user > skill > mcp > builtin
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ToolRegistry = exports.ToolConflictError = void 0;
|
|
8
|
+
const logger_1 = require("./logger");
|
|
9
|
+
/** Priority order (lower index = higher priority) */
|
|
10
|
+
const SOURCE_PRIORITY = ['user', 'skill', 'mcp', 'builtin'];
|
|
11
|
+
/** Tool conflict error */
|
|
12
|
+
class ToolConflictError extends Error {
|
|
13
|
+
constructor(toolName, existingSource, newSource) {
|
|
14
|
+
super(`Tool "${toolName}" conflict: ${existingSource} vs ${newSource}. ` +
|
|
15
|
+
`Exclude one source in your config.`);
|
|
16
|
+
this.toolName = toolName;
|
|
17
|
+
this.existingSource = existingSource;
|
|
18
|
+
this.newSource = newSource;
|
|
19
|
+
this.name = 'ToolConflictError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.ToolConflictError = ToolConflictError;
|
|
23
|
+
/**
|
|
24
|
+
* Tool Registry manages tool registration with deterministic conflict resolution.
|
|
25
|
+
*/
|
|
26
|
+
class ToolRegistry {
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
this.tools = new Map();
|
|
29
|
+
this.config = {
|
|
30
|
+
excludeSources: config.excludeSources ?? [],
|
|
31
|
+
conflictStrategy: config.conflictStrategy ?? 'first-wins',
|
|
32
|
+
logger: config.logger ?? logger_1.noopLogger,
|
|
33
|
+
};
|
|
34
|
+
this.logger = this.config.logger;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Register a tool with conflict detection.
|
|
38
|
+
* Tools are registered in priority order: user > skill > mcp > builtin
|
|
39
|
+
*/
|
|
40
|
+
register(tool) {
|
|
41
|
+
const fullSource = `${tool.source.type}:${tool.source.namespace}`;
|
|
42
|
+
// Check if source is excluded
|
|
43
|
+
if (this.isSourceExcluded(fullSource, tool.source)) {
|
|
44
|
+
this.logger.debug('Tool source excluded', {
|
|
45
|
+
tool: tool.name,
|
|
46
|
+
source: fullSource,
|
|
47
|
+
});
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
// Check for existing tool with same name
|
|
51
|
+
const existing = this.tools.get(tool.name);
|
|
52
|
+
if (existing) {
|
|
53
|
+
const existingSource = `${existing.source.type}:${existing.source.namespace}`;
|
|
54
|
+
// Same source = update
|
|
55
|
+
if (existingSource === fullSource) {
|
|
56
|
+
this.tools.set(tool.name, tool);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
// Different source = conflict
|
|
60
|
+
if (this.config.conflictStrategy === 'error') {
|
|
61
|
+
throw new ToolConflictError(tool.name, existingSource, fullSource);
|
|
62
|
+
}
|
|
63
|
+
// first-wins: compare priority
|
|
64
|
+
const existingPriority = SOURCE_PRIORITY.indexOf(existing.source.type);
|
|
65
|
+
const newPriority = SOURCE_PRIORITY.indexOf(tool.source.type);
|
|
66
|
+
if (newPriority < existingPriority) {
|
|
67
|
+
// New tool has higher priority, replace
|
|
68
|
+
this.logger.warn('Tool replaced due to higher priority', {
|
|
69
|
+
tool: tool.name,
|
|
70
|
+
replaced: existingSource,
|
|
71
|
+
by: fullSource,
|
|
72
|
+
});
|
|
73
|
+
this.tools.set(tool.name, tool);
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Existing tool has higher or equal priority, keep
|
|
78
|
+
this.logger.warn('Tool registration skipped due to conflict', {
|
|
79
|
+
tool: tool.name,
|
|
80
|
+
kept: existingSource,
|
|
81
|
+
skipped: fullSource,
|
|
82
|
+
});
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// No conflict, register
|
|
87
|
+
this.tools.set(tool.name, tool);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Register multiple tools from a source.
|
|
92
|
+
* Tools are sorted by name for deterministic order.
|
|
93
|
+
*/
|
|
94
|
+
registerAll(tools) {
|
|
95
|
+
// Sort by name for deterministic registration order
|
|
96
|
+
const sorted = [...tools].sort((a, b) => a.name.localeCompare(b.name));
|
|
97
|
+
let registered = 0;
|
|
98
|
+
let skipped = 0;
|
|
99
|
+
for (const tool of sorted) {
|
|
100
|
+
if (this.register(tool)) {
|
|
101
|
+
registered++;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
skipped++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { registered, skipped };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get a tool by name.
|
|
111
|
+
*/
|
|
112
|
+
get(name) {
|
|
113
|
+
return this.tools.get(name);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get all registered tools.
|
|
117
|
+
*/
|
|
118
|
+
getAll() {
|
|
119
|
+
return Array.from(this.tools.values());
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get tools as OpenAI-compatible format.
|
|
123
|
+
*/
|
|
124
|
+
toOpenAITools() {
|
|
125
|
+
return this.getAll().map(tool => ({
|
|
126
|
+
type: 'function',
|
|
127
|
+
function: {
|
|
128
|
+
name: tool.name,
|
|
129
|
+
description: tool.description,
|
|
130
|
+
parameters: tool.parameters,
|
|
131
|
+
},
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Clear all registered tools.
|
|
136
|
+
*/
|
|
137
|
+
clear() {
|
|
138
|
+
this.tools.clear();
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Check if a source should be excluded.
|
|
142
|
+
*/
|
|
143
|
+
isSourceExcluded(fullSource, source) {
|
|
144
|
+
return this.config.excludeSources.some(pattern => {
|
|
145
|
+
// Match full source (e.g., 'mcp:github')
|
|
146
|
+
if (pattern === fullSource)
|
|
147
|
+
return true;
|
|
148
|
+
// Match type only (e.g., 'mcp')
|
|
149
|
+
if (pattern === source.type)
|
|
150
|
+
return true;
|
|
151
|
+
// Match namespace pattern (e.g., 'mcp:*')
|
|
152
|
+
if (pattern.endsWith(':*') && pattern.slice(0, -2) === source.type)
|
|
153
|
+
return true;
|
|
154
|
+
return false;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.ToolRegistry = ToolRegistry;
|
|
159
|
+
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../src/lib/tool-registry.ts"],"names":[],"mappings":"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"}
|