@economic/agents 0.0.1-alpha.12 → 0.0.1-alpha.13
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 +159 -31
- package/dist/index.d.mts +93 -13
- package/dist/index.mjs +3630 -121
- package/package.json +4 -1
- package/schema/audit_events.sql +5 -4
- package/schema/conversations.sql +15 -0
package/README.md
CHANGED
|
@@ -43,6 +43,9 @@ const searchSkill: Skill = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
export class MyAgent extends AIChatAgent<Env> {
|
|
46
|
+
// Set fastModel to enable automatic compaction and future background summarization.
|
|
47
|
+
protected fastModel = openai("gpt-4o-mini");
|
|
48
|
+
|
|
46
49
|
async onChatMessage(onFinish, options) {
|
|
47
50
|
const params = await this.buildLLMParams({
|
|
48
51
|
options,
|
|
@@ -111,10 +114,27 @@ Protected method on `AIChatAgent`. Wraps the standalone `buildLLMParams` functio
|
|
|
111
114
|
|
|
112
115
|
- `messages` pre-filled from `this.messages`
|
|
113
116
|
- `activeSkills` pre-filled from `await this.getLoadedSkills()`
|
|
117
|
+
- `fastModel` injected from `this.fastModel`
|
|
114
118
|
- `log` injected into `experimental_context` alongside `options.body`
|
|
115
119
|
- Automatic error logging for non-clean finish reasons
|
|
120
|
+
- Compaction threshold defaulting: when `maxMessagesBeforeCompaction` is not in the config, defaults to `30`. Pass `maxMessagesBeforeCompaction: undefined` explicitly to disable compaction.
|
|
121
|
+
|
|
122
|
+
Config is everything accepted by the standalone `buildLLMParams` except `messages`, `activeSkills`, and `fastModel`.
|
|
123
|
+
|
|
124
|
+
### `fastModel` property
|
|
125
|
+
|
|
126
|
+
Override `fastModel` on your subclass to enable automatic compaction and future background conversation summarization:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
export class MyAgent extends AIChatAgent<Env> {
|
|
130
|
+
protected fastModel = openai("gpt-4o-mini");
|
|
131
|
+
// ...
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When `fastModel` is set, compaction runs automatically with a default threshold of 30 messages. No per-call configuration is needed in the common case. You can still customise or disable it per-call via `maxMessagesBeforeCompaction`.
|
|
116
136
|
|
|
117
|
-
|
|
137
|
+
When `fastModel` is `undefined` (the default), compaction is disabled regardless of `maxMessagesBeforeCompaction`.
|
|
118
138
|
|
|
119
139
|
### `getLoadedSkills()`
|
|
120
140
|
|
|
@@ -152,7 +172,6 @@ const params = await buildLLMParams({
|
|
|
152
172
|
system: "You are a helpful assistant.",
|
|
153
173
|
skills: [searchSkill, codeSkill],
|
|
154
174
|
tools: { myAlwaysOnTool },
|
|
155
|
-
compact: { model: openai("gpt-4o-mini"), maxMessages: 30 },
|
|
156
175
|
stopWhen: stepCountIs(20), // defaults to stepCountIs(20)
|
|
157
176
|
});
|
|
158
177
|
|
|
@@ -160,18 +179,18 @@ return streamText(params).toUIMessageStreamResponse();
|
|
|
160
179
|
// or: generateText(params);
|
|
161
180
|
```
|
|
162
181
|
|
|
163
|
-
| Parameter
|
|
164
|
-
|
|
|
165
|
-
| `options`
|
|
166
|
-
| `onFinish`
|
|
167
|
-
| `model`
|
|
168
|
-
| `messages`
|
|
169
|
-
| `activeSkills`
|
|
170
|
-
| `skills`
|
|
171
|
-
| `system`
|
|
172
|
-
| `tools`
|
|
173
|
-
| `
|
|
174
|
-
| `stopWhen`
|
|
182
|
+
| Parameter | Type | Required | Description |
|
|
183
|
+
| ----------------------------- | ------------------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
|
|
184
|
+
| `options` | `OnChatMessageOptions \| undefined` | Yes | CF options object. Extracts `abortSignal` and `experimental_context`. |
|
|
185
|
+
| `onFinish` | `StreamTextOnFinishCallback<ToolSet>` | Yes | Called when the stream completes. |
|
|
186
|
+
| `model` | `LanguageModel` | Yes | The language model to use. |
|
|
187
|
+
| `messages` | `UIMessage[]` | Yes | Conversation history. Converted to `ModelMessage[]` internally. |
|
|
188
|
+
| `activeSkills` | `string[]` | No | Names of skills loaded in previous turns. Pass `await this.getLoadedSkills()`. |
|
|
189
|
+
| `skills` | `Skill[]` | No | Skills available for on-demand loading. Wires up meta-tools automatically. |
|
|
190
|
+
| `system` | `string` | No | Base system prompt. |
|
|
191
|
+
| `tools` | `ToolSet` | No | Always-on tools, active every turn regardless of loaded skills. |
|
|
192
|
+
| `maxMessagesBeforeCompaction` | `number \| undefined` | No | Verbatim tail kept during compaction. Defaults to `30` when omitted. Pass `undefined` to disable. |
|
|
193
|
+
| `stopWhen` | `StopCondition` | No | Stop condition. Defaults to `stepCountIs(20)`. |
|
|
175
194
|
|
|
176
195
|
When `skills` are provided, `buildLLMParams`:
|
|
177
196
|
|
|
@@ -244,27 +263,62 @@ export const datetimeSkill: Skill = {
|
|
|
244
263
|
|
|
245
264
|
## Compaction
|
|
246
265
|
|
|
247
|
-
When `
|
|
266
|
+
When `fastModel` is set on the agent class, compaction runs automatically before each turn:
|
|
248
267
|
|
|
249
|
-
1. The message list is split into an older window and a recent verbatim tail
|
|
250
|
-
2.
|
|
268
|
+
1. The message list is split into an older window and a recent verbatim tail.
|
|
269
|
+
2. `fastModel` generates a concise summary of the older window.
|
|
251
270
|
3. That summary + the verbatim tail is what gets sent to the LLM.
|
|
252
271
|
4. Full history in DO SQLite is unaffected — compaction is in-memory only.
|
|
253
272
|
|
|
273
|
+
### Enabling compaction
|
|
274
|
+
|
|
275
|
+
Override `fastModel` on your subclass. Compaction runs automatically with a default threshold of 30 messages — no per-call config needed:
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
export class MyAgent extends AIChatAgent<Env> {
|
|
279
|
+
protected fastModel = openai("gpt-4o-mini");
|
|
280
|
+
|
|
281
|
+
async onChatMessage(onFinish, options) {
|
|
282
|
+
const params = await this.buildLLMParams({
|
|
283
|
+
options,
|
|
284
|
+
onFinish,
|
|
285
|
+
model: openai("gpt-4o"),
|
|
286
|
+
system: "...",
|
|
287
|
+
// No compaction config needed — runs automatically with default threshold
|
|
288
|
+
});
|
|
289
|
+
return streamText(params).toUIMessageStreamResponse();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Customising the threshold
|
|
295
|
+
|
|
296
|
+
Pass `maxMessagesBeforeCompaction` to override the default of 30:
|
|
297
|
+
|
|
254
298
|
```typescript
|
|
255
299
|
const params = await this.buildLLMParams({
|
|
256
300
|
options,
|
|
257
301
|
onFinish,
|
|
258
302
|
model: openai("gpt-4o"),
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
303
|
+
maxMessagesBeforeCompaction: 50, // keep last 50 messages verbatim
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Disabling compaction
|
|
308
|
+
|
|
309
|
+
Pass `maxMessagesBeforeCompaction: undefined` explicitly to disable compaction for that call, even when `fastModel` is set:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const params = await this.buildLLMParams({
|
|
313
|
+
options,
|
|
314
|
+
onFinish,
|
|
315
|
+
model: openai("gpt-4o"),
|
|
316
|
+
maxMessagesBeforeCompaction: undefined, // compaction off
|
|
264
317
|
});
|
|
265
|
-
return streamText(params).toUIMessageStreamResponse();
|
|
266
318
|
```
|
|
267
319
|
|
|
320
|
+
Compaction is always off when `fastModel` is `undefined` (the base class default).
|
|
321
|
+
|
|
268
322
|
---
|
|
269
323
|
|
|
270
324
|
## Built-in meta tools
|
|
@@ -317,13 +371,13 @@ execute: async (args, { experimental_context }) => {
|
|
|
317
371
|
};
|
|
318
372
|
```
|
|
319
373
|
|
|
320
|
-
`log` is a no-op when `
|
|
374
|
+
`log` is a no-op when `AGENT_DB` is not bound — so no changes are needed in tools when running without a D1 database.
|
|
321
375
|
|
|
322
376
|
---
|
|
323
377
|
|
|
324
378
|
## Audit logging — D1 setup
|
|
325
379
|
|
|
326
|
-
`AIChatAgent` writes audit events to a Cloudflare D1 database when `
|
|
380
|
+
`AIChatAgent` writes audit events to a Cloudflare D1 database when `AGENT_DB` is bound on the environment. Each agent worker has its own dedicated D1 database.
|
|
327
381
|
|
|
328
382
|
### 1. Create the D1 database
|
|
329
383
|
|
|
@@ -336,14 +390,15 @@ Open the database in the D1 dashboard, select **Console**, and run the contents
|
|
|
336
390
|
```sql
|
|
337
391
|
CREATE TABLE IF NOT EXISTS audit_events (
|
|
338
392
|
id TEXT PRIMARY KEY,
|
|
339
|
-
agent_name TEXT NOT NULL,
|
|
340
393
|
durable_object_id TEXT NOT NULL,
|
|
394
|
+
user_id TEXT NOT NULL,
|
|
341
395
|
message TEXT NOT NULL,
|
|
342
396
|
payload TEXT,
|
|
343
397
|
created_at TEXT NOT NULL
|
|
344
398
|
);
|
|
345
|
-
CREATE INDEX IF NOT EXISTS
|
|
346
|
-
CREATE INDEX IF NOT EXISTS
|
|
399
|
+
CREATE INDEX IF NOT EXISTS audit_events_user ON audit_events(user_id);
|
|
400
|
+
CREATE INDEX IF NOT EXISTS audit_events_do ON audit_events(durable_object_id);
|
|
401
|
+
CREATE INDEX IF NOT EXISTS audit_events_ts ON audit_events(created_at);
|
|
347
402
|
```
|
|
348
403
|
|
|
349
404
|
Safe to re-run — all statements use `IF NOT EXISTS`.
|
|
@@ -352,7 +407,7 @@ Safe to re-run — all statements use `IF NOT EXISTS`.
|
|
|
352
407
|
|
|
353
408
|
```jsonc
|
|
354
409
|
"d1_databases": [
|
|
355
|
-
{ "binding": "
|
|
410
|
+
{ "binding": "AGENT_DB", "database_name": "agents", "database_id": "YOUR_DB_ID" }
|
|
356
411
|
]
|
|
357
412
|
```
|
|
358
413
|
|
|
@@ -366,7 +421,81 @@ npm run db:setup
|
|
|
366
421
|
|
|
367
422
|
This runs the schema SQL against the local D1 SQLite file (`.wrangler/state/`). Re-running is harmless.
|
|
368
423
|
|
|
369
|
-
If `
|
|
424
|
+
If `AGENT_DB` is not bound, all `log()` calls are silent no-ops — the agent works without it.
|
|
425
|
+
|
|
426
|
+
### Providing `userId`
|
|
427
|
+
|
|
428
|
+
The `user_id` column is `NOT NULL`. The base class reads `userId` automatically from `options.body` — no subclass override is needed. The client must include it in the `body` passed to `useAgentChat`:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
useAgentChat({
|
|
432
|
+
agent,
|
|
433
|
+
body: {
|
|
434
|
+
userId: "148583_matt", // compose from agreement number + user identifier
|
|
435
|
+
// ...other fields
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
If the client omits `userId`, the audit insert is skipped and a `console.error` is emitted. This will be visible in Wrangler's output during local development and in Workers Logs in production.
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Conversations — D1 setup
|
|
445
|
+
|
|
446
|
+
`AIChatAgent` maintains a `conversations` table in `AGENT_DB` alongside `audit_events`. One row is kept per Durable Object instance (i.e. per conversation). The row is upserted automatically after every turn — no subclass code needed.
|
|
447
|
+
|
|
448
|
+
### Schema
|
|
449
|
+
|
|
450
|
+
Run the contents of [`schema/conversations.sql`](schema/conversations.sql) in the D1 dashboard console (same database as `audit_events`):
|
|
451
|
+
|
|
452
|
+
```sql
|
|
453
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
454
|
+
durable_object_id TEXT PRIMARY KEY,
|
|
455
|
+
user_id TEXT NOT NULL,
|
|
456
|
+
title TEXT,
|
|
457
|
+
summary TEXT,
|
|
458
|
+
created_at TEXT NOT NULL,
|
|
459
|
+
updated_at TEXT NOT NULL
|
|
460
|
+
);
|
|
461
|
+
CREATE INDEX IF NOT EXISTS conversations_user ON conversations(user_id);
|
|
462
|
+
CREATE INDEX IF NOT EXISTS conversations_ts ON conversations(updated_at);
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Safe to re-run — all statements use `IF NOT EXISTS`.
|
|
466
|
+
|
|
467
|
+
### Upsert behaviour
|
|
468
|
+
|
|
469
|
+
- **First turn**: a new row is inserted with `created_at` and `updated_at` both set to now. `title` and `summary` are `NULL`.
|
|
470
|
+
- **Subsequent turns**: only `user_id` and `updated_at` are updated. `created_at`, `title`, and `summary` are never overwritten by the upsert.
|
|
471
|
+
- `title` and `summary` are populated automatically after the conversation goes idle (see below).
|
|
472
|
+
|
|
473
|
+
### Automatic title and summary generation
|
|
474
|
+
|
|
475
|
+
After every turn, `AIChatAgent` schedules a `generateSummary` callback to fire 30 minutes in the future. If another message arrives before the timer fires, the schedule is cancelled and reset — so the callback only runs once the conversation has been idle for 30 minutes.
|
|
476
|
+
|
|
477
|
+
When `generateSummary` fires it:
|
|
478
|
+
|
|
479
|
+
1. Fetches the current summary from D1 (if any).
|
|
480
|
+
2. Takes the last 30 messages (`SUMMARY_CONTEXT_MESSAGES`) to keep the prompt bounded.
|
|
481
|
+
3. Calls `fastModel` with `Output.object()` to generate a structured `{ title, summary }`.
|
|
482
|
+
4. If a previous summary exists, it is included in the prompt so the model can detect direction changes.
|
|
483
|
+
5. Writes the result back to the `conversations` row.
|
|
484
|
+
|
|
485
|
+
No subclass code is needed — this runs automatically when `AGENT_DB` is bound and `fastModel` is set on the class.
|
|
486
|
+
|
|
487
|
+
### Querying conversation lists
|
|
488
|
+
|
|
489
|
+
To fetch all conversations for a user, ordered by most recent:
|
|
490
|
+
|
|
491
|
+
```sql
|
|
492
|
+
SELECT durable_object_id, title, summary, created_at, updated_at
|
|
493
|
+
FROM conversations
|
|
494
|
+
WHERE user_id = '148583_matt'
|
|
495
|
+
ORDER BY updated_at DESC;
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
If `userId` is not set on the request body, the upsert is skipped and a `console.error` is emitted — the same behaviour as audit logging.
|
|
370
499
|
|
|
371
500
|
---
|
|
372
501
|
|
|
@@ -389,7 +518,6 @@ If `AUDIT_DB` is not bound, all `log()` calls are silent no-ops — the agent wo
|
|
|
389
518
|
| Export | Description |
|
|
390
519
|
| ---------------------- | ------------------------------------------------------------------------------- |
|
|
391
520
|
| `Skill` | A named group of tools with optional guidance. |
|
|
392
|
-
| `CompactOptions` | `{ model: LanguageModel; maxMessages: number }` |
|
|
393
521
|
| `AgentContext<TBody>` | Request body type merged with `log`. Use as the type of `experimental_context`. |
|
|
394
522
|
| `BuildLLMParamsConfig` | Config type for the standalone `buildLLMParams` function. |
|
|
395
523
|
|
package/dist/index.d.mts
CHANGED
|
@@ -22,20 +22,32 @@ interface Skill {
|
|
|
22
22
|
tools: ToolSet;
|
|
23
23
|
}
|
|
24
24
|
//#endregion
|
|
25
|
-
//#region src/features/compaction/index.d.ts
|
|
26
|
-
type CompactOptions = {
|
|
27
|
-
/** Model used to generate the compaction summary */model: LanguageModel; /** Number of recent messages to keep verbatim; older messages are summarised */
|
|
28
|
-
maxMessages: number;
|
|
29
|
-
};
|
|
30
|
-
//#endregion
|
|
31
25
|
//#region src/llm.d.ts
|
|
32
26
|
type LLMParams = Parameters<typeof streamText>[0] & Parameters<typeof generateText>[0];
|
|
33
27
|
type BuildLLMParamsConfig = Omit<LLMParams, "messages" | "experimental_context" | "abortSignal"> & {
|
|
34
28
|
/** CF options object — extracts `abortSignal` and `experimental_context` (from `body`). */options: OnChatMessageOptions | undefined; /** Conversation history (`this.messages`). Converted to `ModelMessage[]` internally. */
|
|
35
29
|
messages: UIMessage[]; /** Skill names loaded in previous turns. Pass `await this.getLoadedSkills()`. */
|
|
36
30
|
activeSkills?: string[]; /** Skills available for on-demand loading this turn. */
|
|
37
|
-
skills?: Skill[];
|
|
38
|
-
|
|
31
|
+
skills?: Skill[];
|
|
32
|
+
/**
|
|
33
|
+
* Number of recent messages to keep verbatim during compaction. Older messages
|
|
34
|
+
* beyond this count are summarised by `fastModel` before being sent to the LLM.
|
|
35
|
+
*
|
|
36
|
+
* Defaults to `DEFAULT_MAX_MESSAGES_BEFORE_COMPACTION` (30) when not provided.
|
|
37
|
+
* Set explicitly to `undefined` to disable compaction entirely.
|
|
38
|
+
*
|
|
39
|
+
* Compaction only runs when `fastModel` is also set on the agent class.
|
|
40
|
+
*
|
|
41
|
+
* @internal Injected by `AIChatAgent.buildLLMParams` — do not set this directly.
|
|
42
|
+
*/
|
|
43
|
+
maxMessagesBeforeCompaction?: number;
|
|
44
|
+
/**
|
|
45
|
+
* The fast/cheap model used for compaction and background summarization.
|
|
46
|
+
* Provided automatically from `AIChatAgent.fastModel` — do not set this directly.
|
|
47
|
+
*
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
fastModel?: LanguageModel;
|
|
39
51
|
};
|
|
40
52
|
/**
|
|
41
53
|
* Builds the parameter object for a Vercel AI SDK `streamText` or `generateText` call.
|
|
@@ -67,7 +79,32 @@ declare function buildLLMParams(config: BuildLLMParamsConfig): Promise<LLMParams
|
|
|
67
79
|
*/
|
|
68
80
|
declare abstract class AIChatAgent<Env extends Cloudflare.Env = Cloudflare.Env> extends AIChatAgent$1<Env> {
|
|
69
81
|
/**
|
|
70
|
-
*
|
|
82
|
+
* Composed user identifier extracted from `options.body.userId` during
|
|
83
|
+
* `buildLLMParams`. Expected format: `{agreementNumber}_{userId}`, e.g. `148583_matt`.
|
|
84
|
+
* Undefined if the client did not include `userId` in the request body.
|
|
85
|
+
*/
|
|
86
|
+
protected _userId: string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Fast/cheap language model used for background tasks: compaction and conversation summarization.
|
|
89
|
+
*
|
|
90
|
+
* Declare this on every subclass:
|
|
91
|
+
*
|
|
92
|
+
* ```typescript
|
|
93
|
+
* protected fastModel = google("gemini-2.0-flash");
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* To disable compaction for a specific call, pass `maxMessagesBeforeCompaction: undefined`
|
|
97
|
+
* to `buildLLMParams` rather than omitting or nulling out `fastModel`.
|
|
98
|
+
*/
|
|
99
|
+
protected abstract fastModel: LanguageModel;
|
|
100
|
+
/**
|
|
101
|
+
* Resolves the D1 database binding and userId required for all D1 writes.
|
|
102
|
+
* Returns null and silently no-ops if AGENT_DB is not bound.
|
|
103
|
+
* Returns null and logs an error if userId is missing from the request body.
|
|
104
|
+
*/
|
|
105
|
+
private resolveD1Context;
|
|
106
|
+
/**
|
|
107
|
+
* Writes an audit event to D1 if `AGENT_DB` is bound on the environment,
|
|
71
108
|
* otherwise silently does nothing.
|
|
72
109
|
*
|
|
73
110
|
* Called automatically after every turn (from `persistMessages`) and on
|
|
@@ -75,17 +112,53 @@ declare abstract class AIChatAgent<Env extends Cloudflare.Env = Cloudflare.Env>
|
|
|
75
112
|
* `experimental_context.log` in tool `execute` functions.
|
|
76
113
|
*/
|
|
77
114
|
protected log(message: string, payload?: Record<string, unknown>): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* Records this conversation in the `conversations` D1 table and resets
|
|
117
|
+
* the idle summarization timer. Called automatically from `persistMessages`
|
|
118
|
+
* after every turn.
|
|
119
|
+
*
|
|
120
|
+
* After each upsert, any pending `generateSummary` schedule is cancelled
|
|
121
|
+
* and a new one is set for 30 minutes from now. If the user sends another
|
|
122
|
+
* message before the timer fires, the schedule is cancelled and reset again
|
|
123
|
+
* (debounce). When the conversation goes idle, `generateSummary` fires and
|
|
124
|
+
* writes the LLM-generated title and summary to D1.
|
|
125
|
+
*/
|
|
126
|
+
private recordConversation;
|
|
127
|
+
/**
|
|
128
|
+
* Generates a title and summary for the conversation after 30 minutes of
|
|
129
|
+
* inactivity. Invoked automatically by the Cloudflare Agents SDK scheduler
|
|
130
|
+
* — do not call this directly.
|
|
131
|
+
*
|
|
132
|
+
* Delegates to `generateConversationSummary` in `features/conversations`,
|
|
133
|
+
* which fetches the previous summary, slices to the last
|
|
134
|
+
* `SUMMARY_CONTEXT_MESSAGES` messages, calls `fastModel` with a structured
|
|
135
|
+
* output schema, and writes the result back to D1.
|
|
136
|
+
*/
|
|
137
|
+
generateSummary(): Promise<void>;
|
|
78
138
|
/**
|
|
79
139
|
* Builds the parameter object for a `streamText` or `generateText` call,
|
|
80
|
-
* pre-filling `messages` and `
|
|
140
|
+
* pre-filling `messages`, `activeSkills`, and `fastModel` from this agent instance.
|
|
81
141
|
* Injects `log` into `experimental_context` and logs non-clean finish reasons.
|
|
82
142
|
*
|
|
143
|
+
* **Compaction** runs automatically when `fastModel` is set on the class, using
|
|
144
|
+
* `DEFAULT_MAX_MESSAGES_BEFORE_COMPACTION` (30) as the threshold. Override the
|
|
145
|
+
* threshold by passing `maxMessagesBeforeCompaction`. Disable compaction entirely
|
|
146
|
+
* by passing `maxMessagesBeforeCompaction: undefined` explicitly.
|
|
147
|
+
*
|
|
83
148
|
* ```typescript
|
|
149
|
+
* // Compaction on (default threshold):
|
|
84
150
|
* const params = await this.buildLLMParams({ options, onFinish, model, system: "..." });
|
|
151
|
+
*
|
|
152
|
+
* // Compaction with custom threshold:
|
|
153
|
+
* const params = await this.buildLLMParams({ options, onFinish, model, maxMessagesBeforeCompaction: 50 });
|
|
154
|
+
*
|
|
155
|
+
* // Compaction off:
|
|
156
|
+
* const params = await this.buildLLMParams({ options, onFinish, model, maxMessagesBeforeCompaction: undefined });
|
|
157
|
+
*
|
|
85
158
|
* return streamText(params).toUIMessageStreamResponse();
|
|
86
159
|
* ```
|
|
87
160
|
*/
|
|
88
|
-
protected buildLLMParams(config: Omit<BuildLLMParamsConfig, "messages" | "activeSkills">): ReturnType<typeof buildLLMParams>;
|
|
161
|
+
protected buildLLMParams(config: Omit<BuildLLMParamsConfig, "messages" | "activeSkills" | "fastModel">): ReturnType<typeof buildLLMParams>;
|
|
89
162
|
/**
|
|
90
163
|
* Skill names persisted from previous turns, read from DO SQLite.
|
|
91
164
|
* Returns an empty array if no skills have been loaded yet.
|
|
@@ -108,9 +181,16 @@ declare abstract class AIChatAgent<Env extends Cloudflare.Env = Cloudflare.Env>
|
|
|
108
181
|
persistMessages(messages: UIMessage[], excludeBroadcastIds?: string[], options?: {
|
|
109
182
|
_deleteStaleRows?: boolean;
|
|
110
183
|
}): Promise<void>;
|
|
111
|
-
private ensureSkillTableExists;
|
|
112
184
|
}
|
|
113
185
|
//#endregion
|
|
186
|
+
//#region src/features/compaction/index.d.ts
|
|
187
|
+
/**
|
|
188
|
+
* Number of recent messages to keep verbatim when compaction runs.
|
|
189
|
+
* Older messages beyond this count are summarised into a single system message.
|
|
190
|
+
* Used as the default when `maxMessagesBeforeCompaction` is not provided to `buildLLMParams`.
|
|
191
|
+
*/
|
|
192
|
+
declare const DEFAULT_MAX_MESSAGES_BEFORE_COMPACTION = 30;
|
|
193
|
+
//#endregion
|
|
114
194
|
//#region src/types.d.ts
|
|
115
195
|
/**
|
|
116
196
|
* The context object available throughout an agent's lifetime — passed via
|
|
@@ -127,4 +207,4 @@ type AgentContext<TBody = Record<string, unknown>> = TBody & {
|
|
|
127
207
|
log: (message: string, payload?: Record<string, unknown>) => void | Promise<void>;
|
|
128
208
|
};
|
|
129
209
|
//#endregion
|
|
130
|
-
export { AIChatAgent, type AgentContext, type BuildLLMParamsConfig,
|
|
210
|
+
export { AIChatAgent, type AgentContext, type BuildLLMParamsConfig, DEFAULT_MAX_MESSAGES_BEFORE_COMPACTION, type Skill, buildLLMParams };
|