the-token-company 0.3.0 → 0.3.2
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/anthropic.js +8 -4
- package/dist/compress.d.ts +2 -0
- package/dist/compress.js +18 -2
- package/dist/types.d.ts +1 -0
- package/dist/types.js +10 -0
- package/package.json +1 -1
package/dist/anthropic.js
CHANGED
|
@@ -31,9 +31,9 @@ function hasSearchToolUse(response) {
|
|
|
31
31
|
function formatSearchResults(results) {
|
|
32
32
|
return results.map(r => `Source: ${r.title}\nURL: ${r.url}\n${r.content}`).join("\n\n");
|
|
33
33
|
}
|
|
34
|
-
async function handleSearchLoop(response, params, originalCreate, ttcClient, rest) {
|
|
34
|
+
async function handleSearchLoop(response, params, originalCreate, ttcClient, stats, rest) {
|
|
35
|
+
const messages = [...(params.messages || [])];
|
|
35
36
|
while (hasSearchToolUse(response)) {
|
|
36
|
-
const messages = [...(params.messages || [])];
|
|
37
37
|
// Add assistant response
|
|
38
38
|
const assistantContent = response.content.map((b) => {
|
|
39
39
|
if (typeof b.toJSON === 'function')
|
|
@@ -47,6 +47,7 @@ async function handleSearchLoop(response, params, originalCreate, ttcClient, res
|
|
|
47
47
|
if (block.type === "tool_use" && block.name === "ttc_web_search") {
|
|
48
48
|
const query = block.input?.query || "";
|
|
49
49
|
const searchResult = await ttcClient.search(query);
|
|
50
|
+
stats._recordSearch(searchResult);
|
|
50
51
|
toolResults.push({
|
|
51
52
|
type: "tool_result",
|
|
52
53
|
tool_use_id: block.id,
|
|
@@ -101,7 +102,10 @@ export function withCompression(client, options) {
|
|
|
101
102
|
if (params?.messages) {
|
|
102
103
|
params = {
|
|
103
104
|
...params,
|
|
104
|
-
messages: await compressAnthropicMessages(compressor, params.messages, model, roleAggr, {
|
|
105
|
+
messages: await compressAnthropicMessages(compressor, params.messages, model, roleAggr, {
|
|
106
|
+
stripServerToolResults,
|
|
107
|
+
skipToolName: webSearch ? "ttc_web_search" : undefined,
|
|
108
|
+
}),
|
|
105
109
|
};
|
|
106
110
|
}
|
|
107
111
|
if (systemAggr != null && typeof params?.system === "string" && params.system.trim()) {
|
|
@@ -116,7 +120,7 @@ export function withCompression(client, options) {
|
|
|
116
120
|
let response = await originalCreate(params, ...rest);
|
|
117
121
|
// Handle search tool loop
|
|
118
122
|
if (webSearch) {
|
|
119
|
-
response = await handleSearchLoop(response, params, originalCreate, ttcClient, rest);
|
|
123
|
+
response = await handleSearchLoop(response, params, originalCreate, ttcClient, stats, rest);
|
|
120
124
|
}
|
|
121
125
|
return response;
|
|
122
126
|
};
|
package/dist/compress.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export declare function compressOpenAIMessages(ttc: Compressor, messages: OpenAI
|
|
|
30
30
|
interface AnthropicBlock {
|
|
31
31
|
type: string;
|
|
32
32
|
text?: string;
|
|
33
|
+
tool_use_id?: string;
|
|
33
34
|
content?: string | Array<{
|
|
34
35
|
type: string;
|
|
35
36
|
text?: string;
|
|
@@ -44,6 +45,7 @@ interface AnthropicMessage {
|
|
|
44
45
|
}
|
|
45
46
|
export declare function compressAnthropicMessages(ttc: Compressor, messages: AnthropicMessage[], model: string, roleAggr: Record<string, number>, options?: {
|
|
46
47
|
stripServerToolResults?: boolean;
|
|
48
|
+
skipToolName?: string;
|
|
47
49
|
}): Promise<AnthropicMessage[]>;
|
|
48
50
|
interface AISDKTextPart {
|
|
49
51
|
type: "text";
|
package/dist/compress.js
CHANGED
|
@@ -47,8 +47,22 @@ export async function compressOpenAIMessages(ttc, messages, model, roleAggr) {
|
|
|
47
47
|
return msg;
|
|
48
48
|
}));
|
|
49
49
|
}
|
|
50
|
+
function collectToolUseIds(messages, toolName) {
|
|
51
|
+
const ids = new Set();
|
|
52
|
+
for (const msg of messages) {
|
|
53
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
54
|
+
continue;
|
|
55
|
+
for (const block of msg.content) {
|
|
56
|
+
if (block.type === "tool_use" && block.name === toolName && block.id) {
|
|
57
|
+
ids.add(block.id);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return ids;
|
|
62
|
+
}
|
|
50
63
|
export async function compressAnthropicMessages(ttc, messages, model, roleAggr, options) {
|
|
51
64
|
const stripServerToolResults = options?.stripServerToolResults ?? false;
|
|
65
|
+
const skipIds = options?.skipToolName ? collectToolUseIds(messages, options.skipToolName) : undefined;
|
|
52
66
|
return Promise.all(messages.map(async (msg) => {
|
|
53
67
|
if (msg.role === "assistant") {
|
|
54
68
|
const assistantAggr = roleAggr["assistant"];
|
|
@@ -75,7 +89,7 @@ export async function compressAnthropicMessages(ttc, messages, model, roleAggr,
|
|
|
75
89
|
return { ...msg, content: result.output };
|
|
76
90
|
}
|
|
77
91
|
if (Array.isArray(msg.content)) {
|
|
78
|
-
const blocks = await compressAnthropicBlocks(ttc, msg.content, model, userAggr, toolAggr);
|
|
92
|
+
const blocks = await compressAnthropicBlocks(ttc, msg.content, model, userAggr, toolAggr, skipIds);
|
|
79
93
|
return { ...msg, content: blocks };
|
|
80
94
|
}
|
|
81
95
|
return msg;
|
|
@@ -95,13 +109,15 @@ async function compressAssistantBlocks(ttc, blocks, model, assistantAggr, stripS
|
|
|
95
109
|
const filtered = results.filter((b) => b != null);
|
|
96
110
|
return filtered.length > 0 ? filtered : blocks;
|
|
97
111
|
}
|
|
98
|
-
async function compressAnthropicBlocks(ttc, blocks, model, userAggr, toolAggr) {
|
|
112
|
+
async function compressAnthropicBlocks(ttc, blocks, model, userAggr, toolAggr, skipIds) {
|
|
99
113
|
return Promise.all(blocks.map(async (block) => {
|
|
100
114
|
if (block.type === "text" && userAggr != null && typeof block.text === "string" && block.text.trim()) {
|
|
101
115
|
const result = await ttc.compress(block.text, { model, aggressiveness: userAggr });
|
|
102
116
|
return { ...block, text: result.output };
|
|
103
117
|
}
|
|
104
118
|
if (block.type === "tool_result" && toolAggr != null) {
|
|
119
|
+
if (block.tool_use_id && skipIds?.has(block.tool_use_id))
|
|
120
|
+
return block;
|
|
105
121
|
return compressToolResult(ttc, block, model, toolAggr);
|
|
106
122
|
}
|
|
107
123
|
return block;
|
package/dist/types.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export declare class CompressionStats {
|
|
|
76
76
|
private _accumulator;
|
|
77
77
|
_startTurn(): void;
|
|
78
78
|
_record(result: CompressResult): void;
|
|
79
|
+
_recordSearch(result: SearchResult): void;
|
|
79
80
|
_endTurn(): void;
|
|
80
81
|
get totalInputTokens(): number;
|
|
81
82
|
get totalOutputTokens(): number;
|
package/dist/types.js
CHANGED
|
@@ -7,6 +7,16 @@ export class CompressionStats {
|
|
|
7
7
|
_record(result) {
|
|
8
8
|
this._accumulator.push(result);
|
|
9
9
|
}
|
|
10
|
+
_recordSearch(result) {
|
|
11
|
+
this.history.push({
|
|
12
|
+
inputTokens: result.originalInputTokens,
|
|
13
|
+
outputTokens: result.outputTokens,
|
|
14
|
+
tokensSaved: result.tokensSaved,
|
|
15
|
+
messagesCompressed: 0,
|
|
16
|
+
ratio: result.outputTokens === 0 ? 0 : result.originalInputTokens / result.outputTokens,
|
|
17
|
+
timestamp: Date.now(),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
10
20
|
_endTurn() {
|
|
11
21
|
if (this._accumulator.length > 0) {
|
|
12
22
|
const inputTokens = this._accumulator.reduce((s, r) => s + r.inputTokens, 0);
|