@radaros/core 0.3.2 → 0.3.4
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/package.json +1 -1
- package/src/agent/agent.ts +113 -14
- package/src/agent/llm-loop.ts +31 -4
- package/src/agent/types.ts +13 -1
- package/src/index.ts +8 -1
- package/src/logger/logger.ts +19 -2
- package/src/memory/user-memory.ts +211 -0
- package/src/models/providers/anthropic.ts +34 -4
- package/src/models/providers/google.ts +29 -4
- package/src/models/providers/openai.ts +28 -6
- package/src/models/providers/vertex.ts +31 -4
- package/src/models/types.ts +12 -0
- package/src/tools/define-tool.ts +3 -1
- package/src/tools/tool-executor.ts +86 -4
- package/src/tools/types.ts +7 -0
- package/src/utils/retry.ts +56 -0
- package/dist/index.d.ts +0 -1317
- package/dist/index.js +0 -4823
package/package.json
CHANGED
package/src/agent/agent.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Logger } from "../logger/logger.js";
|
|
|
7
7
|
import { LLMLoop } from "./llm-loop.js";
|
|
8
8
|
import { RunContext } from "./run-context.js";
|
|
9
9
|
import { getTextContent, type ChatMessage, type MessageContent, type StreamChunk } from "../models/types.js";
|
|
10
|
+
import type { Session } from "../session/types.js";
|
|
10
11
|
import type {
|
|
11
12
|
AgentConfig,
|
|
12
13
|
RunOpts,
|
|
@@ -22,6 +23,7 @@ export class Agent {
|
|
|
22
23
|
private sessionManager: SessionManager;
|
|
23
24
|
private llmLoop: LLMLoop;
|
|
24
25
|
private logger: Logger;
|
|
26
|
+
private storageInitPromise: Promise<void> | null = null;
|
|
25
27
|
|
|
26
28
|
get tools() {
|
|
27
29
|
return this.config.tools ?? [];
|
|
@@ -50,6 +52,9 @@ export class Agent {
|
|
|
50
52
|
this.eventBus = config.eventBus ?? new EventBus();
|
|
51
53
|
|
|
52
54
|
const storage = config.storage ?? new InMemoryStorage();
|
|
55
|
+
if (typeof (storage as any).initialize === "function") {
|
|
56
|
+
this.storageInitPromise = (storage as any).initialize();
|
|
57
|
+
}
|
|
53
58
|
this.sessionManager = new SessionManager(storage);
|
|
54
59
|
|
|
55
60
|
this.logger = new Logger({
|
|
@@ -67,6 +72,8 @@ export class Agent {
|
|
|
67
72
|
temperature: config.temperature,
|
|
68
73
|
structuredOutput: config.structuredOutput,
|
|
69
74
|
logger: this.logger,
|
|
75
|
+
reasoning: config.reasoning,
|
|
76
|
+
retry: config.retry,
|
|
70
77
|
});
|
|
71
78
|
}
|
|
72
79
|
|
|
@@ -76,6 +83,7 @@ export class Agent {
|
|
|
76
83
|
const userId = opts?.userId ?? this.config.userId;
|
|
77
84
|
const inputText = typeof input === "string" ? input : getTextContent(input);
|
|
78
85
|
|
|
86
|
+
if (this.storageInitPromise) await this.storageInitPromise;
|
|
79
87
|
const session = await this.sessionManager.getOrCreate(sessionId, userId);
|
|
80
88
|
|
|
81
89
|
const ctx = new RunContext({
|
|
@@ -110,7 +118,7 @@ export class Agent {
|
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
120
|
|
|
113
|
-
const messages = await this.buildMessages(input,
|
|
121
|
+
const messages = await this.buildMessages(input, session, ctx);
|
|
114
122
|
const output = await this.llmLoop.run(messages, ctx, opts?.apiKey);
|
|
115
123
|
|
|
116
124
|
output.durationMs = Date.now() - startTime;
|
|
@@ -139,10 +147,26 @@ export class Agent {
|
|
|
139
147
|
]);
|
|
140
148
|
}
|
|
141
149
|
|
|
150
|
+
if (this.config.userMemory && userId) {
|
|
151
|
+
this.config.userMemory
|
|
152
|
+
.extractAndStore(
|
|
153
|
+
userId,
|
|
154
|
+
[
|
|
155
|
+
{ role: "user", content: inputText },
|
|
156
|
+
{ role: "assistant", content: output.text },
|
|
157
|
+
],
|
|
158
|
+
this.config.model
|
|
159
|
+
)
|
|
160
|
+
.catch((e: unknown) => this.logger.warn(`UserMemory extraction failed: ${e}`));
|
|
161
|
+
}
|
|
162
|
+
|
|
142
163
|
if (this.config.hooks?.afterRun) {
|
|
143
164
|
await this.config.hooks.afterRun(ctx, output);
|
|
144
165
|
}
|
|
145
166
|
|
|
167
|
+
if (output.thinking) {
|
|
168
|
+
this.logger.thinking(output.thinking);
|
|
169
|
+
}
|
|
146
170
|
this.logger.agentEnd(this.name, output.text, output.usage, output.durationMs);
|
|
147
171
|
|
|
148
172
|
this.eventBus.emit("run.complete", {
|
|
@@ -177,6 +201,7 @@ export class Agent {
|
|
|
177
201
|
const userId = opts?.userId ?? this.config.userId;
|
|
178
202
|
const inputText = typeof input === "string" ? input : getTextContent(input);
|
|
179
203
|
|
|
204
|
+
if (this.storageInitPromise) await this.storageInitPromise;
|
|
180
205
|
const session = await this.sessionManager.getOrCreate(sessionId, userId);
|
|
181
206
|
|
|
182
207
|
const ctx = new RunContext({
|
|
@@ -195,6 +220,11 @@ export class Agent {
|
|
|
195
220
|
|
|
196
221
|
let fullText = "";
|
|
197
222
|
let streamOk = false;
|
|
223
|
+
let streamUsage: import("../models/types.js").TokenUsage = {
|
|
224
|
+
promptTokens: 0,
|
|
225
|
+
completionTokens: 0,
|
|
226
|
+
totalTokens: 0,
|
|
227
|
+
};
|
|
198
228
|
|
|
199
229
|
try {
|
|
200
230
|
if (this.config.hooks?.beforeRun) {
|
|
@@ -212,11 +242,20 @@ export class Agent {
|
|
|
212
242
|
}
|
|
213
243
|
}
|
|
214
244
|
|
|
215
|
-
const messages = await this.buildMessages(input,
|
|
245
|
+
const messages = await this.buildMessages(input, session, ctx);
|
|
216
246
|
|
|
217
247
|
for await (const chunk of this.llmLoop.stream(messages, ctx, opts?.apiKey)) {
|
|
218
248
|
if (chunk.type === "text") {
|
|
219
249
|
fullText += chunk.text;
|
|
250
|
+
} else if (chunk.type === "finish" && chunk.usage) {
|
|
251
|
+
streamUsage = {
|
|
252
|
+
promptTokens: streamUsage.promptTokens + chunk.usage.promptTokens,
|
|
253
|
+
completionTokens: streamUsage.completionTokens + chunk.usage.completionTokens,
|
|
254
|
+
totalTokens: streamUsage.totalTokens + chunk.usage.totalTokens,
|
|
255
|
+
...(chunk.usage.reasoningTokens
|
|
256
|
+
? { reasoningTokens: (streamUsage.reasoningTokens ?? 0) + chunk.usage.reasoningTokens }
|
|
257
|
+
: {}),
|
|
258
|
+
};
|
|
220
259
|
}
|
|
221
260
|
yield chunk;
|
|
222
261
|
}
|
|
@@ -250,12 +289,25 @@ export class Agent {
|
|
|
250
289
|
]);
|
|
251
290
|
}
|
|
252
291
|
|
|
292
|
+
if (this.config.userMemory && userId) {
|
|
293
|
+
this.config.userMemory
|
|
294
|
+
.extractAndStore(
|
|
295
|
+
userId,
|
|
296
|
+
[
|
|
297
|
+
{ role: "user", content: inputText },
|
|
298
|
+
{ role: "assistant", content: fullText },
|
|
299
|
+
],
|
|
300
|
+
this.config.model
|
|
301
|
+
)
|
|
302
|
+
.catch((e: unknown) => this.logger.warn(`UserMemory extraction failed: ${e}`));
|
|
303
|
+
}
|
|
304
|
+
|
|
253
305
|
this.eventBus.emit("run.complete", {
|
|
254
306
|
runId: ctx.runId,
|
|
255
307
|
output: {
|
|
256
308
|
text: fullText,
|
|
257
309
|
toolCalls: [],
|
|
258
|
-
usage:
|
|
310
|
+
usage: streamUsage,
|
|
259
311
|
},
|
|
260
312
|
});
|
|
261
313
|
}
|
|
@@ -264,7 +316,7 @@ export class Agent {
|
|
|
264
316
|
|
|
265
317
|
private async buildMessages(
|
|
266
318
|
input: MessageContent,
|
|
267
|
-
|
|
319
|
+
session: Session,
|
|
268
320
|
ctx: RunContext
|
|
269
321
|
): Promise<ChatMessage[]> {
|
|
270
322
|
const messages: ChatMessage[] = [];
|
|
@@ -279,7 +331,7 @@ export class Agent {
|
|
|
279
331
|
|
|
280
332
|
if (this.config.memory) {
|
|
281
333
|
const memoryContext = await this.config.memory.getContextString(
|
|
282
|
-
sessionId
|
|
334
|
+
session.sessionId
|
|
283
335
|
);
|
|
284
336
|
if (memoryContext) {
|
|
285
337
|
systemContent = systemContent
|
|
@@ -288,6 +340,20 @@ export class Agent {
|
|
|
288
340
|
}
|
|
289
341
|
}
|
|
290
342
|
|
|
343
|
+
if (this.config.userMemory && ctx.userId) {
|
|
344
|
+
const hasRecallTool = (this.config.tools ?? []).some(
|
|
345
|
+
(t) => t.name === "recall_user_facts"
|
|
346
|
+
);
|
|
347
|
+
if (!hasRecallTool) {
|
|
348
|
+
const userContext = await this.config.userMemory.getContextString(ctx.userId);
|
|
349
|
+
if (userContext) {
|
|
350
|
+
systemContent = systemContent
|
|
351
|
+
? `${systemContent}\n\n${userContext}`
|
|
352
|
+
: userContext;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
291
357
|
if (systemContent) {
|
|
292
358
|
messages.push({ role: "system", content: systemContent });
|
|
293
359
|
}
|
|
@@ -296,23 +362,56 @@ export class Agent {
|
|
|
296
362
|
const limit = this.config.numHistoryRuns
|
|
297
363
|
? this.config.numHistoryRuns * 2
|
|
298
364
|
: 20;
|
|
299
|
-
|
|
365
|
+
let history = session.messages ?? [];
|
|
366
|
+
if (limit > 0 && history.length > limit) {
|
|
367
|
+
history = history.slice(-limit);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (this.config.maxContextTokens) {
|
|
371
|
+
history = this.trimHistoryByTokens(history, systemContent, input);
|
|
372
|
+
}
|
|
373
|
+
|
|
300
374
|
if (history.length > 0) {
|
|
301
|
-
this.logger.info(`Loaded ${history.length} history messages for session ${sessionId}`);
|
|
302
|
-
if (messages.length > 0 && messages[0].role === "system") {
|
|
303
|
-
messages[0] = {
|
|
304
|
-
...messages[0],
|
|
305
|
-
content: `${getTextContent(messages[0].content)}\n\nThis is a multi-turn conversation. The previous messages in this session are included below. Use them to maintain context and answer questions about prior exchanges.`,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
375
|
+
this.logger.info(`Loaded ${history.length} history messages for session ${session.sessionId}`);
|
|
308
376
|
}
|
|
309
377
|
messages.push(...history);
|
|
310
378
|
}
|
|
311
379
|
|
|
312
380
|
messages.push({ role: "user", content: input });
|
|
313
381
|
|
|
314
|
-
this.logger.info(`Sending ${messages.length} messages to LLM
|
|
382
|
+
this.logger.info(`Sending ${messages.length} messages to LLM`);
|
|
315
383
|
|
|
316
384
|
return messages;
|
|
317
385
|
}
|
|
386
|
+
|
|
387
|
+
private estimateTokens(text: string): number {
|
|
388
|
+
return Math.ceil(text.length / 3.5);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private trimHistoryByTokens(
|
|
392
|
+
history: ChatMessage[],
|
|
393
|
+
systemContent: string,
|
|
394
|
+
currentInput: MessageContent
|
|
395
|
+
): ChatMessage[] {
|
|
396
|
+
const maxTokens = this.config.maxContextTokens!;
|
|
397
|
+
const inputText = typeof currentInput === "string" ? currentInput : "(multimodal)";
|
|
398
|
+
let reservedTokens = this.estimateTokens(systemContent) + this.estimateTokens(inputText) + 100;
|
|
399
|
+
|
|
400
|
+
const available = maxTokens - reservedTokens;
|
|
401
|
+
if (available <= 0) return [];
|
|
402
|
+
|
|
403
|
+
const result: ChatMessage[] = [];
|
|
404
|
+
let used = 0;
|
|
405
|
+
|
|
406
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
407
|
+
const msg = history[i];
|
|
408
|
+
const text = typeof msg.content === "string" ? msg.content : "";
|
|
409
|
+
const tokens = this.estimateTokens(text);
|
|
410
|
+
if (used + tokens > available) break;
|
|
411
|
+
used += tokens;
|
|
412
|
+
result.unshift(msg);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
318
417
|
}
|
package/src/agent/llm-loop.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
getTextContent,
|
|
6
6
|
type ChatMessage,
|
|
7
7
|
type ModelConfig,
|
|
8
|
+
type ReasoningConfig,
|
|
8
9
|
type StreamChunk,
|
|
9
10
|
type ToolDefinition,
|
|
10
11
|
} from "../models/types.js";
|
|
@@ -13,6 +14,7 @@ import type { RunContext } from "./run-context.js";
|
|
|
13
14
|
import type { RunOutput } from "./types.js";
|
|
14
15
|
import type { ToolCallResult } from "../tools/types.js";
|
|
15
16
|
import type { Logger } from "../logger/logger.js";
|
|
17
|
+
import { withRetry, type RetryConfig } from "../utils/retry.js";
|
|
16
18
|
|
|
17
19
|
const _require = createRequire(import.meta.url);
|
|
18
20
|
|
|
@@ -24,6 +26,8 @@ export class LLMLoop {
|
|
|
24
26
|
private maxTokens?: number;
|
|
25
27
|
private structuredOutput?: z.ZodSchema;
|
|
26
28
|
private logger?: Logger;
|
|
29
|
+
private reasoning?: ReasoningConfig;
|
|
30
|
+
private retry?: Partial<RetryConfig>;
|
|
27
31
|
|
|
28
32
|
constructor(
|
|
29
33
|
provider: ModelProvider,
|
|
@@ -34,6 +38,8 @@ export class LLMLoop {
|
|
|
34
38
|
maxTokens?: number;
|
|
35
39
|
structuredOutput?: z.ZodSchema;
|
|
36
40
|
logger?: Logger;
|
|
41
|
+
reasoning?: ReasoningConfig;
|
|
42
|
+
retry?: Partial<RetryConfig>;
|
|
37
43
|
}
|
|
38
44
|
) {
|
|
39
45
|
this.provider = provider;
|
|
@@ -43,12 +49,16 @@ export class LLMLoop {
|
|
|
43
49
|
this.maxTokens = options.maxTokens;
|
|
44
50
|
this.structuredOutput = options.structuredOutput;
|
|
45
51
|
this.logger = options.logger;
|
|
52
|
+
this.reasoning = options.reasoning;
|
|
53
|
+
this.retry = options.retry;
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
async run(messages: ChatMessage[], ctx: RunContext, apiKey?: string): Promise<RunOutput> {
|
|
49
57
|
const allToolCalls: ToolCallResult[] = [];
|
|
50
58
|
let totalPromptTokens = 0;
|
|
51
59
|
let totalCompletionTokens = 0;
|
|
60
|
+
let totalReasoningTokens = 0;
|
|
61
|
+
let thinkingContent = "";
|
|
52
62
|
const currentMessages = [...messages];
|
|
53
63
|
const toolDefs = this.toolExecutor?.getToolDefinitions() ?? [];
|
|
54
64
|
|
|
@@ -59,6 +69,7 @@ export class LLMLoop {
|
|
|
59
69
|
modelConfig.temperature = this.temperature;
|
|
60
70
|
if (this.maxTokens !== undefined) modelConfig.maxTokens = this.maxTokens;
|
|
61
71
|
if (toolDefs.length > 0) modelConfig.tools = toolDefs;
|
|
72
|
+
if (this.reasoning) modelConfig.reasoning = this.reasoning;
|
|
62
73
|
|
|
63
74
|
if (this.structuredOutput) {
|
|
64
75
|
modelConfig.responseFormat = {
|
|
@@ -68,13 +79,18 @@ export class LLMLoop {
|
|
|
68
79
|
};
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
const response = await
|
|
72
|
-
currentMessages,
|
|
73
|
-
|
|
82
|
+
const response = await withRetry(
|
|
83
|
+
() => this.provider.generate(currentMessages, modelConfig),
|
|
84
|
+
this.retry
|
|
74
85
|
);
|
|
75
86
|
|
|
76
87
|
totalPromptTokens += response.usage.promptTokens;
|
|
77
88
|
totalCompletionTokens += response.usage.completionTokens;
|
|
89
|
+
if (response.usage.reasoningTokens) totalReasoningTokens += response.usage.reasoningTokens;
|
|
90
|
+
|
|
91
|
+
if ((response as any).thinking) {
|
|
92
|
+
thinkingContent += (thinkingContent ? "\n" : "") + (response as any).thinking;
|
|
93
|
+
}
|
|
78
94
|
|
|
79
95
|
currentMessages.push(response.message);
|
|
80
96
|
|
|
@@ -92,9 +108,12 @@ export class LLMLoop {
|
|
|
92
108
|
promptTokens: totalPromptTokens,
|
|
93
109
|
completionTokens: totalCompletionTokens,
|
|
94
110
|
totalTokens: totalPromptTokens + totalCompletionTokens,
|
|
111
|
+
...(totalReasoningTokens > 0 ? { reasoningTokens: totalReasoningTokens } : {}),
|
|
95
112
|
},
|
|
96
113
|
};
|
|
97
114
|
|
|
115
|
+
if (thinkingContent) output.thinking = thinkingContent;
|
|
116
|
+
|
|
98
117
|
if (this.structuredOutput && text) {
|
|
99
118
|
try {
|
|
100
119
|
const jsonStr = this.extractJson(text);
|
|
@@ -146,7 +165,9 @@ export class LLMLoop {
|
|
|
146
165
|
promptTokens: totalPromptTokens,
|
|
147
166
|
completionTokens: totalCompletionTokens,
|
|
148
167
|
totalTokens: totalPromptTokens + totalCompletionTokens,
|
|
168
|
+
...(totalReasoningTokens > 0 ? { reasoningTokens: totalReasoningTokens } : {}),
|
|
149
169
|
},
|
|
170
|
+
...(thinkingContent ? { thinking: thinkingContent } : {}),
|
|
150
171
|
};
|
|
151
172
|
}
|
|
152
173
|
|
|
@@ -165,6 +186,7 @@ export class LLMLoop {
|
|
|
165
186
|
modelConfig.temperature = this.temperature;
|
|
166
187
|
if (this.maxTokens !== undefined) modelConfig.maxTokens = this.maxTokens;
|
|
167
188
|
if (toolDefs.length > 0) modelConfig.tools = toolDefs;
|
|
189
|
+
if (this.reasoning) modelConfig.reasoning = this.reasoning;
|
|
168
190
|
|
|
169
191
|
let fullText = "";
|
|
170
192
|
const pendingToolCalls: Array<{
|
|
@@ -255,7 +277,12 @@ export class LLMLoop {
|
|
|
255
277
|
private zodToJsonSchema(schema: z.ZodSchema): Record<string, unknown> {
|
|
256
278
|
try {
|
|
257
279
|
const { zodToJsonSchema } = _require("zod-to-json-schema");
|
|
258
|
-
|
|
280
|
+
const result = zodToJsonSchema(schema, {
|
|
281
|
+
target: "jsonSchema7",
|
|
282
|
+
$refStrategy: "none",
|
|
283
|
+
}) as Record<string, unknown>;
|
|
284
|
+
delete result["$schema"];
|
|
285
|
+
return result;
|
|
259
286
|
} catch {
|
|
260
287
|
return {};
|
|
261
288
|
}
|
package/src/agent/types.ts
CHANGED
|
@@ -4,9 +4,11 @@ import type { ToolDef, ToolCallResult } from "../tools/types.js";
|
|
|
4
4
|
import type { Memory } from "../memory/memory.js";
|
|
5
5
|
import type { StorageDriver } from "../storage/driver.js";
|
|
6
6
|
import type { EventBus } from "../events/event-bus.js";
|
|
7
|
-
import type { TokenUsage, StreamChunk, MessageContent } from "../models/types.js";
|
|
7
|
+
import type { TokenUsage, StreamChunk, MessageContent, ReasoningConfig } from "../models/types.js";
|
|
8
8
|
import type { RunContext } from "./run-context.js";
|
|
9
9
|
import type { LogLevel } from "../logger/logger.js";
|
|
10
|
+
import type { UserMemory } from "../memory/user-memory.js";
|
|
11
|
+
import type { RetryConfig } from "../utils/retry.js";
|
|
10
12
|
|
|
11
13
|
export interface AgentConfig {
|
|
12
14
|
name: string;
|
|
@@ -30,6 +32,14 @@ export interface AgentConfig {
|
|
|
30
32
|
eventBus?: EventBus;
|
|
31
33
|
/** Logging level. Set to "debug" for tool call details, "info" for summaries, "silent" to disable. Default: "silent". */
|
|
32
34
|
logLevel?: LogLevel;
|
|
35
|
+
/** Enable extended thinking / reasoning for the model. */
|
|
36
|
+
reasoning?: ReasoningConfig;
|
|
37
|
+
/** User-scoped memory for cross-session personalization. */
|
|
38
|
+
userMemory?: UserMemory;
|
|
39
|
+
/** Retry configuration for transient LLM API failures (429, 5xx, network errors). */
|
|
40
|
+
retry?: Partial<RetryConfig>;
|
|
41
|
+
/** Maximum context window tokens. History is auto-trimmed to fit. */
|
|
42
|
+
maxContextTokens?: number;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
export interface RunOpts {
|
|
@@ -46,6 +56,8 @@ export interface RunOutput {
|
|
|
46
56
|
usage: TokenUsage;
|
|
47
57
|
/** Parsed structured output if structuredOutput schema is set. */
|
|
48
58
|
structured?: unknown;
|
|
59
|
+
/** Model's internal reasoning / thinking content (when reasoning is enabled). */
|
|
60
|
+
thinking?: string;
|
|
49
61
|
durationMs?: number;
|
|
50
62
|
}
|
|
51
63
|
|
package/src/index.ts
CHANGED
|
@@ -47,6 +47,7 @@ export type {
|
|
|
47
47
|
ModelResponse,
|
|
48
48
|
StreamChunk,
|
|
49
49
|
ModelConfig,
|
|
50
|
+
ReasoningConfig,
|
|
50
51
|
} from "./models/types.js";
|
|
51
52
|
export { getTextContent, isMultiModal } from "./models/types.js";
|
|
52
53
|
export { ModelRegistry, registry, openai, anthropic, google, ollama, vertex } from "./models/registry.js";
|
|
@@ -60,7 +61,7 @@ export type { VertexAIConfig } from "./models/providers/vertex.js";
|
|
|
60
61
|
// Tools
|
|
61
62
|
export { defineTool } from "./tools/define-tool.js";
|
|
62
63
|
export { ToolExecutor } from "./tools/tool-executor.js";
|
|
63
|
-
export type { ToolDef, ToolResult, ToolCallResult, Artifact } from "./tools/types.js";
|
|
64
|
+
export type { ToolDef, ToolResult, ToolCallResult, Artifact, ToolCacheConfig } from "./tools/types.js";
|
|
64
65
|
|
|
65
66
|
// Storage
|
|
66
67
|
export type { StorageDriver } from "./storage/driver.js";
|
|
@@ -103,6 +104,8 @@ export type { Session } from "./session/types.js";
|
|
|
103
104
|
// Memory
|
|
104
105
|
export { Memory } from "./memory/memory.js";
|
|
105
106
|
export type { MemoryConfig, MemoryEntry } from "./memory/types.js";
|
|
107
|
+
export { UserMemory } from "./memory/user-memory.js";
|
|
108
|
+
export type { UserMemoryConfig, UserFact } from "./memory/user-memory.js";
|
|
106
109
|
|
|
107
110
|
// Events
|
|
108
111
|
export { EventBus } from "./events/event-bus.js";
|
|
@@ -112,6 +115,10 @@ export type { AgentEventMap } from "./events/types.js";
|
|
|
112
115
|
export { Logger } from "./logger/logger.js";
|
|
113
116
|
export type { LogLevel, LoggerConfig } from "./logger/logger.js";
|
|
114
117
|
|
|
118
|
+
// Utils
|
|
119
|
+
export { withRetry } from "./utils/retry.js";
|
|
120
|
+
export type { RetryConfig } from "./utils/retry.js";
|
|
121
|
+
|
|
115
122
|
// MCP
|
|
116
123
|
export { MCPToolProvider } from "./mcp/mcp-client.js";
|
|
117
124
|
export type { MCPToolProviderConfig } from "./mcp/mcp-client.js";
|
package/src/logger/logger.ts
CHANGED
|
@@ -187,10 +187,23 @@ export class Logger {
|
|
|
187
187
|
console.log(this.pipe());
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
thinking(content: string): void {
|
|
191
|
+
if (!this.shouldLog("info")) return;
|
|
192
|
+
const truncated = content.length > 500 ? content.slice(0, 500) + "…" : content;
|
|
193
|
+
const label = this.c(C.dim + C.italic, "Thinking: ");
|
|
194
|
+
const lines = truncated.split("\n");
|
|
195
|
+
console.log(`${this.pipe()} ${label}${this.c(C.dim + C.italic, lines[0])}`);
|
|
196
|
+
const pad = " ".repeat(10);
|
|
197
|
+
for (let i = 1; i < lines.length; i++) {
|
|
198
|
+
console.log(`${this.pipe()} ${pad}${this.c(C.dim + C.italic, lines[i])}`);
|
|
199
|
+
}
|
|
200
|
+
console.log(this.pipe());
|
|
201
|
+
}
|
|
202
|
+
|
|
190
203
|
agentEnd(
|
|
191
204
|
agentName: string,
|
|
192
205
|
output: string,
|
|
193
|
-
usage: { promptTokens: number; completionTokens: number; totalTokens: number },
|
|
206
|
+
usage: { promptTokens: number; completionTokens: number; totalTokens: number; reasoningTokens?: number },
|
|
194
207
|
durationMs: number
|
|
195
208
|
): void {
|
|
196
209
|
if (!this.shouldLog("info")) return;
|
|
@@ -199,7 +212,7 @@ export class Logger {
|
|
|
199
212
|
this.printBoxLine("Output: ", output);
|
|
200
213
|
console.log(this.pipe());
|
|
201
214
|
|
|
202
|
-
|
|
215
|
+
let tokensLine =
|
|
203
216
|
this.c(C.dim, "Tokens: ") +
|
|
204
217
|
this.c(C.brightGreen, `↑ ${usage.promptTokens}`) +
|
|
205
218
|
this.c(C.dim, " ") +
|
|
@@ -207,6 +220,10 @@ export class Logger {
|
|
|
207
220
|
this.c(C.dim, " ") +
|
|
208
221
|
this.c(C.bold + C.brightGreen, `Σ ${usage.totalTokens}`);
|
|
209
222
|
|
|
223
|
+
if (usage.reasoningTokens) {
|
|
224
|
+
tokensLine += this.c(C.dim, " ") + this.c(C.brightMagenta, `🧠 ${usage.reasoningTokens}`);
|
|
225
|
+
}
|
|
226
|
+
|
|
210
227
|
const duration =
|
|
211
228
|
this.c(C.dim, "Duration: ") +
|
|
212
229
|
this.c(C.yellow, this.formatDuration(durationMs));
|