@vellumai/assistant 0.8.8-dev.202606081859.f7bdc00 → 0.8.8-dev.202606081950.5bd40e7
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/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/compaction-direct.test.ts +32 -18
- package/src/__tests__/compaction-events.test.ts +2 -2
- package/src/__tests__/compaction.benchmark.test.ts +1 -1
- package/src/__tests__/context-overflow-reducer.test.ts +5 -5
- package/src/__tests__/context-window-manager-compact-retry.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-media-retry.test.ts +1 -1
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +71 -0
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-undo.test.ts +2 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +1 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +1 -1
- package/src/agent/loop.ts +5 -19
- package/src/cli/lib/__tests__/install-from-github.test.ts +199 -20
- package/src/cli/lib/__tests__/plugin-details.test.ts +18 -11
- package/src/cli/lib/__tests__/search-plugins.test.ts +12 -5
- package/src/cli/lib/install-from-github.ts +246 -41
- package/src/cli/lib/plugin-details.ts +20 -13
- package/src/cli/lib/search-plugins.ts +14 -8
- package/src/config/feature-flag-registry.json +3 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +1 -1
- package/src/daemon/conversation-agent-loop.ts +19 -53
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-media-retry.ts +19 -6
- package/src/daemon/conversation-process.ts +1 -1
- package/src/daemon/conversation-runtime-assembly.ts +37 -1
- package/src/daemon/conversation.ts +11 -11
- package/src/plugins/defaults/compaction/compact.ts +24 -15
- package/src/plugins/defaults/compaction/context-overflow-reducer.ts +4 -4
- package/src/plugins/defaults/compaction/manager-store.ts +1 -1
- package/src/{context → plugins/defaults/compaction}/window-manager.ts +12 -12
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +9 -10
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +1 -1
package/package.json
CHANGED
|
@@ -173,7 +173,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
173
173
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
174
174
|
}));
|
|
175
175
|
|
|
176
|
-
mock.module("../
|
|
176
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
177
177
|
ContextWindowManager: class {
|
|
178
178
|
constructor() {}
|
|
179
179
|
updateConfig() {}
|
|
@@ -3,19 +3,29 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The agent loop calls {@link defaultCompact} directly with a
|
|
5
5
|
* {@link CompactionContext} rather than routing through a middleware pipeline.
|
|
6
|
-
* These tests assert that the default implementation
|
|
7
|
-
*
|
|
8
|
-
* conversational options verbatim. The orchestrator
|
|
9
|
-
* (conversation-agent-loop) is exercised by
|
|
6
|
+
* These tests assert that the default implementation resolves the
|
|
7
|
+
* conversation's {@link ContextWindowManager} from the compaction store and
|
|
8
|
+
* forwards the request's conversational options verbatim. The orchestrator
|
|
9
|
+
* integration path (conversation-agent-loop) is exercised by
|
|
10
10
|
* `conversation-agent-loop-overflow.test.ts`.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { describe, expect, test } from "bun:test";
|
|
13
|
+
import { describe, expect, mock, test } from "bun:test";
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
// `defaultCompact` resolves the manager from the per-conversation compaction
|
|
16
|
+
// store. Register each test's canned stub in a map the mocked store reads from.
|
|
17
|
+
const fakeContextWindowManagers = new Map<string, unknown>();
|
|
18
|
+
mock.module("../plugins/defaults/compaction/manager-store.js", () => ({
|
|
19
|
+
createContextWindowManager: () => undefined,
|
|
20
|
+
getContextWindowManager: (conversationId: string) =>
|
|
21
|
+
fakeContextWindowManagers.get(conversationId),
|
|
22
|
+
disposeContextWindowManager: (conversationId: string) => {
|
|
23
|
+
fakeContextWindowManagers.delete(conversationId);
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
const { defaultCompact } =
|
|
28
|
+
await import("../plugins/defaults/compaction/compact.js");
|
|
19
29
|
|
|
20
30
|
type ContextWindowResultShape = {
|
|
21
31
|
compacted: boolean;
|
|
@@ -55,13 +65,17 @@ function makeResult(
|
|
|
55
65
|
};
|
|
56
66
|
}
|
|
57
67
|
|
|
58
|
-
|
|
68
|
+
/** Register a stub manager under a conversation id and return its recorder. */
|
|
69
|
+
function registerManager(
|
|
70
|
+
conversationId: string,
|
|
71
|
+
result: ContextWindowResultShape,
|
|
72
|
+
) {
|
|
59
73
|
const observed: {
|
|
60
74
|
messages: unknown;
|
|
61
75
|
signal: unknown;
|
|
62
76
|
options: unknown;
|
|
63
77
|
}[] = [];
|
|
64
|
-
|
|
78
|
+
fakeContextWindowManagers.set(conversationId, {
|
|
65
79
|
maybeCompact: async (
|
|
66
80
|
messages: unknown,
|
|
67
81
|
signal: unknown,
|
|
@@ -70,8 +84,8 @@ function makeManager(result: ContextWindowResultShape) {
|
|
|
70
84
|
observed.push({ messages, signal, options });
|
|
71
85
|
return result;
|
|
72
86
|
},
|
|
73
|
-
}
|
|
74
|
-
return
|
|
87
|
+
});
|
|
88
|
+
return observed;
|
|
75
89
|
}
|
|
76
90
|
|
|
77
91
|
describe("defaultCompact", () => {
|
|
@@ -81,13 +95,13 @@ describe("defaultCompact", () => {
|
|
|
81
95
|
summaryText: "manager-summary",
|
|
82
96
|
compactedMessages: 7,
|
|
83
97
|
});
|
|
84
|
-
const
|
|
98
|
+
const observed = registerManager("conv-delegates", expected);
|
|
85
99
|
const messages = [{ role: "user", content: "hi" }] as never;
|
|
86
100
|
const signal = new AbortController().signal;
|
|
87
101
|
|
|
88
102
|
// WHEN defaultCompact runs with those messages and a signal
|
|
89
103
|
const result = (await defaultCompact({
|
|
90
|
-
|
|
104
|
+
conversationId: "conv-delegates",
|
|
91
105
|
messages,
|
|
92
106
|
signal,
|
|
93
107
|
})) as unknown as ContextWindowResultShape;
|
|
@@ -105,11 +119,11 @@ describe("defaultCompact", () => {
|
|
|
105
119
|
|
|
106
120
|
test("forwards the request's compaction options to the manager", async () => {
|
|
107
121
|
// GIVEN a manager and a fully-populated compaction context
|
|
108
|
-
const
|
|
122
|
+
const observed = registerManager("conv-options", makeResult());
|
|
109
123
|
|
|
110
124
|
// WHEN defaultCompact runs with force/profile/trust options
|
|
111
125
|
await defaultCompact({
|
|
112
|
-
|
|
126
|
+
conversationId: "conv-options",
|
|
113
127
|
messages: [] as never,
|
|
114
128
|
force: true,
|
|
115
129
|
overrideProfile: "fast-profile",
|
|
@@ -118,7 +132,7 @@ describe("defaultCompact", () => {
|
|
|
118
132
|
actorTrustClass: "guardian",
|
|
119
133
|
});
|
|
120
134
|
|
|
121
|
-
// THEN the manager received exactly those options, and the
|
|
135
|
+
// THEN the manager received exactly those options, and the conversation id,
|
|
122
136
|
// messages, and signal are not leaked into the options bag
|
|
123
137
|
expect(observed).toHaveLength(1);
|
|
124
138
|
expect(observed[0]!.options).toEqual({
|
|
@@ -12,8 +12,8 @@ import { describe, expect, mock, test } from "bun:test";
|
|
|
12
12
|
|
|
13
13
|
import { CompactionCircuit } from "../agent/compaction-circuit.js";
|
|
14
14
|
import type { AgentEvent } from "../agent/loop.js";
|
|
15
|
-
import type { ContextWindowResult } from "../context/window-manager.js";
|
|
16
15
|
import type { ServerMessage } from "../daemon/message-protocol.js";
|
|
16
|
+
import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
|
|
17
17
|
import type { Message, ProviderResponse } from "../providers/types.js";
|
|
18
18
|
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
@@ -187,7 +187,7 @@ let mockCompactResult: ContextWindowResult = {
|
|
|
187
187
|
summaryText: "",
|
|
188
188
|
};
|
|
189
189
|
|
|
190
|
-
mock.module("../
|
|
190
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
191
191
|
ContextWindowManager: class {
|
|
192
192
|
nonPersistedPrefixCount = 0;
|
|
193
193
|
constructor() {}
|
|
@@ -12,7 +12,7 @@ import { describe, expect, mock, test } from "bun:test";
|
|
|
12
12
|
|
|
13
13
|
import { DEFAULT_CONFIG } from "../config/defaults.js";
|
|
14
14
|
import { estimatePromptTokens } from "../context/token-estimator.js";
|
|
15
|
-
import { ContextWindowManager } from "../
|
|
15
|
+
import { ContextWindowManager } from "../plugins/defaults/compaction/window-manager.js";
|
|
16
16
|
import type { Message, Provider } from "../providers/types.js";
|
|
17
17
|
|
|
18
18
|
mock.module("../util/logger.js", () => ({
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import { estimatePromptTokens } from "../context/token-estimator.js";
|
|
4
|
-
import type {
|
|
5
|
-
ContextWindowCompactOptions,
|
|
6
|
-
ContextWindowResult,
|
|
7
|
-
} from "../context/window-manager.js";
|
|
8
|
-
import { createContextSummaryMessage } from "../context/window-manager.js";
|
|
9
4
|
import {
|
|
10
5
|
createInitialReducerState,
|
|
11
6
|
reduceContextOverflow,
|
|
12
7
|
type ReducerConfig,
|
|
13
8
|
type ReducerState,
|
|
14
9
|
} from "../plugins/defaults/compaction/context-overflow-reducer.js";
|
|
10
|
+
import type {
|
|
11
|
+
ContextWindowCompactOptions,
|
|
12
|
+
ContextWindowResult,
|
|
13
|
+
} from "../plugins/defaults/compaction/window-manager.js";
|
|
14
|
+
import { createContextSummaryMessage } from "../plugins/defaults/compaction/window-manager.js";
|
|
15
15
|
import type { Message } from "../providers/types.js";
|
|
16
16
|
|
|
17
17
|
function msg(role: "user" | "assistant", text: string): Message {
|
|
@@ -94,7 +94,7 @@ mock.module("../context/compactor.js", () => ({
|
|
|
94
94
|
},
|
|
95
95
|
}));
|
|
96
96
|
|
|
97
|
-
import { ContextWindowManager } from "../
|
|
97
|
+
import { ContextWindowManager } from "../plugins/defaults/compaction/window-manager.js";
|
|
98
98
|
import type { Message, Provider } from "../providers/types.js";
|
|
99
99
|
|
|
100
100
|
function makeProvider(): Provider {
|
|
@@ -167,7 +167,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
167
167
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
168
168
|
}));
|
|
169
169
|
|
|
170
|
-
mock.module("../
|
|
170
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
171
171
|
ContextWindowManager: class {
|
|
172
172
|
constructor() {}
|
|
173
173
|
updateConfig() {}
|
|
@@ -164,7 +164,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
164
164
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
165
165
|
}));
|
|
166
166
|
|
|
167
|
-
mock.module("../
|
|
167
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
168
168
|
ContextWindowManager: class {
|
|
169
169
|
constructor() {}
|
|
170
170
|
updateConfig() {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import { createContextSummaryMessage } from "../context/window-manager.js";
|
|
4
3
|
import { stripMediaPayloadsForRetry } from "../daemon/conversation-media-retry.js";
|
|
4
|
+
import { createContextSummaryMessage } from "../plugins/defaults/compaction/window-manager.js";
|
|
5
5
|
import type { ContentBlock, Message } from "../providers/types.js";
|
|
6
6
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
@@ -249,7 +249,7 @@ mock.module("../agent/loop.js", () => ({
|
|
|
249
249
|
},
|
|
250
250
|
}));
|
|
251
251
|
|
|
252
|
-
mock.module("../
|
|
252
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
253
253
|
ContextWindowManager: class {
|
|
254
254
|
constructor() {}
|
|
255
255
|
updateConfig() {}
|
|
@@ -221,7 +221,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
221
221
|
let maybeCompactCalls: Array<{ force: boolean }> = [];
|
|
222
222
|
let forceCompactionEnabled = false;
|
|
223
223
|
|
|
224
|
-
mock.module("../
|
|
224
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
225
225
|
ContextWindowManager: class {
|
|
226
226
|
constructor() {}
|
|
227
227
|
updateConfig() {}
|
|
@@ -262,7 +262,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
262
262
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
263
263
|
}));
|
|
264
264
|
|
|
265
|
-
mock.module("../
|
|
265
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
266
266
|
ContextWindowManager: class {
|
|
267
267
|
constructor() {}
|
|
268
268
|
updateConfig() {}
|
|
@@ -86,12 +86,14 @@ import {
|
|
|
86
86
|
loadSlackChronologicalContext,
|
|
87
87
|
loadSlackChronologicalMessages,
|
|
88
88
|
resolveChannelCapabilities,
|
|
89
|
+
resolveTurnInboundActorContext,
|
|
89
90
|
stripChannelCapabilityContext,
|
|
90
91
|
stripInjectionsForCompaction,
|
|
91
92
|
stripNowScratchpad,
|
|
92
93
|
} from "../daemon/conversation-runtime-assembly.js";
|
|
93
94
|
import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
|
|
94
95
|
import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
|
|
96
|
+
import type { TrustContext } from "../daemon/trust-context.js";
|
|
95
97
|
import type { MessageRow } from "../memory/conversation-crud.js";
|
|
96
98
|
import { getDb } from "../memory/db-connection.js";
|
|
97
99
|
import { initializeDb } from "../memory/db-init.js";
|
|
@@ -1438,6 +1440,75 @@ describe("applyRuntimeInjections with nowScratchpad", () => {
|
|
|
1438
1440
|
});
|
|
1439
1441
|
});
|
|
1440
1442
|
|
|
1443
|
+
// ---------------------------------------------------------------------------
|
|
1444
|
+
// resolveTurnInboundActorContext
|
|
1445
|
+
// ---------------------------------------------------------------------------
|
|
1446
|
+
|
|
1447
|
+
describe("resolveTurnInboundActorContext", () => {
|
|
1448
|
+
/**
|
|
1449
|
+
* No trust context means there is no inbound actor to ground the turn on, so
|
|
1450
|
+
* the actor section is suppressed.
|
|
1451
|
+
*/
|
|
1452
|
+
test("returns null when there is no trust context", () => {
|
|
1453
|
+
// GIVEN a turn with no trust context
|
|
1454
|
+
// WHEN the inbound actor context is resolved
|
|
1455
|
+
const actorContext = resolveTurnInboundActorContext(undefined, "asst-1");
|
|
1456
|
+
|
|
1457
|
+
// THEN there is no actor context to inject
|
|
1458
|
+
expect(actorContext).toBeNull();
|
|
1459
|
+
});
|
|
1460
|
+
|
|
1461
|
+
/**
|
|
1462
|
+
* Guardian (owner) turns suppress the actor section — the unified turn context
|
|
1463
|
+
* only renders actor fields for non-guardian actors.
|
|
1464
|
+
*/
|
|
1465
|
+
test("returns null on guardian turns", () => {
|
|
1466
|
+
// GIVEN a guardian trust context (no requester chat id, so the direct
|
|
1467
|
+
// projection branch is taken)
|
|
1468
|
+
const trustContext: TrustContext = {
|
|
1469
|
+
sourceChannel: "vellum",
|
|
1470
|
+
trustClass: "guardian",
|
|
1471
|
+
requesterDisplayName: "Alice",
|
|
1472
|
+
};
|
|
1473
|
+
|
|
1474
|
+
// WHEN the inbound actor context is resolved
|
|
1475
|
+
const actorContext = resolveTurnInboundActorContext(trustContext, "asst-1");
|
|
1476
|
+
|
|
1477
|
+
// THEN the actor section is suppressed for the owner
|
|
1478
|
+
expect(actorContext).toBeNull();
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1481
|
+
/**
|
|
1482
|
+
* A non-guardian trust context without the identity fields needed for the
|
|
1483
|
+
* unified actor-trust lookup is projected directly into the actor context.
|
|
1484
|
+
*/
|
|
1485
|
+
test("projects a non-guardian trust context directly", () => {
|
|
1486
|
+
// GIVEN a trusted-contact trust context lacking requester chat/user ids
|
|
1487
|
+
const trustContext: TrustContext = {
|
|
1488
|
+
sourceChannel: "telegram",
|
|
1489
|
+
trustClass: "trusted_contact",
|
|
1490
|
+
requesterIdentifier: "@bob_handle",
|
|
1491
|
+
requesterDisplayName: "Bob",
|
|
1492
|
+
requesterSenderDisplayName: "Bobby",
|
|
1493
|
+
};
|
|
1494
|
+
|
|
1495
|
+
// WHEN the inbound actor context is resolved
|
|
1496
|
+
const actorContext = resolveTurnInboundActorContext(trustContext, "asst-1");
|
|
1497
|
+
|
|
1498
|
+
// THEN the trust context is projected into the model-facing actor context
|
|
1499
|
+
expect(actorContext).toEqual({
|
|
1500
|
+
sourceChannel: "telegram",
|
|
1501
|
+
canonicalActorIdentity: null,
|
|
1502
|
+
actorIdentifier: "@bob_handle",
|
|
1503
|
+
actorDisplayName: "Bob",
|
|
1504
|
+
actorSenderDisplayName: "Bobby",
|
|
1505
|
+
actorMemberDisplayName: undefined,
|
|
1506
|
+
trustClass: "trusted_contact",
|
|
1507
|
+
guardianIdentity: undefined,
|
|
1508
|
+
});
|
|
1509
|
+
});
|
|
1510
|
+
});
|
|
1511
|
+
|
|
1441
1512
|
// ---------------------------------------------------------------------------
|
|
1442
1513
|
// buildUnifiedTurnContextBlock
|
|
1443
1514
|
// ---------------------------------------------------------------------------
|
|
@@ -153,7 +153,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
153
153
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
154
154
|
}));
|
|
155
155
|
|
|
156
|
-
mock.module("../
|
|
156
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
157
157
|
ContextWindowManager: class {
|
|
158
158
|
constructor() {}
|
|
159
159
|
updateConfig() {}
|
|
@@ -154,7 +154,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
154
154
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
155
155
|
}));
|
|
156
156
|
|
|
157
|
-
mock.module("../
|
|
157
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
158
158
|
ContextWindowManager: class {
|
|
159
159
|
constructor() {}
|
|
160
160
|
updateConfig() {}
|
|
@@ -170,7 +170,7 @@ mock.module("../memory/retriever.js", () => ({
|
|
|
170
170
|
injectMemoryRecallAsUserBlock: (msgs: Message[]) => msgs,
|
|
171
171
|
}));
|
|
172
172
|
|
|
173
|
-
mock.module("../
|
|
173
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
174
174
|
ContextWindowManager: class {
|
|
175
175
|
constructor() {}
|
|
176
176
|
updateConfig() {}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
import { findLastUndoableUserMessageIndex } from "../daemon/conversation.js";
|
|
3
4
|
import {
|
|
4
5
|
CONTEXT_SUMMARY_MARKER,
|
|
5
6
|
createContextSummaryMessage,
|
|
6
|
-
} from "../
|
|
7
|
-
import { findLastUndoableUserMessageIndex } from "../daemon/conversation.js";
|
|
7
|
+
} from "../plugins/defaults/compaction/window-manager.js";
|
|
8
8
|
import type { Message } from "../providers/types.js";
|
|
9
9
|
|
|
10
10
|
function textMessage(role: "user" | "assistant", text: string): Message {
|
|
@@ -137,7 +137,7 @@ mock.module("../memory/retrieval-budget.js", () => ({
|
|
|
137
137
|
computeRecallBudget: () => 0,
|
|
138
138
|
}));
|
|
139
139
|
|
|
140
|
-
mock.module("../
|
|
140
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
141
141
|
ContextWindowManager: class {
|
|
142
142
|
constructor() {}
|
|
143
143
|
updateConfig() {}
|
|
@@ -181,7 +181,7 @@ mock.module("../memory/query-builder.js", () => ({
|
|
|
181
181
|
mock.module("../memory/retrieval-budget.js", () => ({
|
|
182
182
|
computeRecallBudget: () => 0,
|
|
183
183
|
}));
|
|
184
|
-
mock.module("../
|
|
184
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
185
185
|
ContextWindowManager: class {
|
|
186
186
|
updateConfig() {}
|
|
187
187
|
shouldCompact() {
|
|
@@ -178,7 +178,7 @@ mock.module("../memory/query-builder.js", () => ({
|
|
|
178
178
|
mock.module("../memory/retrieval-budget.js", () => ({
|
|
179
179
|
computeRecallBudget: () => 0,
|
|
180
180
|
}));
|
|
181
|
-
mock.module("../
|
|
181
|
+
mock.module("../plugins/defaults/compaction/window-manager.js", () => ({
|
|
182
182
|
ContextWindowManager: class {
|
|
183
183
|
updateConfig() {}
|
|
184
184
|
shouldCompact() {
|
|
@@ -36,6 +36,7 @@ const applyRuntimeInjectionsMock = mock(async (messages: unknown) => ({
|
|
|
36
36
|
}));
|
|
37
37
|
mock.module("../daemon/conversation-runtime-assembly.js", () => ({
|
|
38
38
|
applyRuntimeInjections: applyRuntimeInjectionsMock,
|
|
39
|
+
resolveTurnInboundActorContext: () => null,
|
|
39
40
|
}));
|
|
40
41
|
|
|
41
42
|
// The hook self-resolves the live conversation and its trust class; both are
|
|
@@ -148,7 +149,6 @@ function makeHookCtx(
|
|
|
148
149
|
requestId: "req-test",
|
|
149
150
|
isNonInteractive: false,
|
|
150
151
|
modelProfile: null,
|
|
151
|
-
actorContext: null,
|
|
152
152
|
...overrides,
|
|
153
153
|
};
|
|
154
154
|
}
|
package/src/agent/loop.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
estimateToolsTokens,
|
|
11
11
|
getCalibrationProviderKey,
|
|
12
12
|
} from "../context/token-estimator.js";
|
|
13
|
-
import type { ContextWindowResult } from "../context/window-manager.js";
|
|
14
13
|
import type { InboundActorContext } from "../daemon/conversation-runtime-assembly.js";
|
|
15
14
|
import type { ToolActivityMetadata } from "../daemon/message-types/web-activity.js";
|
|
16
15
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
@@ -22,15 +21,11 @@ import type {
|
|
|
22
21
|
PreModelCallContext,
|
|
23
22
|
StopContext,
|
|
24
23
|
} from "../plugin-api/types.js";
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
defaultCompact,
|
|
28
|
-
} from "../plugins/defaults/compaction/compact.js";
|
|
29
|
-
import { getContextWindowManager } from "../plugins/defaults/compaction/manager-store.js";
|
|
24
|
+
import { defaultCompact } from "../plugins/defaults/compaction/compact.js";
|
|
25
|
+
import type { ContextWindowResult } from "../plugins/defaults/compaction/window-manager.js";
|
|
30
26
|
import postCompact from "../plugins/defaults/memory-retrieval/hooks/post-compact.js";
|
|
31
27
|
import { runHook } from "../plugins/pipeline.js";
|
|
32
28
|
import type { CompactionCircuitEvent } from "../plugins/types.js";
|
|
33
|
-
import { PluginExecutionError } from "../plugins/types.js";
|
|
34
29
|
import { normalizeThinkingConfigForWire } from "../providers/thinking-config.js";
|
|
35
30
|
import type {
|
|
36
31
|
ContentBlock,
|
|
@@ -730,17 +725,8 @@ export class AgentLoop {
|
|
|
730
725
|
// Record the history-stripped marker right after stripping, before the
|
|
731
726
|
// pipeline runs.
|
|
732
727
|
await onEvent({ type: "history_stripped" });
|
|
733
|
-
// The compaction module owns the per-conversation manager;
|
|
734
|
-
//
|
|
735
|
-
// without a compaction path (agent wakes, standalone unit tests), which
|
|
736
|
-
// never reach this gate.
|
|
737
|
-
const manager = getContextWindowManager(this.conversationId);
|
|
738
|
-
if (manager == null) {
|
|
739
|
-
throw new PluginExecutionError(
|
|
740
|
-
`default-compaction: no ContextWindowManager registered for conversation ${this.conversationId} — the compaction store must construct one before compaction runs`,
|
|
741
|
-
DEFAULT_COMPACTION_PLUGIN_NAME,
|
|
742
|
-
);
|
|
743
|
-
}
|
|
728
|
+
// The compaction module owns the per-conversation manager; pass the
|
|
729
|
+
// conversation id and let `defaultCompact` resolve it from the store.
|
|
744
730
|
// The mid-loop budget gate is reached only when this turn decides to
|
|
745
731
|
// compact in place, so `force` past the auto-threshold check.
|
|
746
732
|
// `actorTrustClass` comes from the turn's trust snapshot (the actor whose
|
|
@@ -748,7 +734,7 @@ export class AgentLoop {
|
|
|
748
734
|
// guardian-only attachments for untrusted actors. `overrideProfile` is the
|
|
749
735
|
// turn's resolved inference-profile override for the summary call.
|
|
750
736
|
const compactResult = await defaultCompact({
|
|
751
|
-
|
|
737
|
+
conversationId: this.conversationId,
|
|
752
738
|
messages: rawHistory,
|
|
753
739
|
signal,
|
|
754
740
|
force: true,
|